Opencvについて③

Opencv3系についてのメモ

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

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

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

---
###①リサイズ

cv2.resize(src, dsize[, dst[, fx[, fy[, interpolation]]]])
cv2.resize(第1引数、第2引数、第3引数)のイメージ

自分が使用している画像の通常時

```python:opencv.py
#通常画像
img = cv2,imread(cap_dir)
img.shape
>>>(340,255,3)
```

Opencvチュートリアルとしては

```python:opencv公式.py
import cv2
import numpy as np

img = cv2.imread(cap_dir)
res = cv2.resize(img,None,fx=1, fy=1, interpolation = cv2.INTER_CUBIC)
```
img:表示画像
None:未使用
fx=2:元画像に対してxを何倍にするか
fy=2:元画像に対してyを何倍にするか
interpolation=cv2.INTER_CUBIC:画像拡大時の補間メソッド

又は

```python:opencv公式.py
import cv2
import numpy as np

img = cv2.imread(cap_dir)

height, width = img.shape[:2]
res = cv2.resize(img,(2*width, 2*height), interpolation = cv2.INTER_CUBIC)
```

`img.shape[:2]`で画像のxとyの数値を取り込んで
`(2*width, 2*height)`で元の大きさに対して何倍かを決定している。

どちらも同じ事を実施しています。
元画像を元に変化させていくならこちらかと。(縦横比率は変わらない)

アスペクト比を気にせずに拡大・縮小をするのであれば

```python:opencv.py
size = (300,200)
img_resize = cv2.resize(img,size)
#or
img_resize = cv2.resize(img,(300,200))
```

これだけでも可能です。

![スクリーンショット (354).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/607764/b85ee4c4-eeb1-731c-7ec4-8b23f4855267.png)![スクリーンショット (349).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/607764/8b5c93ca-164e-a8f1-c373-e0a4651b12d8.png)
縦横比に関しては超適当です。
画像のアスペクト比を確認してからごちゃごちゃやるよりは
`.shape[:2]`で取り込んだ方がスマートかと

---

第3引数と記載している部分に関してのメソッド

interpolation = method
INTER_NEAREST
INTER_LINEAR(デフォルト設定)
INTER_AREA
INTER_CUBIC
INTER_LANCZOS4
と結構ありました

拡大時には`interpolation=cv2.INTER_LINEAR(処理速い)` or `cv2.INTER_CUBIC(処理遅い)`
縮小時には`interpolation=cv2.INTER_AREA`
との認識でよいかと…
英語表記なので細かいニュアンスが読み取れません…

---

###②画像平行移動

```python:opencv.py
img = cv2.imread(cap_dir)
h, w = img.shape[:2]
dx, dy = 30, 30

M = np.float32([[1,0,dx],[0,1,dy]])
img_afn = cv2.warpAffine(img,M,(w,h))
```
物体の位置を移動させる処理です．(x,y)方向への移動量が $(t_x,t_y)$ だとすると，この並進を表す変換行列 $\textbf{M}$ は以下のようになります:

```math
M = \begin{bmatrix} 1 & 0 & t_x \\ 0 & 1 & t_y  \end{bmatrix}
```
by公式

```python:opencv.py
img.shape
>>>(340, 255, 3)

afn_mat = np.float32([[1,0,dx],[0,1,dy]])
print(afn_mat)
[[ 1.  0. 30.]
 [ 0.  1. 30.]]
```
`np.float32([[1,0,dx],[0,1,dy]])`numpy配列で移動量を設定。

cv2.warpAffine(第1引数、第2引数、第3引数)
第1引数:画像
第2引数:移動量
第3引数:出力画像のサイズ ← 公式にはサイズを指定しないとエラー吐くって表記あり

これで画像が移動します。(現時点で使い道は思いつかず)

![スクリーンショット (354).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/607764/b85ee4c4-eeb1-731c-7ec4-8b23f4855267.png)![スクリーンショット (357).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/607764/eea3b066-023e-cdf2-5e07-89c4ad3a3f98.png)

---

###③画像回転

```python:opencv.py
img = cv2.imread(cap_dir,0)
h, w = img.shape

M = cv2.getRotationMatrix2D((w/2,h/2),45,1)
img_afn2 = cv2.warpAffine(img,M,(w,h))
```

cv2.getRotationMatrix2D((w/2,h/2),45,1)
(w/2,h/2):回転中心位置。数値を変更すると中心位置がずれます。
45:回転角度。
1:倍率。2に設定したら表示枠はそのままで画像が2倍になりました。

![スクリーンショット (360).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/607764/2288349e-b4c2-4903-8dc8-5e8a359f5a31.png)

カラー表示も問題なく出来ますが
カラーにすると(縦、横、色)と情報が増えるので
img.shapeの格納数を増やせばカラー画像の取り扱いの出来ます。
`h, w, c = img.shape`って事です。

公式さん曰く

---
画像を回転角 $\theta$ 回転させるための変換行列は以下のようになります．

```math
M = \begin{bmatrix} cos\theta & -sin\theta \\ sin\theta & cos\theta   \end{bmatrix}
```

OpenCVが提供する回転はスケーリングも同時に行い，回転の中心位置を変更できます．この変換を表す変換行列は以下のようになります．

```math
\begin{bmatrix} \alpha &  \beta & (1- \alpha )  \cdot center.x -  \beta \cdot center.y \\ - \beta &  \alpha &  \beta \cdot center.x + (1- \alpha )  \cdot center.y \end{bmatrix}
```

ここで:

```math
\begin{array}{l} \alpha =  scale \cdot \cos \theta , \\ \beta =  scale \cdot \sin \theta \end{array}
```

---

この変換行列を計算するための cv2.getRotationMatrix2D という関数があります．以下の例はスケーリングをせずに画像中心に対して90度回転する変換を試しています．

cv2.getRotationMatrix2D((w/2,h/2),45,1)は上記の計算式を用いて画像回転している様です。

公式には上記の様に記載されていますが式に関しては正直理解していませｎ。
どこの数値を触ると画像がどう変化するかを試してみた結果ですので
試してみて画像で理解するしかないかと思っています。

---
###④まとめ
使う・使わない別としてのまとめ
画像処理に関してはかなり多いので多分使うであろう物を
別途まとめます。