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