Opencv画像の幾何学的処理と画像回転pythonの実装

Opencvによる画像の幾何学的処理と回転画像のpython実装

はじめに:深層学習の分野では、データ拡張のために変換、回転、ミラーリングなどの操作を使用することがよくあります。従来のCV分野では、撮影角度の問題により、画像を修正する必要があります。幾何学的変換がこのプロセスです。したがって、幾何学的変換を理解し、学ぶ必要があります。

  • 幾何学的変換の原則のほとんどは似ていますが、変換マトリックスは異なります。したがって、学習の例として、最も一般的に使用される変換と回転を取り上げます。
    ピクセル位置の変換方法は次のとおりです。
    ここに写真の説明を挿入

式のTは変換行列です。ここで、(v、w)は元の座標、(x、y)は変換された座標です。異なる変換は異なる行列に対応します。一般的な変換行列とその関数は次のとおりです。

ここに写真の説明を挿入

座標系の変換

  • 変換の中心ズームと変換の場合、画像座標の原点(画像の左上隅が原点)を変換の中心として使用できます。これは座標系の変換を必要とせず、一般的な形式で直接計算できます。以下のために回転及びオフセット原点をさ一般に基づいて画像の中心システムの座標変換を含みます、。
  • 画像座標の原点は画像の左上隅にあり、水平方向はX軸、垂直方向はY軸です。数学の教科書の一般的な座標系は、原点としての画像の中心に基づいており、水平方向の右はX軸、垂直方向の上はY軸であり、これはカルテシアン座標系と呼ばれます。下の写真を見てください:

ここに写真の説明を挿入

したがって、回転とオフセットには、3つのステップ(3つの変換)が必要です。

  • 1.入力された元の画像の画像座標をデカルト座標系に変換します。
  • 2.回転計算を実行します。回転行列は以前に与えられています。
  • 3.回転した画像のカルテシアン座標を画像座標に変換し直します。

したがって、上記の3つのステップ(3つの変換)によると、回転(時計回りの回転)の変換形式は、3つの変換に3つのマトリックスがあります。

ここに写真の説明を挿入

逆マッピング

  • ゴンザレスの「DigitalImageProcessing_Third Edition」では、フォワードマッピングが、変換式を使用して元の画像に従って出力画像の対応するピクセルの空間位置を直接計算することであることは非常に明確です。これにより、問題が発生する可能性があります。出力画像の同じ場所に複数のピクセル座標がマッピングされているか、出力画像の一部の場所が対応する入力画像のピクセルとまったく一致しない、つまりマッピングされていないため、通常の穴(黒いハニカム)が発生する可能性があります。 。より良い方法は、逆マッピングを使用することです。出力画像の位置(x、y)をスキャンし、Image(Tの逆行列)を介して入力画像に対応する位置(v、w)を計算し、補間を使用します。このメソッドは、出力画像内の位置のグレー値を決定します。

補間

  • リバースマッピングを使用した後、出力画像の位置の値を補間法で決定する必要があるため、補間アルゴリズムを選択する必要があります。通常、最近傍補間、双線形補間、双立方補間などがあります。OpencVはデフォルトで双線形補間を使用します。

1.Opencvインターフェース呼び出し

以下は、opencvでの画像の幾何学的変換インターフェース呼び出しです。

import cv2
import numpy as np

画像翻訳

#读取图片
img = cv2.imread('E:/Machine Learning/OpenCV/task2/task2.jpg',)
#getRotationMatrix2D有三个参数,第一个为旋转中心,第二个为旋转角度,第三个为缩放比例
M = cv2.getRotationMatrix2D((cols/2,rows/2),90,1)
rows,cols,channel=img.shape
move=np.float32([[1,0,100],[0,1,50]])
dst = cv2.warpAffine(img, move, (rows,cols))
cv2.imshow('original', img)
cv2.imshow('result', dst)
cv2.imwrite('E:/Machine Learning/OpenCV/task2/1.jpg',dst)
cv2.waitKey(0)
cv2.destroyAllWindows()

ここに写真の説明を挿入

ここに写真の説明を挿入

画像の回転

#getRotationMatrix2D有三个参数,第一个为旋转中心,第二个为旋转角度,第三个为缩放比例
M = cv2.getRotationMatrix2D((cols/2,rows/2),90,1)
dst = cv2.warpAffine(img, M, (rows,cols))
cv2.imshow('original', img)
cv2.imshow('result', dst)
cv2.imwrite('E:/Machine Learning/OpenCV/task2/2.jpg',dst)
cv2.waitKey(0)
cv2.destroyAllWindows()

ここに写真の説明を挿入

アフィン変換

  • アフィン変換は、2次元座標から2次元座標への線形変換であり、2次元グラフィックスの「平坦性」を維持します。変換前に平行だった線は、変換後も平行のままです。以下に示すように:
pst1=np.float32([[50,50],[0,100],[200,100]])
pst2=np.float32([[10,100],[200,70],[150,300]])
M=cv2.getAffineTransform(pst1,pst2)
dst=cv2.warpAffine(img,M,(rows,cols))
cv2.imshow('original', img)
cv2.imshow('result', dst)
cv2.imwrite('E:/Machine Learning/OpenCV/task2/3.jpg',dst)
cv2.waitKey(0)
cv2.destroyAllWindows()

ここに写真の説明を挿入

概要

  • 1.従来のCV分野では、カメラの撮影角度により、画像を補正する必要があります。処理方法には、平行移動、回転、アフィン、遠近法などがあります。
  • 2.画像​​の幾何学的変換プロセスでは、変換マトリックスを使用して画像のピクセル座標をマッピングします。
  • 3.画像を回転させるには、円の中心を指定する必要があります。ここでは、回転中心を原点として座標系をデカルト座標系に変換する必要があります。マッピングが完了すると、画像の座標系に戻ります。
  • 4.マッピングプロセスでは、後方マッピングの方が優れており、前方マッピングにはマッピングのオーバーラップとボイドが含まれる場合があります。通常、グレーレベルのマッピングには双線形補間が使用されます。

2.画像​​回転のpythonコード実装

import numpy as np
import cv2
import matplotlib as mpl
import matplotlib.pyplot as plt
# 排除警告信息
import warnings
# matplotlib画图常见参数设置
mpl.rcParams["font.family"] = "SimHei" 
# 设置字体
mpl.rcParams["axes.unicode_minus"]=False 
# 用来正常显示负号
plt.rcParams['font.sans-serif']=['SimHei'] 
# 用来正常显示中文标签# 嵌入式显示图形
%matplotlib inline
warnings.filterwarnings("ignore")
#读取图片
img = cv2.imread('E:/Machine Learning/OpenCV/task2/task2.jpg',cv2.IMREAD_GRAYSCALE)
rows,cols=img.shape
#设置旋转角度,np.sin()使用弧度计算
rote=45
pi_rote=np.pi*45/180

#变换矩阵
n=cols/2
m=rows/2
change_ax=np.matrix([[1,0,0],[0,-1,0],[-n,m,1]])
rote_img=np.matrix([[np.cos(pi_rote),-np.sin(pi_rote),0],[np.sin(pi_rote),np.cos(pi_rote),0],[0,0,1]])
change_back=np.matrix([[1,0,0],[0,-1,0],[n,m,1]])
T1=np.matmul(change_ax,rote_img)
T2=np.matmul(T1,change_back)
T=T2.I

#构建一个同样规格的图片
img1 = np.ones((rows,cols), np.uint8)*255

#利用变换矩阵,算该图片像素对应的灰度
for i in range(cols):
    for j in range(rows):
        rloc=[i,j,1]
        oloc=np.matmul(rloc,T)
        x,y= np.ceil(oloc[0,0]).astype(int), np.ceil(oloc[0,1]).astype(int)
        if (x<0 or x>cols-1) or(y<0 or y>rows-1):
            cor=255
        else:
            cor=img.item(x,y)
            img1.itemset((i,j),cor)
        
#显示变换后的图像
plt.subplot(1,2,1)
plt.title('原始图')
plt.imshow(img)
plt.subplot(1,2,2)
plt.title('旋转45度')
plt.imshow(img1)
plt.show()

ここに写真の説明を挿入

おすすめ

転載: blog.csdn.net/hu_hao/article/details/105711592