z变换判断稳定性和因果性_图像处理的仿射变换与透视变换
原文首發(fā)于微信公眾號(hào):【3D視覺(jué)工坊】。
引言
這一周主要在研究圖像的放射變換與透視變換,目前出現(xiàn)的主要問(wèn)題是需要正確識(shí)別如下圖中的編碼標(biāo)志點(diǎn)圓心。
1.當(dāng)傾斜角較小時(shí):
傾斜角較小
2.傾斜角較大時(shí):
傾斜角較大
由上面兩幅圖可以看出,當(dāng)傾斜角較大時(shí),中間的圓斑將變?yōu)闄E圓,四周的圓環(huán)帶之間的面積比關(guān)系也將出現(xiàn)變化,影響識(shí)別算法的正確判斷。
那么如何將傾斜角如此大的編碼標(biāo)志點(diǎn)進(jìn)行校正呢?這便是本篇文章需要解決的問(wèn)題。
一 仿射變換與透視變換
其實(shí)一直有點(diǎn)沒(méi)太理解「放射」倆字是啥意思,但是大家都這么叫,其實(shí)仿射變換和透視變換更直觀的叫法可以叫做「平面變換」和「空間變換」或者「二維坐標(biāo)變換」和「三維坐標(biāo)變換」。如果這么命名的話,其實(shí)很顯然,這倆是一回事,只不過(guò)一個(gè)是二維坐標(biāo)(x,y),一個(gè)是三維坐標(biāo)(x,y,z)。也就是:
仿射變換:
透視變換:
1.31.41.51.6 從另一個(gè)角度也能說(shuō)明三維變換和二維變換的意思,仿射變換的方程組有6個(gè)未知數(shù),所以要求解就需要找到3組映射點(diǎn),三個(gè)點(diǎn)剛好確定一個(gè)平面。透視變換的方程組有8個(gè)未知數(shù),所以要求解就需要找到4組映射點(diǎn),四個(gè)點(diǎn)就剛好確定了一個(gè)三維空間。
仿射變換和透視變換的數(shù)學(xué)原理也不需要深究,其計(jì)算方法為坐標(biāo)向量和變換矩陣的乘積,換言之就是矩陣運(yùn)算。在應(yīng)用層面,放射變換是圖像基于3個(gè)固定頂點(diǎn)的變換,如圖1.1:所示:
圖中紅點(diǎn)即為固定頂點(diǎn),在變換先后固定頂點(diǎn)的像素值不變,圖像整體則根據(jù)變換規(guī)則進(jìn)行變換同理,透視變換是圖像基于4個(gè)固定頂點(diǎn)的變換,如圖1.2所示:
圖1.2 基于四個(gè)點(diǎn)的透視變換在OpenCV中,放射變換和透視變換均有封裝好的函數(shù),分別為:
void warpAffine(InputArray src, OutputArray dst, InputArray M, Size dsize, int flags=INTER_LINEAR, int borderMode=BORDER_CONSTANT, const Scalar& borderValue=Scalar())與
void warpPerspective(InputArray src, OutputArray dst, InputArray M, Size dsize, int flags=INTER_LINEAR, int borderMode=BORDER_CONSTANT, const Scalar& borderValue=Scalar())兩種變換函數(shù)形式完全相同,因此以仿射變換為例:
void warpAffine(InputArray src, OutputArray dst, InputArray M, Size dsize, int flags=INTER_LINEAR, int borderMode=BORDER_CONSTANT, const Scalar& borderValue=Scalar()) 參數(shù)InputArray src:輸入變換前的圖像; 參數(shù)OutputArray dst:輸出變換后圖像,需要初始化一個(gè)空矩陣用來(lái)保存結(jié)果,不用設(shè)定矩陣尺寸; 參數(shù)Size dsize:設(shè)置輸出圖像大小; 參數(shù)int flags=INTER_LINEAR:設(shè)置插值方式,默認(rèn)方式為線性插值; 后兩個(gè)參數(shù)不常用,在此不贅述。關(guān)于生成變換矩陣InputArray M的函數(shù)getAffineTransform():
Mat getAffineTransform(const Point2f* src, const Point2f* dst) 參數(shù)const Point2f* src:原圖的三個(gè)固定頂點(diǎn) 參數(shù)const Point2f* dst:目標(biāo)圖像的三個(gè)固定頂點(diǎn) 返回值:Mat型變換矩陣,可直接用于warpAffine()函數(shù) 注意,頂點(diǎn)數(shù)組長(zhǎng)度超過(guò)3個(gè),則會(huì)自動(dòng)以前3個(gè)為變換頂點(diǎn);數(shù)組可用Point2f[]或Point2f*表示示例代碼如下:
//讀取原圖Mat I = imread("..//img.jpg");//設(shè)置空矩陣用于保存目標(biāo)圖像Mat dst;//設(shè)置原圖變換頂點(diǎn)Point2f AffinePoints0[3] = { Point2f(100, 50), Point2f(100, 390), Point2f(600, 50) };//設(shè)置目標(biāo)圖像變換頂點(diǎn)Point2f AffinePoints1[3] = { Point2f(200, 100), Point2f(200, 330), Point2f(500, 50) };//計(jì)算變換矩陣Mat Trans = getAffineTransform(AffinePoints0, AffinePoints1);//矩陣仿射變換warpAffine(I, dst, Trans, Size(I.cols, I.rows));//分別顯示變換先后圖像進(jìn)行對(duì)比imshow("src", I);imshow("dst", dst);waitKey();同理,透視變換與仿射變換函數(shù)類似:
void warpPerspective(InputArray src, OutputArray dst, InputArray M, Size dsize, int flags=INTER_LINEAR, int borderMode=BORDER_CONSTANT, const Scalar& borderValue=Scalar())生成變換矩陣函數(shù)為:
Mat getPerspectiveTransform(const Point2f* src, const Point2f* dst)注意透視變換頂點(diǎn)為4個(gè)。
兩種變換完整代碼及結(jié)果比較:
#include <iostream> #include <opencv.hpp> using namespace std; using namespace cv;Mat AffineTrans(Mat src, Point2f* scrPoints, Point2f* dstPoints) {Mat dst;Mat Trans = getAffineTransform(scrPoints, dstPoints);warpAffine(src, dst, Trans, Size(src.cols, src.rows), CV_INTER_CUBIC);return dst; }Mat PerspectiveTrans(Mat src, Point2f* scrPoints, Point2f* dstPoints) {Mat dst;Mat Trans = getPerspectiveTransform(scrPoints, dstPoints);warpPerspective(src, dst, Trans, Size(src.cols, src.rows), CV_INTER_CUBIC);return dst; }void main() {Mat I = imread("..//img.jpg"); //700*438Point2f AffinePoints0[4] = { Point2f(100, 50), Point2f(100, 390), Point2f(600, 50), Point2f(600, 390) };Point2f AffinePoints1[4] = { Point2f(200, 100), Point2f(200, 330), Point2f(500, 50), Point2f(600, 390) };Mat dst_affine = AffineTrans(I, AffinePoints0, AffinePoints1);Mat dst_perspective = PerspectiveTrans(I, AffinePoints0, AffinePoints1);for (int i = 0; i < 4; i++){circle(I, AffinePoints0[i], 2, Scalar(0, 0, 255), 2);circle(dst_affine, AffinePoints1[i], 2, Scalar(0, 0, 255), 2);circle(dst_perspective, AffinePoints1[i], 2, Scalar(0, 0, 255), 2);}imshow("origin", I);imshow("affine", dst_affine);imshow("perspective", dst_perspective);waitKey(); } 1.3 程序運(yùn)行結(jié)果可以看出,仿射變換以3個(gè)點(diǎn)為基準(zhǔn)點(diǎn),即使數(shù)組長(zhǎng)度為4也僅取前3個(gè)點(diǎn)作為基準(zhǔn)點(diǎn);透視變換以4個(gè)點(diǎn)為基準(zhǔn)點(diǎn),兩種變換結(jié)果不相同。應(yīng)根據(jù)實(shí)際情況判斷使用哪種變換方式更佳。
二 編碼標(biāo)志點(diǎn)透視變換矯正
回到引言部分的問(wèn)題,對(duì)于編碼標(biāo)志點(diǎn)中,我們可以以中心橢圓與坐標(biāo)軸的四個(gè)交點(diǎn)為檢測(cè)點(diǎn),以橢圓的長(zhǎng)軸為半徑繪制一個(gè)理想圓,理想圓與坐標(biāo)軸的交點(diǎn)為目標(biāo)點(diǎn)。運(yùn)用上面介紹的透視變換知識(shí),便可以很容易的解決問(wèn)題,如圖2.1所示。
圖2.1 透視變換三 跋
文章的最后,單純地需要感謝一下高靜小朋友提供的測(cè)試樣圖,才得以文章正式成文。
文章始發(fā)于我的個(gè)人公眾號(hào):3D視覺(jué)工坊。
知識(shí)星球:「3D視覺(jué)工坊」。
總結(jié)
以上是生活随笔為你收集整理的z变换判断稳定性和因果性_图像处理的仿射变换与透视变换的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: mysql做文本挖掘_4graphlab
- 下一篇: java递归老鼠走迷宫_递归算法求老鼠走