图像旋转变换的推导
前面我們提到了圖像的縮放變換,可以用矩陣乘法的形式來表達變換后的像素位置映射關系。
那么,對于旋轉變換呢?我們可以同樣將其想象成二維平面上矢量的旋轉。如下圖所示,矢量[x1,y1]逆時針旋轉θθ度到了[x2,y2]。
設定矢量的長度為s,根據坐標系定義,我們可以得到:
x2=s?cosβx2=s?cos?β
根據上面的圖形,有:
β=α+θβ=α+θ
因此:
x2=s?cos(α+θ)x2=s?cos?(α+θ) y2=s?sin(α+θ)y2=s?sin?(α+θ)
根據初中所學的三角函數公式:
sin(α+θ)=sinα?cosθ+cosα?sinθsin?(α+θ)=sinα?cosθ+cosα?sinθ cos(α+θ)=cosα?cosθ?sinα?sinθcos?(α+θ)=cosα?cosθ?sinα?sinθ 于是:
x2=s?cosα?cosθ?s?sinα?sinθx2=s?cosα?cosθ?s?sinα?sinθ y2=s?sinα?cosθ+s?cosα?sinθy2=s?sinα?cosθ+s?cosα?sinθ 由于:
x1=s?cosαx1=s?cos?α y1=s?sinαy1=s?sin?α 因此:
x2=x1?cosθ?y1?sinθx2=x1?cosθ?y1?sinθ y2=x1?sinθ+y1?cosθy2=x1?sinθ+y1?cosθ 于是,上式寫成矩陣乘法的形式如下:
[x2y2]=[cosθsinθ?sinθcosθ][x1y1](77)(77)[x2y2]=[cosθ?sinθsinθcosθ][x1y1]
我們來看看一個圖像逆時針旋轉180度的情況。 import cv2import numpy as np import mathlenna = cv2.imread("lenna256.png", 0) row, col = lenna.shapelenna_rotation = np.zeros_like(lenna)A = np.mat([[math.cos(math.pi), -math.sin(math.pi)], [math.sin(math.pi), math.cos(math.pi)]])for r in range(row):for l in range(col):v = np.dot(A.I, np.array([r, l]).T)lenna_rotation[r, l] = lenna[int(v[0, 0]), int(v[0, 1])]cv2.imshow("lenna", lenna) cv2.imshow("rotation", lenna_rotation) cv2.waitKey()
上面的圖像寬度和高度是一樣的,而且旋轉角度是180度,比較特殊。在一般情況下,我們需要注意的是2點:一是旋轉圖像一般要將旋轉中心設置在圖像的中心點位置;二是圖像旋轉后,可能越過了原來的圖像邊界范圍。這些都比較麻煩,好在opencv已經做好了這一切。
lenna = cv2.imread("lenna256.png", 0) row, col = lenna.shape M = cv2.getRotationMatrix2D((col // 2, row // 2), 70, 0.5) dst = cv2.warpAffine(lenna, M, (col, row)) cv2.imshow("rotation", dst) cv2.waitKey()總結
- 上一篇: 图像增强之对比度拉伸
- 下一篇: 图像“颜色选择”怎么用?