OpenCV仿射變換的示例代碼
1、認(rèn)識(shí)仿射變換
仿射變換(Affine Map)又稱仿射映射,是指在幾何中,一個(gè)向量空間進(jìn)行一次線性變換并接上一個(gè)平移,變換為另一個(gè)向量空間的過(guò)程。保持二維圖形之間的相對(duì)位置保持不變,平行線依然是平行線,且直線上的點(diǎn)的位置順序不變。
一個(gè)任意的仿射變換都可以表示為乘以一個(gè)矩陣接著再加上一個(gè)向量的形式。三種常見的變換形式:
- 旋轉(zhuǎn):ratation(線性變換)
- 平移:translation(向量加)
- 縮放:scale(線性變換)
通常使用2 x 3的矩陣來(lái)表示仿射變換:


2、仿射變換的求法
說(shuō)明:仿射變換表示的就是兩幅圖片之間的一種聯(lián)系,關(guān)于這種聯(lián)系的信息大致可以分為以下兩種場(chǎng)景:
- 已知X和T,而且已知它們是有聯(lián)系的,接下來(lái)的跟著就是求出矩陣M。
- 已知M和X,想要求得T。只要應(yīng)用算式T=M*X即可。

如上,點(diǎn)1、2、3(在Image 1中形成一個(gè)三角形)與Image 2中的三個(gè)點(diǎn)是一一映射的關(guān)系,且它們?nèi)匀恍纬扇切?,但形狀已?jīng)和之前的不一樣的,可以通過(guò)這樣的兩組三點(diǎn)求出仿射變換,然后把這種變換應(yīng)用到圖像中去。
3、進(jìn)行仿射變換:warpAffine()函數(shù)
warpAffine()函數(shù)的作用依據(jù)下面的公式對(duì)圖像做仿射變換:

void warpAffine(InputArray src,OutputArray dst,InputArray M,Size dsize,int flags=INTER_LINEAR,intborderMOde=BODER_CONSTANT,const Scalar& borderValue=Scalar())
- 第一個(gè)參數(shù):輸入圖像
- 第二個(gè)參數(shù):輸出圖像,函數(shù)調(diào)用后的運(yùn)算結(jié)果存在這里,需要和源圖片有一樣的尺寸和類型
- 第三個(gè)參數(shù):2 x 3的變換矩陣,求得的仿射變換
- 第四個(gè)參數(shù):表示輸出圖像的尺寸
- 第五個(gè)參數(shù):插值方法的標(biāo)識(shí)符。默認(rèn)值是線性插值法(INTER_LINEAR)
![[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來(lái)直接上傳(img-oCWwUOWK-1659625193572)(F:\學(xué)習(xí)記錄\opencv\截圖\image-20220804143908462.jpg)]](http://img.jbzj.com/file_images/article/202208/202208050831204.jpg)
- 第六個(gè)參數(shù):邊界像素模式
- 第七個(gè)參數(shù):在恒定的邊界情況下取值,默認(rèn)值Scalar(),即0
4、計(jì)算二維旋轉(zhuǎn)變換矩陣:getRotationMatrix2D()函數(shù)
說(shuō)明:getRotationMatrix2D()函數(shù)用于計(jì)算二維旋轉(zhuǎn)變換矩陣。變換會(huì)將旋轉(zhuǎn)中心映射到它自身
Mat getRotationMatrix2D(Point2f center,double angle,double scale)
- 第一個(gè)參數(shù):表示源圖像的旋轉(zhuǎn)中心
- 第二個(gè)參數(shù):旋轉(zhuǎn)角度。角度為正值表示向逆時(shí)針旋轉(zhuǎn)(坐標(biāo)原點(diǎn)是左上角)
- 第三個(gè)參數(shù):縮放系統(tǒng)
5、示例程序:
#include<opencv2/opencv.hpp>
#include<opencv2/imgproc/imgproc.hpp>
#include<opencv2/highgui/highgui.hpp>
#include<iostream>
using namespace std;
using namespace cv;
#define WINDOW_NAME1 "【原始圖窗口】"
#define WINDOW_NAME2 "【經(jīng)過(guò)Warp后的窗口】"
#define WINDOW_NAME3 "【經(jīng)過(guò)Warp和Rotate后的窗口】"
int main()
{
system("color 2F");
//參數(shù)準(zhǔn)備
Point2f srcTriangle[3];
Point2f dstTriangle[3];
Mat rotMat(2, 3, CV_32FC1);
Mat warpMat(2, 3, CV_32FC1);
Mat srcImage, dstImage_warp, dstImage_warp_rotate;
//加載源圖像
srcImage = imread("E:\\Pec\\lan.jpg",1);
//設(shè)置目標(biāo)圖像的大小和類型與源圖像一致
dstImage_warp = Mat::zeros(srcImage.rows, srcImage.cols, srcImage.type());
//設(shè)置源圖像和目標(biāo)圖像上的三組點(diǎn)以計(jì)算仿射變換
//srcTriangle[0] = Point2f(0, 0); //Point2f表示Point類的兩個(gè)數(shù)據(jù)x,y為float類型;vector 表示存放四維int
//srcTriangle[1] = Point2f(static_cast<float>(srcImage.cols - 1), 0);
//srcTriangle[2] = Point2f(0, static_cast<float>(srcImage.rows - 1));
//dstTriangle[0] = Point2f(static_cast<float>(srcImage.cols*0.0), static_cast<float>(srcImage.rows*0.33));
//dstTriangle[1] = Point2f(static_cast<float>(srcImage.cols*0.65), static_cast<float>(srcImage.rows*0.35));
//dstTriangle[2] = Point2f(static_cast<float>(srcImage.cols*0.15), static_cast<float>(srcImage.rows*0.6));
//獲取變換矩陣,指定三個(gè)點(diǎn)
srcTriangle[0] = Point2f(50, 50);
srcTriangle[1] = Point2f(200, 50);
srcTriangle[2] = Point2f(50, 200);
dstTriangle[0] = Point2f(100, 100);
dstTriangle[1] = Point2f(200, 50);
dstTriangle[2] = Point2f(100, 250);
//求仿射變換,得到一個(gè)2x3的矩陣
warpMat = getAffineTransform(srcTriangle, dstTriangle);
//對(duì)源圖像應(yīng)用剛剛的求得的仿射變換
warpAffine(srcImage, dstImage_warp, warpMat, dstImage_warp.size());
//對(duì)圖像進(jìn)行縮放后再旋轉(zhuǎn)
//計(jì)算圖像中點(diǎn)順時(shí)針旋轉(zhuǎn)50°縮放因子為0.6的旋轉(zhuǎn)矩陣
Point center = Point(dstImage_warp.cols / 2, dstImage_warp.rows / 2);
double angle = -30.0;
double scale = 0.8;
//通過(guò)上面的旋轉(zhuǎn)細(xì)節(jié)信息求出旋轉(zhuǎn)矩陣
rotMat = getRotationMatrix2D(center, angle, scale);
//旋轉(zhuǎn)已經(jīng)縮放后的圖像
warpAffine(dstImage_warp, dstImage_warp_rotate, rotMat, dstImage_warp.size());
imshow(WINDOW_NAME1, srcImage);
imshow(WINDOW_NAME2, dstImage_warp);
imshow(WINDOW_NAME3, dstImage_warp_rotate);
waitKey(0);
return 0;
}

到此這篇關(guān)于OpenCV仿射變換的示例代碼的文章就介紹到這了,更多相關(guān)OpenCV 仿射變換內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
python運(yùn)用pygame庫(kù)實(shí)現(xiàn)雙人彈球小游戲
這篇文章主要為大家詳細(xì)介紹了python運(yùn)用pygame庫(kù)實(shí)現(xiàn)雙人彈球小游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-11-11
Anaconda+Pycharm+Pytorch虛擬環(huán)境創(chuàng)建(各種包安裝保姆級(jí)教學(xué))
相信很多時(shí)候大家都會(huì)用到虛擬環(huán)境,他具有可以讓你快速切換不同的python版本,本文主要介紹了Anaconda+Pycharm+Pytorch虛擬環(huán)境創(chuàng)建,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-10-10
詳解利用Pandas求解兩個(gè)DataFrame的差集,交集,并集
這篇文章主要和大家講解一下如何利用Pandas函數(shù)求解兩個(gè)DataFrame的差集、交集、并集,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以了解一下2022-07-07
Python?虛擬環(huán)境的價(jià)值和常用命令詳解
在實(shí)際項(xiàng)目開發(fā)中,我們通常會(huì)根據(jù)自己的需求去下載各種相應(yīng)的框架庫(kù),如Scrapy、Beautiful?Soup等,但是可能每個(gè)項(xiàng)目使用的框架庫(kù)并不一樣,或使用框架的版本不一樣,今天給大家分享下Python?虛擬環(huán)境的價(jià)值和常用命令,感興趣的朋友一起看看吧2022-05-05
Python如何使用隊(duì)列方式實(shí)現(xiàn)多線程爬蟲
這篇文章主要介紹了Python如何使用隊(duì)列方式實(shí)現(xiàn)多線程爬蟲,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-05-05
python程序 創(chuàng)建多線程過(guò)程詳解
這篇文章主要介紹了python程序 創(chuàng)建多線程過(guò)程詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-09-09
Python中map和列表推導(dǎo)效率比較實(shí)例分析
這篇文章主要介紹了Python中map和列表推導(dǎo)效率比較,實(shí)例分析了Python中的map與列表的推導(dǎo)效率,需要的朋友可以參考下2015-06-06
動(dòng)態(tài)創(chuàng)建類實(shí)例代碼
Python中要?jiǎng)?chuàng)建一個(gè)類的實(shí)例,要首先導(dǎo)入該類或者該類所屬的模塊。2009-10-10

