日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

【OpenCV】透视变换应用——实现鸟瞰图与贴图

發(fā)布時(shí)間:2024/1/1 编程问答 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【OpenCV】透视变换应用——实现鸟瞰图与贴图 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

透視變換是3D轉(zhuǎn)換,透視變換的本質(zhì)是將圖像投影到一個(gè)新的視平面;

據(jù)此,我們可以使用透視變化來實(shí)現(xiàn)鳥瞰圖和圖形貼圖的效果;

一、鳥瞰圖

實(shí)現(xiàn)前:

?實(shí)現(xiàn)效果:

?

1.準(zhǔn)備一個(gè)空的mat對(duì)象 用于保存轉(zhuǎn)換后的圖

Mat image=imread("road.jpg");imshow("image",image);Mat result=Mat::zeros(500,600,CV_8UC1);//存儲(chǔ)轉(zhuǎn)換后的圖像坐標(biāo) 按順時(shí)針 左上、右上、右下、左下(可自己定順序)vector<Point2f> obj;obj.push_back(Point2f(0,0));obj.push_back(Point2f(600,0));obj.push_back(Point2f(600,500));obj.push_back(Point2f(0,500));

2.在原圖窗口里做鼠標(biāo)操作,通過setMouseCallback鼠標(biāo)回調(diào)函數(shù),獲取原圖四個(gè)坐標(biāo)

在原圖中點(diǎn)擊四個(gè)點(diǎn)獲取四個(gè)坐標(biāo),順序與上述1中設(shè)置的坐標(biāo)對(duì)應(yīng),如果1中是順時(shí)針,按選擇坐標(biāo)時(shí)也應(yīng)該按順時(shí)針操作,并且按照左上、右上、右下、左下順序;

//2.在原圖窗口里做鼠標(biāo)操作,通過鼠標(biāo)回調(diào)函數(shù),獲取原圖四個(gè)坐標(biāo)struct imagedata data;data.img=image;//將原圖傳入setMouseCallback("image",mouseHundle,&data);//鼠標(biāo)回調(diào)函數(shù)waitKey(0);//鍵盤輸入 向下執(zhí)行//點(diǎn)擊按鍵之后結(jié)束鼠標(biāo)操作,得到原圖四個(gè)坐標(biāo)和轉(zhuǎn)換后的坐標(biāo) //用到的結(jié)構(gòu)體和鼠標(biāo)處理函數(shù) struct imagedata {Mat img;vector<Point2f>points;//該points是test1原圖需要做轉(zhuǎn)換的坐標(biāo)//在test2中是原圖轉(zhuǎn)換后的坐標(biāo) };void mouseHundle(int event,int x,int y,int flag,void *arg) {struct imagedata* ind=(struct imagedata *)arg;if(event==EVENT_LBUTTONDOWN)//鼠標(biāo)左鍵按下{//畫圓circle(ind->img,Point(x,y),3,Scalar(0,0,255),3,CV_AA);imshow("image",ind->img);//test1鳥瞰圖顯示原圖帶圓點(diǎn)//imshow("dst",ind->img);//test2貼圖顯示city圖帶圓點(diǎn)if(ind->points.size()<4){ind->points.push_back(Point2f(x,y));//轉(zhuǎn)換的坐標(biāo)只需要收集四個(gè)}} }

3.開始計(jì)算坐標(biāo)映射矩陣

Mat res=findHomography(data.points,obj,CV_RANSAC);

4.進(jìn)行透視轉(zhuǎn)換

將原圖轉(zhuǎn)變?yōu)樾Ч麍D進(jìn)行顯示

warpPerspective(image,result,res,result.size()); imshow("result",result); waitKey(0);

二、貼圖

city圖實(shí)現(xiàn)前:?

?貼圖實(shí)現(xiàn)后:

左邊大屏幕更改

?貼圖與鳥瞰圖有些不同,鳥瞰圖是將一張?jiān)瓐D,通過選擇四個(gè)點(diǎn)轉(zhuǎn)換成鳥瞰圖;

轉(zhuǎn)換后的坐標(biāo)固定的,轉(zhuǎn)換前的4個(gè)坐標(biāo)由鼠標(biāo)選擇;

而貼圖的話,是將原圖通過選擇的點(diǎn)進(jìn)行轉(zhuǎn)換,再貼到city圖中;

轉(zhuǎn)換前的坐標(biāo)固定的,就是普通的圖片,轉(zhuǎn)換后的坐標(biāo)由鼠標(biāo)選擇;

1.準(zhǔn)備原圖要貼上去的圖,即1.jpg

Mat image1=imread("1.jpg");//原圖Mat image2=imread("city.jpg");//city圖Mat dst=image2.clone();//克隆一份城市圖//1.準(zhǔn)備原圖要貼上去的圖,即1.jpg//Mat result=Mat::zeros(image1.rows,image1.cols,CV_8UC1);//存儲(chǔ)轉(zhuǎn)換前的圖像坐標(biāo)vector<Point2f> obj;obj.push_back(Point2f(0,0));obj.push_back(Point2f(image1.cols,0));obj.push_back(Point2f(image1.cols,image1.rows));obj.push_back(Point2f(0,image1.rows));imshow("dst",image2);

2.在city窗口里做鼠標(biāo)操作,通過鼠標(biāo)回調(diào)函數(shù),獲取轉(zhuǎn)換后的四個(gè)坐標(biāo)

struct imagedata data;data.img=dst;//將city圖傳入setMouseCallback("dst",mouseHundle,&data);//鼠標(biāo)回調(diào)函數(shù)waitKey(0);

?3.開始計(jì)算坐標(biāo)映射矩陣

//點(diǎn)擊按鍵之后結(jié)束鼠標(biāo)操作,得到原圖四個(gè)坐標(biāo)和轉(zhuǎn)換后的坐標(biāo)Mat res=findHomography(obj,data.points,CV_RANSAC);

?4.透視轉(zhuǎn)換

warpPerspective(image1,dst,res,dst.size());imshow("image1",dst);

?做到這一步,將原圖變成這樣子

?

5.?獲取四個(gè)坐標(biāo),將city圖中選擇的位置填充成黑色,防止兩個(gè)圖片顏色沖突

最后通過image2+=dst把圖片貼到city圖上,這樣就完成了

Point pts[4];for(int i=0;i<4;i++){pts[i]=data.points[i];}//在city圖中選擇的位置填充成黑色,防止兩圖顏色沖突fillConvexPoly(image2,pts,4,Scalar(0),CV_AA);image2+=dst;//把圖片貼到city圖上imshow("final",image2);waitKey(0);

?完整源碼

#include <iostream> #include <opencv2/opencv.hpp> using namespace std; using namespace cv;struct imagedata {Mat img;vector<Point2f>points;//該points是test1原圖需要做轉(zhuǎn)換的坐標(biāo)//在test2中是原圖轉(zhuǎn)換后的坐標(biāo) };void mouseHundle(int event,int x,int y,int flag,void *arg) {struct imagedata* ind=(struct imagedata *)arg;if(event==EVENT_LBUTTONDOWN)//鼠標(biāo)左鍵按下{//畫圓circle(ind->img,Point(x,y),3,Scalar(0,0,255),3,CV_AA);//imshow("image",ind->img);//test1顯示原圖帶圓點(diǎn)imshow("dst",ind->img);//test2顯示city圖帶圓點(diǎn)if(ind->points.size()<4){ind->points.push_back(Point2f(x,y));//轉(zhuǎn)換的坐標(biāo)只需要收集四個(gè)}} }void test1() {Mat image=imread("road.jpg");imshow("image",image);//1.準(zhǔn)備空的mat對(duì)象 用于保存轉(zhuǎn)換后的圖Mat result=Mat::zeros(500,600,CV_8UC1);//存儲(chǔ)轉(zhuǎn)換后的圖像坐標(biāo) 按順時(shí)針 左上、右上、右下、做下(可自己定順序)vector<Point2f> obj;obj.push_back(Point2f(0,0));obj.push_back(Point2f(600,0));obj.push_back(Point2f(600,500));obj.push_back(Point2f(0,500));//2.在原圖窗口里做鼠標(biāo)操作,通過鼠標(biāo)回調(diào)函數(shù),獲取原圖四個(gè)坐標(biāo)struct imagedata data;data.img=image;//將原圖傳入setMouseCallback("image",mouseHundle,&data);//鼠標(biāo)回調(diào)函數(shù)waitKey(0);//點(diǎn)擊按鍵之后結(jié)束鼠標(biāo)操作,得到原圖四個(gè)坐標(biāo)和轉(zhuǎn)換后的坐標(biāo)//3.開始計(jì)算坐標(biāo)映射矩陣Mat res=findHomography(data.points,obj,CV_RANSAC);//4.透視轉(zhuǎn)換warpPerspective(image,result,res,result.size());imshow("result",result);waitKey(0); } void test2() {Mat image1=imread("1.jpg");Mat image2=imread("city.jpg");Mat dst=image2.clone();//克隆一份城市圖//1.準(zhǔn)備原圖要貼上去的圖,即1.jpg//Mat result=Mat::zeros(image1.rows,image1.cols,CV_8UC1);//存儲(chǔ)轉(zhuǎn)換前的圖像坐標(biāo)vector<Point2f> obj;obj.push_back(Point2f(0,0));obj.push_back(Point2f(image1.cols,0));obj.push_back(Point2f(image1.cols,image1.rows));obj.push_back(Point2f(0,image1.rows));imshow("dst",image2);//2.在city窗口里做鼠標(biāo)操作,通過鼠標(biāo)回調(diào)函數(shù),獲取需要四個(gè)坐標(biāo)struct imagedata data;data.img=dst;//將city圖傳入setMouseCallback("dst",mouseHundle,&data);//鼠標(biāo)回調(diào)函數(shù)waitKey(0);//點(diǎn)擊按鍵之后結(jié)束鼠標(biāo)操作,得到原圖四個(gè)坐標(biāo)和轉(zhuǎn)換后的坐標(biāo)//3.開始計(jì)算坐標(biāo)映射矩陣Mat res=findHomography(obj,data.points,CV_RANSAC);//4.透視轉(zhuǎn)換warpPerspective(image1,dst,res,dst.size());imshow("image1",dst);Point pts[4];for(int i=0;i<4;i++){pts[i]=data.points[i];}//在city圖中選擇的位置填充成黑色,防止兩圖顏色沖突fillConvexPoly(image2,pts,4,Scalar(0),CV_AA);image2+=dst;//把圖片貼到city圖上imshow("final",image2);waitKey(0); }int main() {//test1();test2();return 0; }

感謝觀看!!!!

以上就是全部內(nèi)容,如果對(duì)您有幫助,歡迎點(diǎn)贊評(píng)論,或者發(fā)現(xiàn)有哪里寫錯(cuò)的,歡迎指正!

?

總結(jié)

以上是生活随笔為你收集整理的【OpenCV】透视变换应用——实现鸟瞰图与贴图的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。