OpenCV基礎覚書(静止画編)

OpenCVを使う機会があったけど、久し振り過ぎて覚えてなかったので、復習がてらOpenCVの基礎をまとめます。

ここで使用する画像は[Pixabay](https://pixabay.com)から取得しました。

###ライブラリのインポート

```python
import cv2
```

###画像の読み込み

```python
img = cv2.imread('./input/img.jpg')
```

###画像の表示
(何かしらのキー入力で終了)

```python
cv2.imshow('img', img)
cv2.waitKey(0)
cv2.destroyAllWindows()
```

![img.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/350321/1e91e743-80ae-2444-c2d3-1245ca0b8637.jpeg)

###画像の書き込み

```python
cv2.imwrite('./output/img.jpg', img)
```

###画像をリサイズ
1/2にリサイズ

```python
h, w, c = img.shape
size = (w//2, h//2)
img_resize = cv2.resize(img, size)
```

![img_resize2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/350321/adad7d04-d6d7-f2e5-3ba7-cebf18c2fde0.jpeg)

###画像のグレースケール化

```python
img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
```

![img_gray.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/350321/67d8eb46-2b53-ba69-1725-193f7370f160.jpeg)


###画像のグレースケール化2
(出力画像は同じ)

```python
img_gray = cv2.imread('./input/XXXX.jpg', 0)
```


###画像のγ値の変更

```python
import numpy as np

gamma = 0.5 #γ値
img = cv2.imread('./input/XXXX.jpg', 0)
gamma_cvt = np.zeros((256, 1), dtype=np.uint8)
for i in range(256):
    gamma_cvt[i][0] = 255 * (float(i)/255) ** (1.0 / gamma)
    
img_gamma = cv2.LUT(img, gamma_cvt)
```
γ値=0.5
![img_gamma_05.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/350321/bb2ac807-4f89-a689-6bbf-0a122e76d019.jpeg)
γ値=2.0
![img_gamma_20.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/350321/0b161cf4-4c57-d5de-3ed2-c2f05ee532d5.jpeg)


###画像のRGBヒストグラムを表示

```python
import matplotlib.pyplot as plt
%matplotlib inline

color_list = ['blue', 'green', 'red']
for i,j in enumerate(color_list):
    hist = cv2.calcHist([img],[i],None, [256], [0,256])
    plt.plot(hist, color =j)
```

![histgram.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/350321/6a0eeeab-f19f-108a-8f5f-f9bacc867a6e.png)


###画像のグレースケールヒストグラムを表示

```python
hist2 = cv2.calcHist([img_gray], [0], None, [256], [0, 256])
plt.plot(hist2)
```

![histgram2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/350321/a8d73c9d-c69e-bc9a-30ec-df33727ba8f1.png)


###画像の2値化
2値化にはグレースケール画像を使用
※thresholdに指定する値はグレースケールのヒストグラムを参考にすると良い。

```python
threshold = 100
ret, img_th = cv2.threshold(img_gray, threshold, 255, cv2.THRESH_BINARY)
```

![img_th.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/350321/460bf3aa-f180-9152-3a63-8d5d9ca839a4.jpeg)

###画像の2値化(OTSU)

```python
ret, img_otsu = cv2.threshold(img_gray, 0, 255, cv2.THRESH_OTSU)
```

![img_otsu.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/350321/7ea84fd1-386b-964a-c1b7-c66d7032e6a1.jpeg)


###画像の2値化(ADAPTIVE)

```python
img_ada = cv2.adaptiveThreshold(img, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 3, 1)
```

![img_ada.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/350321/70234ce4-e5de-a51f-77df-b87b54139810.jpeg)

###アフィン変換(平行移動)
下20ピクセル、右20ピクセル移動

```python
import numpy as np

h, w, c = img.shape
dx, dy = 20, 20

afn_mat = np.float32([[1, 0, dx], [0, 1, dy]])
img_afn = cv2.warpAffine(img, afn_mat, (w, h))
```

![img_afn.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/350321/70a94e28-1822-7bec-b82d-388e22589b92.jpeg)

###画像の回転

```python
center = (w//2, h//2)
angle = 15 #角度指定
scale = 1.0

rotation_matrix = cv2.getRotationMatrix2D(center, angle, scale)
img_rotated = cv2.warpAffine(img, rotation_matrix, (w, h))
```

![img_rotated.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/350321/fa5920be-ebac-4d5b-96e1-1a7e43988c48.jpeg)



###画像の上下反転

```python
img_flip_ud = cv2.flip(img, 0)
```

![img_flip_ud.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/350321/d7d141bd-30ed-905d-dd3d-b6ddce623521.jpeg)

###画像の左右反転

```python
img_flip_lr = cv2.flip(img, 1)
```
![img_flip_lr.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/350321/8523d33b-f66c-43c0-0f91-a414dac3a15f.jpeg)

###画像の上下左右反転

```python
img_flip_udlr = cv2.flip(img, -1)
```

![img_flip_udlr.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/350321/ecb155f1-a0c2-a3ef-4461-e4d3523d31e7.jpeg)

###画像の平滑化

```python
img_blur = cv2.blur(img, (3,3))
```
![img_blur.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/350321/d953568f-d338-353b-a4b7-e88b21c2909a.jpeg)

###画像の平滑化(ガウシアンフィルタ)

```python
img_ga = cv2.GaussianBlur(img, (9, 9), 2)
```

![img_ga.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/350321/68eb0a3c-691a-5a4d-693f-204572b2121b.jpeg)

###画像の平滑化(メディアンフィルタ)

```python
img_me = cv2.medianBlur(img, 5)
```

![img_me.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/350321/fdb5cd67-85bc-6235-07d1-6221bd228eb2.jpeg)

###画像の平滑化(バイテラルフィルタ)

```python
img_bi = cv2.bilateralFilter(img, 9, 75, 75)
```

![img_bi.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/350321/cf57682d-0ee6-e070-5769-d69ac79cbf19.jpeg)

###エッジ検出(Sobelフィルター)

```python
img_sobel_x = cv2.Sobel(img_gray, cv2.CV_32F, 1, 0, ksize=3)
img_sobel_y = cv2.Sobel(img_gray, cv2.CV_32F, 0, 1, ksize=3)
img_sobel_x = cv2.convertScaleAbs(img_sobel_x)
img_sobel_y = cv2.convertScaleAbs(img_sobel_y)
```

img_sobel_x　※x方向の微分による垂直方向のエッジ検出
![img_sobel_x.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/350321/821cc7fd-f9f9-b283-3161-f20008f9863e.jpeg)

img_sobel_y　※y方向の微分による水平方向のエッジ検出
![img_sobel_y.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/350321/df9ad6e6-4463-6abb-8a30-db41bd160a63.jpeg)

###エッジ検出(Laplacianフィルター)

```python
img_lap = cv2.Laplacian(img_gray, cv2.CV_32F)
img_lap = cv2.convertScaleAbs(img_lap)
img_lap *= 2 #2次で微分するため画像が暗くなるので値を倍にする
```

![img_lap.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/350321/fde2fca8-f31c-d25d-d95c-ab11d3260929.jpeg)


###エッジ検出(ガウシアンフィルタ～Laplacianフィルター)
Laplacianフィルターではノイズが出やすいのでガウシアンフィルタで平滑化したものでエッジ検出をする

```python
img_blur = cv2.GaussianBlur(img_gray, (3, 3), 2)
img_lap2 = cv2.Laplacian(img_blur, cv2.CV_32F)
img_lap2 = cv2.convertScaleAbs(img_lap2)
img_lap2 *= 2
```

![img_glap.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/350321/a9e40ca7-1dd0-40ed-e2a3-2d2f872fa23c.jpeg)

###エッジ検出(Cannyフィルター)
2つの閾値でノイズを除去しエッジだけを検出する

```python
img_canny = cv2.Canny(img_gray, 100, 200)
```

![img_canny.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/350321/577442ec-d787-9db4-376a-c365bfcbd694.jpeg)



以上です。気が向いたら動画編もやるかもしれません。