图像透视变换应用
簡介
透視變換是將成像投影到一個新的視平面,也稱作投影映射。投影變換是三維空間上的非線性變換,可看做是仿射變換的更一般形式,簡單講即通過一個3x3的變換矩陣將原圖投影到一個新的視平面(Viewing Plane),在視覺上的直觀表現(xiàn)就是產(chǎn)生或消除了遠近感。
OpenCV透視變換的透視變換
1、warpPerspective
利用透視矩陣對圖像進行透視變換。
-  說明 
 OpenCV提供了warpPerspective( )函數(shù)來實現(xiàn)圖片的透視變換,只需要輸入梯形四個頂點的坐標(biāo)和目標(biāo)畫布四個角的坐標(biāo),即可自動完成轉(zhuǎn)換。核心代碼只有兩行:首先讀取兩個坐標(biāo)數(shù)組,計算變換矩陣;然后根據(jù)變換矩陣對原圖進行透視變換,并輸出到目標(biāo)畫布。函數(shù)warpPerspective使用指定的矩陣轉(zhuǎn)換源圖像: 
 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??)
 當(dāng)設(shè)置標(biāo)志W(wǎng)ARP_INVERSE_MAP時。否則,首先使用invert反轉(zhuǎn)轉(zhuǎn)換,然后將其放在上面的公式中,而不是M中。
-  聲明 void warpPerspective(InputArray src,OutputArray dst,InputArray M,Size dsize,int flags=INTER_LINEAR,int borderMode= BORDER_CONSTANT,const Scalar &borderValue=Scalar() )
-  參數(shù) src輸入圖像 dst 輸出圖像,其大小為dsize,并且類型與src相同。 M 3×3的轉(zhuǎn)換矩陣。 dsize 輸出圖像的尺寸大小。 flags 插值方法(INTER_LINEAR或INTER_NEAREST)與可選標(biāo)志W(wǎng)ARP_INVERSE_MAP的組合,設(shè)置M為逆變換(dst→src\texttt{dst}\rightarrow\texttt{src}dst→src)。 borderMode 邊界補償方式,BORDER_CONSTANT 或者BORDER_REPLICATE borderValue 邊界補償大小,常值,默認為0。 
關(guān)于變換矩陣M,OpenCV提供兩種方法計算:
1.1、findHomography–計算透視矩陣
通過輸入和輸出圖像中兩組點計算透視矩陣。
-  說明 
 查找兩個平面之間的透視轉(zhuǎn)換。
 通過變換前、后兩個平面的點尋找出一個單應(yīng)性變換矩陣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被最小化。如果參數(shù)方法設(shè)置為默認值0,則該函數(shù)使用所有點對通過簡單的最小二乘方案計算初始單應(yīng)性估計。 
 但是,如果不是所有的點對(srcPointsisrcPoints_isrcPointsi?, dstPointsidstPoints_idstPointsi?)都適合嚴(yán)格的透視圖轉(zhuǎn)換(也就是說,存在一些異常值),那么這個初始估計就會很差。在這種情況下,您可以使用三種健壯方法中的一種。RANSAC方法,LMeDS和 RHO嘗試許多不同的隨機對應(yīng)點對的子集(四雙,共線雙被丟棄),估計單應(yīng)性矩陣使用這個子集和一個簡單的最小二乘算法,然后計算計算單應(yīng)性的質(zhì)量/善良的數(shù)量(這是內(nèi)圍層RANSAC或至少值重新投影誤差LMeDS)。然后使用最佳子集生成單應(yīng)矩陣的初始估計inliers/outliers的掩碼。
 無論采用何種方法,無論是否健壯,都可以使用Levenberg-Marquardt方法進一步精簡計算出的單應(yīng)性矩陣(僅在穩(wěn)健方法中使用inliers),以進一步降低重投影誤差。
 RANSAC和RHO的方法幾乎可以處理任何異常值比率,但是需要一個閾值來區(qū)分異常值和異常值。LMeDS方法不需要任何閾值,但是只有在有超過50%的內(nèi)部值時,它才能正確運行。最后,如果沒有異常值并且噪聲很小,請使用默認方法(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 );
-  參數(shù) srcPoint原始平面中點的坐標(biāo),其類型為CV_32FC2或vector 的矩陣。 dstPoint 目標(biāo)平面中點的坐標(biāo),類型為CV_32FC2的矩陣或vector 。 method 用于計算單應(yīng)矩陣的方法。 ransacReprojThreshold mask 通過可靠的方法(RANSAC或LMEDS)設(shè)置的可選輸出掩碼。請注意,輸入掩碼值將被忽略。 maxIters RANSAC的最大迭代次數(shù)。 confidence 置信度,介于0和1之間。 method取值- 0: 使用所有點的常規(guī)方法,即最小二乘法
- RANSAC: 基于RANSAC的魯棒方法
- LMEDS: 最小中值穩(wěn)健方法
- RHO: 基于PROSAC穩(wěn)健的方法
 
1.2、getPerspectiveTransform–根據(jù)四對對應(yīng)點計算透視變換
通過原圖和變換后圖像的4個對應(yīng)點(即對應(yīng)的四邊形)計算出透視變換矩陣。
-  說明 
 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 )
-  參數(shù) src源圖像中四邊形頂點的坐標(biāo)。 dst 目標(biāo)圖像中相應(yīng)四邊形頂點的坐標(biāo)。 solveMethod 傳遞給cv :: solve(DecompTypes)的方法。 
2、perspectiveTransform–點的透視變換
利用透視矩陣對點進行透視變換。
-  說明 
 執(zhí)行向量的透視矩陣轉(zhuǎn)換。函數(shù)cv :: perspectiveTransform通過將src的每個元素視為2D或3D向量來對其進行轉(zhuǎn)換,其方式如下: 
 
 這里顯示了3D矢量變換。在2D矢量變換的情況下,將省略z分量。該函數(shù)轉(zhuǎn)換2D或3D向量的稀疏集合。如果要使用透視變換來變換圖像,請使用warpPerspective。如果存在反問題,也就是說,您想從幾對對應(yīng)點中計算出最可能的透視變換,則可以使用getPerspectiveTransform或findHomography。 
-  聲明 void perspectiveTransform( InputArray src,OutputArray dst,InputArray m )
-  參數(shù) src輸入兩通道或三通道浮點數(shù)組;每個元素都是要轉(zhuǎn)換的2D / 3D向量。 dst 與src具有相同大小和類型的輸出數(shù)組。 m 3x3或4x4浮點轉(zhuǎn)換矩陣。 
應(yīng)用
?簡單變換
void onMouse(int event, int x, int y, int flags, void* utsc) {if (event==EVENT_LBUTTONUP){//畫出源圖像中需要透視到四邊形中的4個待轉(zhuǎn)換點circle(src2, Point(x, y), 2, Scalar(0, 0, 255), 2);imshow("wait", src2);//記錄原圖中待轉(zhuǎn)換的點坐標(biāo)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) {//將原圖像中的四個點轉(zhuǎn)換到目的圖形的對應(yīng)四個點上//第一個點——左上角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;//通過原圖像和目標(biāo)圖像中4個對應(yīng)點求出透視矩陣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; }
 
 
注意:需要注意透視變換中點與點的對應(yīng)順序,應(yīng)該順時針方向進行點的轉(zhuǎn)換。
?復(fù)雜的透視變換
 可以結(jié)合第一個應(yīng)用的方式,使用點擊事件進行獲取需要在目標(biāo)圖片上轉(zhuǎn)換的具體坐標(biāo)。
 
 
 
 ?自動檢測源映射坐標(biāo)
 上面都是手動或者自己輸入的變換源坐標(biāo),下面讓計算機自己檢測需要的4個坐標(biāo)。
 步驟:
1.1 灰度
1.2 二值化分割
1.3 去噪聲
1.4 閉操作
 
 
 
 
 
 
 
 
學(xué)習(xí):
 【OpenCV3.3】通過透視變換矯正變形圖像
Opencv日常之Homography
【OpenCV】透視變換 Perspective Transformation(續(xù))
【圖像處理】透視變換 Perspective Transformation
圖像透視變換原理及實現(xiàn)
詳解 OpenCV 透視變換原理 及 實例
【圖像處理】透視變換 Perspective Transformation
opencv學(xué)習(xí)筆記五十:透視變換綜合實例
總結(jié)
 
                            
                        - 上一篇: echarts默认不显示部分折线,鼠标移
- 下一篇: python视频处理库推荐_Python
