opencv学习(三十五)之仿射变换warpAffine
1.仿射變換介紹
仿射變換是指在向量空間中進(jìn)行一次線性變換(乘以一個(gè)矩陣)并加上一個(gè)平移(加上一個(gè)向量),變換為另一個(gè)向量空間的過(guò)程。在有限維的情況下,每個(gè)仿射變換可以由一個(gè)矩陣A和一個(gè)向量b給出,它可以寫(xiě)作A和一個(gè)附加的列b。一個(gè)仿射變換對(duì)應(yīng)于一個(gè)矩陣和一個(gè)向量的乘法,而仿射變換的復(fù)合對(duì)應(yīng)于普通的矩陣乘法,只要加入一個(gè)額外的行到矩陣的底下,這一行全部是0除了最右邊是一個(gè)1,而列向量的底下要加上一個(gè)1.
Affine Transform描述了一種二維仿射變換的功能,它是一種二維坐標(biāo)之間的線性變換,保持二維圖形的“平直性”(即變換后直線還是直線,圓弧還是圓弧)和“平行性”(其實(shí)是保持二維圖形間的相對(duì)位置關(guān)系不變,平行線還是平行線,而直線上的點(diǎn)位置順序不變,另特別注意向量間夾角可能會(huì)發(fā)生變化)。仿射變換可以通過(guò)一系列的原子變換的復(fù)合來(lái)實(shí)現(xiàn)包括:平移(Translation)、縮放(Scale)、翻轉(zhuǎn)(Flip)、旋轉(zhuǎn)(Rotation)和錯(cuò)切(Shear).
事實(shí)上,仿射變換代表的是兩幅圖之間的關(guān)系,我們通常使用2x3矩陣來(lái)表示仿射變換如下:
考慮到我們要使用矩陣A和B對(duì)二維向量做變換,所以也能表示為下列形式:
或
得到如下結(jié)果:
2.仿射變換求法
從上面解釋中我們得知仿射變換表示的就是兩幅圖片的一種聯(lián)系,關(guān)于這種聯(lián)系的信息大致可以從以下兩種場(chǎng)景獲得。
a. 我們已知X和T而且我們知道他們是有聯(lián)系的,接下來(lái)的工作就是求解矩陣M
b. 我們一致M和X要求得T,我們只需要應(yīng)用算式T=M.X即可。對(duì)于這種聯(lián)系的信息可以用矩陣M清晰的表達(dá)(即給出明確的2x3矩陣)或者也可以用兩幅圖片點(diǎn)之間幾何關(guān)系來(lái)表達(dá)。
因?yàn)榫仃嘙聯(lián)系著兩幅圖片,我們以其表示兩圖中各三點(diǎn)直接的聯(lián)系為例,如下:
點(diǎn)1,2和3(在圖一中形成一個(gè)三角)與圖二中三個(gè)點(diǎn)一一映射,仍然形成三角形,但形狀已經(jīng)大大改變。如果我們能通過(guò)這樣兩組三點(diǎn)求出仿射變換(你能選擇自己喜歡的點(diǎn)),接下來(lái)我們就能把仿射變換應(yīng)用到圖像中所有的點(diǎn)。
3.opencv實(shí)現(xiàn)仿射變換
利用opencv實(shí)現(xiàn)仿射變換一般會(huì)涉及到warpAffine和getRotationMatrix2D兩個(gè)函數(shù),其中warpAffine可以實(shí)現(xiàn)一些簡(jiǎn)單的重映射,而getRotationMatrix2D可以獲得旋轉(zhuǎn)矩陣。
warpAffine函數(shù)
參數(shù)解釋
. src: 輸入圖像
. dst: 輸出圖像,尺寸由dsize指定,圖像類型與原圖像一致
. M: 2X3的變換矩陣
. dsize: 指定圖像輸出尺寸
. flags: 插值算法標(biāo)識(shí)符,有默認(rèn)值INTER_LINEAR,如果插值算法為WARP_INVERSE_MAP, warpAffine函數(shù)使用如下矩陣進(jìn)行圖像轉(zhuǎn)換
常用的插值算法如下:
. borderMode: 邊界像素模式,有默認(rèn)值BORDER_CONSTANT
. borderValue: 邊界取值,有默認(rèn)值Scalar()即0
getRotationMatrix2D函數(shù)
Mat cv::getRotationMatrix2D ( Point2f center,double angle,double scale )參數(shù)解釋
. center: Point2f類型,表示原圖像的旋轉(zhuǎn)中心
. angle: double類型,表示圖像旋轉(zhuǎn)角度,角度為正則表示逆時(shí)針旋轉(zhuǎn),角度為負(fù)表示逆時(shí)針旋轉(zhuǎn)(坐標(biāo)原點(diǎn)是圖像左上角)
. scale: 縮放系數(shù)
函數(shù)計(jì)算如下矩陣:
其中
示例代碼
#include <iostream> #include <opencv2/core.hpp> #include <opencv2/highgui.hpp> #include <opencv2/imgproc.hpp>using namespace std; using namespace cv;//全局變量 String src_windowName = "原圖像"; String warp_windowName = "仿射變換"; String warp_rotate_windowName = "仿射旋轉(zhuǎn)變換"; String rotate_windowName = "圖像旋轉(zhuǎn)";int main() {Point2f srcTri[3];Point2f dstTri[3];Mat rot_mat(2, 3, CV_32FC1);Mat warp_mat(2, 3, CV_32FC1);Mat srcImage, warp_dstImage, warp_rotate_dstImage, rotate_dstImage;//加載圖像srcImage = imread("dog.jpg");//判斷文件是否加載成功if(srcImage.empty()){cout << "圖像加載失敗!" << endl;return -1;}elsecout << "圖像加載成功!" << endl << endl;//創(chuàng)建仿射變換目標(biāo)圖像與原圖像尺寸類型相同warp_dstImage = Mat::zeros(srcImage.rows, srcImage.cols, srcImage.type());//設(shè)置三個(gè)點(diǎn)來(lái)計(jì)算仿射變換srcTri[0] = Point2f(0, 0);srcTri[1] = Point2f(srcImage.cols - 1, 0);srcTri[2] = Point2f(0, srcImage.rows - 1);dstTri[0] = Point2f(srcImage.cols*0.0, srcImage.rows*0.33);dstTri[1] = Point2f(srcImage.cols*0.85, srcImage.rows*0.25);dstTri[2] = Point2f(srcImage.cols*0.15, srcImage.rows*0.7);//計(jì)算仿射變換矩陣warp_mat = getAffineTransform(srcTri, dstTri);//對(duì)加載圖形進(jìn)行仿射變換操作warpAffine(srcImage, warp_dstImage, warp_mat, warp_dstImage.size());//計(jì)算圖像中點(diǎn)順時(shí)針旋轉(zhuǎn)50度,縮放因子為0.6的旋轉(zhuǎn)矩陣Point center = Point(warp_dstImage.cols/2, warp_dstImage.rows/2);double angle = -50.0;double scale = 0.6;//計(jì)算旋轉(zhuǎn)矩陣rot_mat = getRotationMatrix2D(center, angle, scale);//旋轉(zhuǎn)已扭曲圖像warpAffine(warp_dstImage, warp_rotate_dstImage, rot_mat, warp_dstImage.size());//將原圖像旋轉(zhuǎn)warpAffine(srcImage, rotate_dstImage, rot_mat, srcImage.size());//顯示變換結(jié)果namedWindow(src_windowName, WINDOW_AUTOSIZE);imshow(src_windowName, srcImage);namedWindow(warp_windowName, WINDOW_AUTOSIZE);imshow(warp_windowName, warp_dstImage);namedWindow(warp_rotate_windowName, WINDOW_AUTOSIZE);imshow(warp_rotate_windowName, warp_rotate_dstImage);namedWindow(rotate_windowName, WINDOW_AUTOSIZE);imshow(rotate_windowName, rotate_dstImage);waitKey(0);return 0; }運(yùn)行結(jié)果
總結(jié)
以上是生活随笔為你收集整理的opencv学习(三十五)之仿射变换warpAffine的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 哈工大 软件构造Lab1的设计实现
- 下一篇: 分享文章:如何提高你的学习能力,也许对你