OpenCV-Python:OpenCVでのIV画像処理
14幾何学的変換
目標:
•動き、回転、アフィン変換など、画像に対してさまざまな変換を実行する方法を学びます。
•学習する関数は、cv2.getPerspectiveTransformです。
変換:
OpenCVは、cv2.warpAffineとcv2.warpPerspectiveの2つの変換関数を提供します。これらの2つの関数を使用すると、すべてのタイプの変換を実装できます。cv2.warpAffineが受け取るパラメーターは2×3変換行列ですが、cv2.warpPerspectiveが受け取るパラメーターは3×3変換行列です。
14.1拡張ズーム
拡張ズームは、画像のサイズのみを変更します。OpenCVが提供する関数cv2.resize()は、この関数を実現できます。画像のサイズは自分で手動で設定でき、ズーム率も指定できます。さまざまな補間方法を使用することを選択できます。スケーリングするときはcv2.INTER_AREAを使用することをお勧めし、拡張するときはv2.INTER_CUBIC(遅い)とv2.INTER_LINEARを使用することをお勧めします。デフォルトでは、画像のサイズを変更するすべての操作に使用される補間方法はcv2.INTER_LINEARです。次のいずれかの方法を使用して、画像のサイズを変更できます。
import cv2
import numpy as np
img=cv2.imread('messi5.jpg')
# 下面的 None 本应该是输出图像的尺寸,但是因为后边我们设置了缩放因子
# 因此这里为 None
res=cv2.resize(img,None,fx=2,fy=2,interpolation=cv2.INTER_CUBIC)
#OR
# 这里呢,我们直接设置输出图像的尺寸,所以不用设置缩放因子
height,width=img.shape[:2]
res=cv2.resize(img,(2*width,2*height),interpolation=cv2.INTER_CUBIC)
while(1):
cv2.imshow('res',res)
cv2.imshow('img',img)
if cv2.waitKey(1) & 0xFF == 27:
break
cv2.destroyAllWindows()
# Resize(src, dst, interpolation=CV_INTER_LINEAR)
14.2パン
平行移動とは、オブジェクトの位置を変更することです。(x、y)方向に移動する必要があり、移動距離が(tx、ty)の場合、次の方法で移動マトリックスを作成できます。
Numpy配列(データ型はnp.float32)を使用してこの行列を作成し、それを関数cv2.warpAffine()に渡すことができます。次の例を見てください。移動(100,50)ピクセルです。
import cv2
import numpy as np
img = cv2.imread('messi5.jpg',0)
rows,cols = img.shape
M = np.float32([[1,0,100],[0,1,50]])
dst = cv2.warpAffine(img,M,(cols,rows))
cv2.imshow('img',dst)
cv2.waitKey(0)
cv2.destroyAllWindows()
警告:関数cv2.warpAffine()の3番目のパラメーターは出力画像のサイズであり、その形式は画像(幅、高さ)である必要があります。画像の幅は列の数に対応し、高さは行の数に対応することに注意してください。
結果は次のとおりです。
14.3回転
画像の回転角θについては、次の形式の回転行列を使用する必要があります。
ただし、OpenCVではどこでも回転できますが、回転行列の形式は次のように変更
する必要があります。
それらの中で:
この回転行列を構築するために、OpenCVは関数cv2.getRotationMatrix2Dを提供します。
次の例は、ズームせずに画像を90度回転させます。
import cv2
import numpy as np
img=cv2.imread('messi5.jpg',0)
rows,cols=img.shape
# 这里的第一个参数为旋转中心,第二个为旋转角度,第三个为旋转后的缩放因子
# 可以通过设置旋转中心,缩放因子,以及窗口大小来防止旋转后超出边界的问题
M=cv2.getRotationMatrix2D((cols/2,rows/2),45,0.6)
# 第三个参数是输出图像的尺寸中心
dst=cv2.warpAffine(img,M,(2*cols,2*rows))
while(1):
cv2.imshow('img',dst)
if cv2.waitKey(1)&0xFF==27:
break
cv2.destroyAllWindows()
結果は次のとおりです。
14.4アフィン変換
アフィン変換では、元の画像のすべての平行線も結果画像で平行になります。この行列を作成するには、元の画像から3つの点を見つけ、出力画像内でそれらの位置を見つける必要があります。次に、cv2.getAffineTransformは2x3行列を作成し、最後にこの行列は関数cv2.warpAffineに渡されます。
以下の例と私が選択したポイント(緑色でマークされたポイント)を見てみましょう。
img = cv2.imread('drawing.png')
rows,cols,ch = img.shape
pts1 = np.float32([[50,50],[200,50],[50,200]])
pts2 = np.float32([[10,100],[200,50],[100,250]])
M = cv2.getAffineTransform(pts1,pts2)
dst = cv2.warpAffine(img,M,(cols,rows))
plt.subplot(121),plt.imshow(img),plt.title('Input')
plt.subplot(122),plt.imshow(dst),plt.title('Output')
plt.show()
結果は次のとおりです。
14.5パースペクティブ変換
視野角変換には、3x3変換行列が必要です。直線は、変換の前後でまだ直線です。この変換行列を作成するには、入力画像上の4つの点と、出力画像上の対応する位置を見つける必要があります。これらの4つのポイントのいずれか3つを同一線上に置くことはできません。この変換行列は、関数cv2.getPerspectiveTransform()を使用して作成できます。次に、この行列を関数cv2.warpPerspectiveに渡します。
コードは次のように表示されます。
img = cv2.imread('sudokusmall.png')
rows,cols,ch = img.shape
pts1 = np.float32([[56,65],[368,52],[28,387],[389,390]])
pts2 = np.float32([[0,0],[300,0],[0,300],[300,300]])
M = cv2.getPerspectiveTransform(pts1,pts2)
dst = cv2.warpPerspective(img,M,(300,300))
plt.subplot(121),plt.imshow(img),plt.title('Input')
plt.subplot(122),plt.imshow(dst),plt.title('Output')
plt.show()
結果は次のとおりです。
詳細については、公式アカウントに注意してください。