图像透视变换应用
簡介
透視變換是將成像投影到一個新的視平面,也稱作投影映射。投影變換是三維空間上的非線性變換,可看做是仿射變換的更一般形式,簡單講即通過一個3x3的變換矩陣將原圖投影到一個新的視平面(Viewing Plane),在視覺上的直觀表現就是產生或消除了遠近感。
OpenCV透視變換的透視變換
1、warpPerspective
利用透視矩陣對圖像進行透視變換。
-
說明
OpenCV提供了warpPerspective( )函數來實現圖片的透視變換,只需要輸入梯形四個頂點的坐標和目標畫布四個角的坐標,即可自動完成轉換。核心代碼只有兩行:首先讀取兩個坐標數組,計算變換矩陣;然后根據變換矩陣對原圖進行透視變換,并輸出到目標畫布。函數warpPerspective使用指定的矩陣轉換源圖像:
dst(x,y)=src(M11x+M12y+M13M31x+M32y+M33,M21x+M22y+M23M31x+M32y+M33)\texttt{dst} (x,y) = \texttt{src} \left ( \frac{M_{11} x + M_{12} y + M_{13}}{M_{31} x + M_{32} y + M_{33}} , \frac{M_{21} x + M_{22} y + M_{23}}{M_{31} x + M_{32} y + M_{33}} \right ) dst(x,y)=src(M31?x+M32?y+M33?M11?x+M12?y+M13??,M31?x+M32?y+M33?M21?x+M22?y+M23??)
當設置標志WARP_INVERSE_MAP時。否則,首先使用invert反轉轉換,然后將其放在上面的公式中,而不是M中。 -
聲明
void warpPerspective(InputArray src,OutputArray dst,InputArray M,Size dsize,int flags=INTER_LINEAR,int borderMode= BORDER_CONSTANT,const Scalar &borderValue=Scalar() ) -
參數
src輸入圖像 dst 輸出圖像,其大小為dsize,并且類型與src相同。 M 3×3的轉換矩陣。 dsize 輸出圖像的尺寸大小。 flags 插值方法(INTER_LINEAR或INTER_NEAREST)與可選標志WARP_INVERSE_MAP的組合,設置M為逆變換(dst→src\texttt{dst}\rightarrow\texttt{src}dst→src)。 borderMode 邊界補償方式,BORDER_CONSTANT 或者BORDER_REPLICATE borderValue 邊界補償大小,常值,默認為0。
關于變換矩陣M,OpenCV提供兩種方法計算:
1.1、findHomography–計算透視矩陣
通過輸入和輸出圖像中兩組點計算透視矩陣。
-
說明
查找兩個平面之間的透視轉換。
通過變換前、后兩個平面的點尋找出一個單應性變換矩陣H:
使得反投影誤差:
∑i(xi′?h11xi+h12yi+h13h31xi+h32yi+h33)2+(yi′?h21xi+h22yi+h23h31xi+h32yi+h33)2\sum _i \left ( x'_i- \frac{h_{11} x_i + h_{12} y_i + h_{13}}{h_{31} x_i + h_{32} y_i + h_{33}} \right )^2+ \left ( y'_i- \frac{h_{21} x_i + h_{22} y_i + h_{23}}{h_{31} x_i + h_{32} y_i + h_{33}} \right )^2i∑?(xi′??h31?xi?+h32?yi?+h33?h11?xi?+h12?yi?+h13??)2+(yi′??h31?xi?+h32?yi?+h33?h21?xi?+h22?yi?+h23??)2被最小化。如果參數方法設置為默認值0,則該函數使用所有點對通過簡單的最小二乘方案計算初始單應性估計。
但是,如果不是所有的點對(srcPointsisrcPoints_isrcPointsi?, dstPointsidstPoints_idstPointsi?)都適合嚴格的透視圖轉換(也就是說,存在一些異常值),那么這個初始估計就會很差。在這種情況下,您可以使用三種健壯方法中的一種。RANSAC方法,LMeDS和 RHO嘗試許多不同的隨機對應點對的子集(四雙,共線雙被丟棄),估計單應性矩陣使用這個子集和一個簡單的最小二乘算法,然后計算計算單應性的質量/善良的數量(這是內圍層RANSAC或至少值重新投影誤差LMeDS)。然后使用最佳子集生成單應矩陣的初始估計inliers/outliers的掩碼。
無論采用何種方法,無論是否健壯,都可以使用Levenberg-Marquardt方法進一步精簡計算出的單應性矩陣(僅在穩健方法中使用inliers),以進一步降低重投影誤差。
RANSAC和RHO的方法幾乎可以處理任何異常值比率,但是需要一個閾值來區分異常值和異常值。LMeDS方法不需要任何閾值,但是只有在有超過50%的內部值時,它才能正確運行。最后,如果沒有異常值并且噪聲很小,請使用默認方法(method= 0)。 -
聲明
Mat findHomography( InputArray srcPoints, InputArray dstPoints,int method = 0, double ransacReprojThreshold = 3,OutputArray mask=noArray(), const int maxIters = 2000,const double confidence = 0.995 );Mat findHomography(InputArray srcPoints, InputArray dstPoints,OutputArray mask, int method = 0, double ransacReprojThreshold =3 ); -
參數
srcPoint原始平面中點的坐標,其類型為CV_32FC2或vector 的矩陣。 dstPoint 目標平面中點的坐標,類型為CV_32FC2的矩陣或vector 。 method 用于計算單應矩陣的方法。 ransacReprojThreshold mask 通過可靠的方法(RANSAC或LMEDS)設置的可選輸出掩碼。請注意,輸入掩碼值將被忽略。 maxIters RANSAC的最大迭代次數。 confidence 置信度,介于0和1之間。 method取值
- 0: 使用所有點的常規方法,即最小二乘法
- RANSAC: 基于RANSAC的魯棒方法
- LMEDS: 最小中值穩健方法
- RHO: 基于PROSAC穩健的方法
1.2、getPerspectiveTransform–根據四對對應點計算透視變換
通過原圖和變換后圖像的4個對應點(即對應的四邊形)計算出透視變換矩陣。
-
說明
The function calculates the 3×3 matrix of a perspective transform so that:
-
聲明
Mat cv::getPerspectiveTransform ( InputArray src,InputArray dst,int solveMethod = DECOMP_LU ) Mat cv::getPerspectiveTransform ( const Point2f src[],const Point2f dst[],int solveMethod = DECOMP_LU ) -
參數
src源圖像中四邊形頂點的坐標。 dst 目標圖像中相應四邊形頂點的坐標。 solveMethod 傳遞給cv :: solve(DecompTypes)的方法。
2、perspectiveTransform–點的透視變換
利用透視矩陣對點進行透視變換。
-
說明
執行向量的透視矩陣轉換。函數cv :: perspectiveTransform通過將src的每個元素視為2D或3D向量來對其進行轉換,其方式如下:
這里顯示了3D矢量變換。在2D矢量變換的情況下,將省略z分量。該函數轉換2D或3D向量的稀疏集合。如果要使用透視變換來變換圖像,請使用warpPerspective。如果存在反問題,也就是說,您想從幾對對應點中計算出最可能的透視變換,則可以使用getPerspectiveTransform或findHomography。
-
聲明
void perspectiveTransform( InputArray src,OutputArray dst,InputArray m ) -
參數
src輸入兩通道或三通道浮點數組;每個元素都是要轉換的2D / 3D向量。 dst 與src具有相同大小和類型的輸出數組。 m 3x3或4x4浮點轉換矩陣。
應用
?簡單變換
void onMouse(int event, int x, int y, int flags, void* utsc) {if (event==EVENT_LBUTTONUP){//畫出源圖像中需要透視到四邊形中的4個待轉換點circle(src2, Point(x, y), 2, Scalar(0, 0, 255), 2);imshow("wait", src2);//記錄原圖中待轉換的點坐標srcTri[clickTimes].x = x;srcTri[clickTimes].y = y;clickTimes++;cout << "The" << clickTimes << " point: [ " << srcTri[clickTimes - 1].x << "," << srcTri[clickTimes - 1].y << "]" << endl;}if (clickTimes == 4) {//將原圖像中的四個點轉換到目的圖形的對應四個點上//第一個點——左上角dstTri[0].x = 0;dstTri[0].y = 0;//第二個點——右上角dstTri[1].x = 480;dstTri[1].y = 0;//第三個點——右下角dstTri[2].x = 480;dstTri[2].y = 600;//第四個點——左下角dstTri[3].x = 0;dstTri[3].y = 600;//通過原圖像和目標圖像中4個對應點求出透視矩陣Mat m = findHomography(srcTri, dstTri, RANSAC);warpPerspective(src, dst, m, Size(480, 600));imshow("dst", dst);} }int main() {src = imread("D:/test/m.png");src2 = src.clone();namedWindow("src", WINDOW_AUTOSIZE);imshow("src", src2);setMouseCallback("src", onMouse);waitKey(0);return 0; }
注意:需要注意透視變換中點與點的對應順序,應該順時針方向進行點的轉換。
?復雜的透視變換
可以結合第一個應用的方式,使用點擊事件進行獲取需要在目標圖片上轉換的具體坐標。
?自動檢測源映射坐標
上面都是手動或者自己輸入的變換源坐標,下面讓計算機自己檢測需要的4個坐標。
步驟:
1.1 灰度
1.2 二值化分割
1.3 去噪聲
1.4 閉操作
學習:
【OpenCV3.3】通過透視變換矯正變形圖像
Opencv日常之Homography
【OpenCV】透視變換 Perspective Transformation(續)
【圖像處理】透視變換 Perspective Transformation
圖像透視變換原理及實現
詳解 OpenCV 透視變換原理 及 實例
【圖像處理】透視變換 Perspective Transformation
opencv學習筆記五十:透視變換綜合實例
總結
- 上一篇: echarts默认不显示部分折线,鼠标移
- 下一篇: 专利挖掘文章研读笔记