仿射變換的基本概念
仿射變換是一種二維坐標(x, y)到二維坐標(u, v)的線性變換,其數學表達式形式如下:
對應的齊次坐標矩陣表示形式為:
仿射變換保持了二維圖形的“平直性”(直線經仿射變換后依然為直線)和“平行性”(直線之間的相對位置關系保持不變,平行線經仿射變換后依然為平行線,且直線上點的位置順序不會發生變化)。
非共線的三對對應點可以確定一個唯一的仿射變換。
幾種常見的仿射變換形式:
-
平移變換
數學形式:
矩陣形式:
-
縮放變換
矩陣形式:
-
旋轉變換
矩陣形式:
仿射變換形式匯總圖:
OpenCV 中實現仿射變換,一般涉及到 getRotationMatrix2D 和 warpAffine 這兩個函數:
計算二維旋轉變換矩陣:getRotationMatrix2D 函數
Mat getRotationMatrix2D(Point2f center, double angle, double scale);
- center,源圖像的旋轉中心。最終旋轉中心會映射到輸出圖像同樣位置上,即如果(0,0)是旋轉中心,那么輸出圖像旋轉中心同樣是(0,0)。
- angle,旋轉角度。角度 > 0,表示逆時針旋轉(坐標原點是左上角)。
- scale,縮放系數。
進行仿射變換:warpAffine 函數
void warpAffine(InputArray src, OutputArray dst, InputArray M, Size dsize, int flags = INTER_LINEAR, int borderMode = BORDER_CONSTANT, const Scalar& boederValue = Scalar());
- src,輸入圖像,即原圖像,填 Mat 類對象那個即可。
- dst,輸出圖像,需要和源圖像有一樣的類型。
- M,2×3 的變換矩陣。因為變換矩陣第三行形式固定,所以忽略。
- dsize,輸出圖像的尺寸。
- flags,插值的標識符。默認為 INTER_LINEAR (線性插值)。插值就是根據已知數據點(條件),來預測未知數據點值得方法。在尺寸調整過程中,圖像的大小可能發生改變。此時像素與像素之間的關系就不是一一對應關系,因此在尺寸調整過程中,可能會涉及到像素值的插值計算。可選插值方式如下:
INTER_NEAREST(最近鄰差值)
INTER_LINEAR(線性插值,默認)
INTER_AREA(區域插值,利用像素區域關系的重采樣插值)
INTER_CUBIC(三次樣條插值,超過 4×4 像素鄰域內的雙三次插值)
INTER_LANCZOS4(Lanczos 插值,超過 8×8 像素鄰域的 Lanczos 插值)
- borderMode,邊界擴展類型。默認值為 BORDER_CONSTANT,詳解鏈接:https://www.cnblogs.com/bjxqmy/p/12306276.html
- borderValue ,只有當 borderMode取值為 BORDER_CONSTANT 時,這個參數才會被使用,邊界會被填充成 borderValue 指定的顏色。
代碼示例:
#include<opencv.hpp> #include<iostream>
using namespace std; using namespace cv; int main() { Mat src = imread("C:/Users/齊明洋/Desktop/證件照/1.jpg"); imshow("src", src);
//旋轉中心為圖像中心 Point center = Point(src.cols / 2, src.rows / 2); Mat M = getRotationMatrix2D(center, 45, 0.2); Mat dst; warpAffine(src, dst, M, src.size()); circle(dst, center, 2, Scalar(0, 0, 255), 3); imshow("dst", dst); waitKey(0); }
效果演示:
借鑒博客:https://www.cnblogs.com/shine-lee/p/10950963.html
https://www.cnblogs.com/liekkas0626/p/5238564.html
https://www.cnblogs.com/houkai/p/6660272.html