Opencvについて④

Opencv3系についてのメモ

基本的には公式ドキュメントを確認しながらの物。

メモについて
[Opencvについて①](https://qiita.com/bobrock/items/d410db7ac71908eb2ecf)
[Opencvについて②](https://qiita.com/bobrock/items/40f442bd2d67df7b0aa9)
[Opencvについて③](https://qiita.com/bobrock/items/5150dd3040c775d23c6f)

環境・使用画像は前回と同様。

---
###①2値化(単純な閾値処理) 
一言でいうと白黒画像
『0』か『1』下で画像を表す。

```Python:opencv.ipynb
import cv2
import numpy as np

cap_dir = niku.png
img = cv2.imread(cap_dir,0)
threshold = 100
ret,th1 = cv2.threshold(img,threshold,255,cv2.THRESH_BINARY)
ret,th2 = cv2.threshold(img,threshold,255,cv2.THRESH_BINARY_INV)
ret,th3 = cv2.threshold(img,threshold,255,cv2.THRESH_TRUNC)
ret,th4 = cv2.threshold(img,threshold,255,cv2.THRESH_TOZERO)
ret,th5 = cv2.threshold(img,threshold,255,cv2.THRESH_TOZERO_INV)

cv2.imshow("THRESH_BINARY",th1)
cv2.imshow("THRESH_BINARY_INV",th2)
cv2.imshow("THRESH_TRUNC",th3)
cv2.imshow("THRESH_TOZERO",th4)
cv2.imshow("THRESH_TOZERO_INV",th5)

cv2.waitKey(0)
cv2.destroyAllWindows()
```
cv2.threshold(第1引数,第2引数,第3引数,第4引数)

第1引数：入力画像(グレースケール画像)
第2引数：しきい値
第3引数：最大値(入力画像の数値が0~255なので255でよいかと思う)
第4引数：しきい値処理フラグ

cv2.thresholdは2つの値を返すので
`ret,th1 = cv2.threshold(img,threshold,255,cv2.THRESH_BINARY)`となっており
th1側に処理された後の画像(2値画像)が格納されます。




しきい値を100にしている場合は以下の様な画像になる。

![スクリーンショット (365).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/607764/2ddeb9c2-ce4d-3eba-3035-d3e9bf0d9329.png)

---

しきい値を150にしている場合は以下の様な画像になる。

![スクリーンショット (366).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/607764/ab833f07-e130-0ee5-9ac9-5565245ec9f7.png)

上規の画像は分かりにくいと思うので[ここ](http://labs.eecs.tottori-u.ac.jp/sd/Member/oyamada/OpenCV/html/py_tutorials/py_imgproc/py_thresholding/py_thresholding.html#thresholding)に公式の2値化画像があるので確認して下さい。


輪郭検出を行うのであれば必須と思われます。

ちなみにカラー画像でも試してみましたが処理はできますが多分使えないと思います。

---

###②大津の2値化

```Python:opencv.ipynb
img = cv2.imread(cap_dir,0)
ret2,img_o = cv2.threshold(img,0,255,cv2.THRESH_OTSU)

cv2.imshow("niku",img)
cv2.imshow("niku_othu",img_o)
cv2.waitKey(0)
cv2.destroyAllWindows()
```

cv2.threshold(第1引数,第2引数,第3引数,第4引数)

第1引数：入力画像(グレースケール画像)
第2引数：しきい値
第3引数：最大値(入力画像の数値が0~255なので255でよいかと思う)
第4引数：しきい値処理フラグ(ここでは`cv2.THRESH_OTSU`)

しきい値に関しては0にする。との公式表記があります。

正直どういった状況で大津の技法を使用するのかよくわかりません。
これに関しては某e-learningで触った程度です。

実際に使ってみた感じで行くとthreshold(閾値)が自動変化するので
背景色が単色で且つ、粒子等の輪郭検出を行うには楽でした。

ただ、上記は確認画像が安定している事が前提なので
安定していないとかなりおかしな輪郭検出となりました。

なのでTHRESH_BINARYをデフォルトと思って
処理したい画像に応じて変更いていくのが吉と感じました。

![スクリーンショット (369).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/607764/0832937c-98e5-3823-86bb-91895fa1d6aa.png)

---

###③2値化+トラックバー

```Python:opencv.ipynb

def onTrackbar(position):
    global threshold
    threshold = position

cv2.namedWindow("img")
threshold = 100
cv2.createTrackbar("threshold","img",threshold,255,onTrackbar)

while True:
    ret,img_th = cv2.threshold(img,threshold,255,cv2.THRESH_BINARY)
    cv2.imshow("img",img_th)
    if cv2.waitKey(10) == 27:
        break
cv2.destroyAllWindows()

```
cv2.createTrackbar(第1引数、第2引数,第3引数,第4引数,第5引数)
第1引数：トラックバー名称
第2引数：第1引数で指定したトラックバーが表示されているウィンドウの名前
第3引数：トラックバーのデフォルト値
第4引数：トラックバーの取りうる最大値
第5引数：トラックバーの位置が変わる度に呼び出されるコールバック関数

第5引数に関してはdef関数

前述の`cv2.nameWindow("img")`の記載がないとトラックバーは表示されないので注意

![スクリーンショット (413).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/607764/090f9a42-d6cd-7792-6cc0-39c6cf356797.png)
![スクリーンショット (410).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/607764/b0250a81-576b-b0fa-0ec3-b83bda2c831b.png)
![スクリーンショット (411).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/607764/66cd4919-86a4-e879-b81e-2c07c4dbd917.png)

トラックバーにてthreshold値を変化させて、画像の変化が見られて楽しいです。
2値化の引数を変えても楽しめます。

---

###④まとめ
多分2値化をある程度使えないと、輪郭検出はしんどいと思いました。
公式ドキュメントは神