OpenCV透視變換應(yīng)用之書本視圖矯正+廣告屏幕切換
一、透視變換的實(shí)際應(yīng)用場(chǎng)景
我們?cè)诔鲩T坐車時(shí),經(jīng)常會(huì)看到司機(jī)會(huì)使用一種行車輔助工具,這其中就使用到了透視變換的相關(guān)操作,協(xié)助司機(jī)安全行車。
可以看出,自身小車周圍路況的正常顯示,便利了司機(jī)的行車操作
像這種透視變換的實(shí)際生活應(yīng)用,其實(shí)還有許多,接下來(lái),我們就來(lái)學(xué)習(xí)一下OpenCV的透視變換
二、案例了解透視變換--書本視圖矯正
原圖:
目標(biāo):需要使用透視變換 將書桌上的課本 正視視角查看
結(jié)果展示:
書本視圖矯正完整代碼如下:【這里是鼠標(biāo)點(diǎn)擊從左上角開始順時(shí)針選取4個(gè)點(diǎn)透視變換】
#include <iostream> #include <opencv2/opencv.hpp> #include<vector> using namespace cv; using namespace std; //鼠標(biāo)操作 自己準(zhǔn)備結(jié)構(gòu)體 struct imagedata { Mat img;//目標(biāo)圖像 用于點(diǎn)擊 確定坐標(biāo) vector<Point2f> points;//存放原圖的坐標(biāo) 通過(guò)鼠標(biāo)的點(diǎn)擊進(jìn)行存放 }; //鼠標(biāo)操作的回調(diào)函數(shù):用于選擇四個(gè)角的點(diǎn)(使用方法:從左上角開始順時(shí)針選擇四個(gè)點(diǎn),選完之后回車操作) void mouseHundle(int event,int x,int y,int flag,void *arg) { //強(qiáng)制轉(zhuǎn)換 struct imagedata * d = (struct imagedata*)arg; //如果按下的是鼠標(biāo)左鍵 if(event==EVENT_LBUTTONDOWN) { //用圓形來(lái)標(biāo)記下鼠標(biāo)按下左鍵標(biāo)記的位置 circle(d->img,Point(x,y),3,Scalar(255,0,0),3,CV_AA);//在圖上標(biāo)記,圓心為點(diǎn)擊的位置 imshow("image",d->img);//原窗口上進(jìn)行顯示標(biāo)記點(diǎn) //透視變換 需要使用四個(gè)點(diǎn)的坐標(biāo) if(d->points.size()<4) { d->points.push_back(Point2f(x,y));//把點(diǎn)擊下來(lái)的坐標(biāo)進(jìn)行存儲(chǔ) } } } void example_1() { Mat image=imread("D:/00000000000003jieduanshipincailliao/book2.jpg"); Mat result=Mat::zeros(400,500,CV_8UC1);//最終結(jié)果顯示 單通道 //準(zhǔn)備坐標(biāo):存放四個(gè)轉(zhuǎn)換以后的坐標(biāo) vector<Point2f>obj; //坐標(biāo)一定要相反 鏡像坐標(biāo) obj.push_back(Point2f(0,0)); obj.push_back(Point2f(500,0)); obj.push_back(Point2f(500,400)); obj.push_back(Point2f(0,400)); imshow("image",image); struct imagedata data; data.img=image; //鼠標(biāo)操作 鼠標(biāo)處理的回調(diào)函數(shù) setMouseCallback("image",mouseHundle,&data); //按任意鍵關(guān)閉當(dāng)前顯示的窗口,顯示下一個(gè)窗口 waitKey(0); //利用RANSAC算法 計(jì)算得到轉(zhuǎn)換映射矩陣3*3 Mat res=findHomography(data.points,obj,CV_RANSAC); //查看轉(zhuǎn)換矩陣 //imshow("res",res); //原圖轉(zhuǎn)換出來(lái)結(jié)果圖 warpPerspective(image,result,res,result.size()); //查看轉(zhuǎn)換結(jié)果圖 透視變換 imshow("result",result); waitKey(0); } int main(int argc, char *argv[]) { example_1(); return 0; }
以上是使用鼠標(biāo)點(diǎn)擊確定坐標(biāo),當(dāng)然,我們也可以在代碼中寫上選定的坐標(biāo)進(jìn)行透視變換的相關(guān)操作。 依然選取左上角開始順時(shí)針坐標(biāo)選取,這里以左上角為例,其他三個(gè)點(diǎn)可以類比左上角坐標(biāo)選擇來(lái)確定下坐標(biāo)選取
可以看到左上角坐標(biāo) x=282,y=43
自己定下透視變換使用到的四個(gè)坐標(biāo) 直接回車 即可查看透視變換結(jié)果
//鼠標(biāo)操作 鼠標(biāo)處理的回調(diào)函數(shù) //setMouseCallback("image",mouseHundle,&data); //不使用鼠標(biāo)點(diǎn)擊,自己定下透視變換的四個(gè)坐標(biāo) vector<Point2f>src; src.push_back(Point2f(283,134)); src.push_back(Point2f(745,234)); src.push_back(Point2f(578,463)); src.push_back(Point2f(61,299)); //按任意鍵關(guān)閉當(dāng)前顯示的窗口,顯示下一個(gè)窗口 waitKey(0); //利用RANSAC算法 計(jì)算得到轉(zhuǎn)換映射矩陣3*3 Mat res=findHomography(src,obj,CV_RANSAC); //查看轉(zhuǎn)換矩陣 //imshow("res",res);
程序運(yùn)行 直接回車操作 查看
三、案例了解透視變換--廣告屏幕切換
背景圖片:
想要切換的廣告圖片:
目標(biāo):選擇廣告屏幕 切換 廣告屏幕內(nèi)容
結(jié)果:廣告屏上面的 內(nèi)容推薦 成功切換成自己想要切換的廣告圖片
實(shí)現(xiàn)方法:處理后兩張圖片的疊加,就是先將想要更換的廣告屏填充黑色背景圖,再將自己想要的廣告圖片 兩張圖片疊加就能達(dá)到切換廣告屏幕的效果
廣告屏幕切換完整代碼如下:
#include <iostream> #include <opencv2/opencv.hpp> using namespace cv; using namespace std; struct imagedata { Mat img;//目標(biāo)圖像 vector <Point2f> points;//3D點(diǎn) }; //鼠標(biāo)操作函數(shù):用于選擇四個(gè)角的點(diǎn)(使用方法有順序的,從左上角順時(shí)針選擇,選完之后回車) void mouseHundle(int event,int x,int y,int flag,void *ptr) { struct imagedata * d=(struct imagedata*)ptr; if(event==EVENT_LBUTTONDOWN) { //確定按下的是鼠標(biāo)左鍵 //用圓形標(biāo)記一下鼠標(biāo)按下左鍵標(biāo)記的位置 circle(d->img,Point(x,y),3,Scalar(255,0,0),3,CV_AA);//在圖上標(biāo)記,圓心為點(diǎn)擊的位置 imshow("dst",d->img);//在dst背景圖中顯示鼠標(biāo)選取的圖片 if(d->points.size()<4)//只存下來(lái),最先點(diǎn)的前四個(gè)點(diǎn) { d->points.push_back(Point2f(x,y));//把鼠標(biāo)操作點(diǎn)擊的點(diǎn)存起來(lái) } } } void example_2() { Mat image1=imread("D:/00000000000003jieduanshipincailliao/0802.jpg");//想要切換的廣告內(nèi)容 Mat image2=imread("D:/00000000000003jieduanshipincailliao/city.jpg");//紐約時(shí)代廣場(chǎng)圖片背景 Mat dst=image2.clone();//背景圖片 克隆 //存放原圖坐標(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)); //紐約時(shí)代廣場(chǎng)圖背景圖顯示 imshow("dst",dst); struct imagedata data; data.img =dst; //鼠標(biāo)操作 鼠標(biāo)處理的回調(diào)函數(shù) setMouseCallback("dst",mouseHundle,&data); //按任意鍵關(guān)閉當(dāng)前顯示的窗口,顯示下一個(gè)窗口 waitKey(0); //計(jì)算得到轉(zhuǎn)換映射矩陣 3*3 原圖坐標(biāo)轉(zhuǎn)換為鼠標(biāo)選擇 Mat res = findHomography(obj,data.points,CV_RANSAC); //imshow("res",res); //透視變換 warpPerspective(image1,dst,res,dst.size()); //僅有的卻換后的廣告圖圖片 //imshow("image1",dst); Point pts[4]; for(int i=0;i<4;i++) { pts[i]=data.points[i]; } //鼠標(biāo)點(diǎn)選的四個(gè)坐標(biāo)的區(qū)域填充成黑色 fillConvexPoly(image2,pts,4,Scalar(0),CV_AA); //imshow("image2",image2); //將僅有的卻換后的廣告圖圖片 和 鼠標(biāo)點(diǎn)選的四個(gè)坐標(biāo)的區(qū)域填充成黑色的背景圖圖片 疊加 image2+=dst; //顯示出最后廣告換屏結(jié)果圖片 imshow("final",image2); waitKey(0); } int main(int argc, char *argv[]) { example_2(); return 0; }
到此這篇關(guān)于OpenCV透視變換應(yīng)用之書本視圖矯正+廣告屏幕切換的文章就介紹到這了,更多相關(guān)OpenCV透視變換應(yīng)用內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- OpenCV通過(guò)透視變換實(shí)現(xiàn)矯正圖像詳解
- Java OpenCV圖像處理之仿射變換,透視變換,旋轉(zhuǎn)詳解
- Python?OpenCV超詳細(xì)講解透視變換的實(shí)現(xiàn)
- OpenCV實(shí)現(xiàn)透視變換矯正
- Python?Opencv基于透視變換的圖像矯正
- 詳解如何在pyqt中通過(guò)OpenCV實(shí)現(xiàn)對(duì)窗口的透視變換
- opencv3/C++ 平面對(duì)象識(shí)別&透視變換方式
- OpenCV圖像幾何變換之透視變換
- Opencv透視變換綜合實(shí)例詳解
- OpenCV實(shí)現(xiàn)透視變換的示例代碼
相關(guān)文章
C++簡(jiǎn)明圖解分析靜態(tài)成員與單例設(shè)計(jì)模式
與靜態(tài)數(shù)據(jù)成員不同,靜態(tài)成員函數(shù)的作用不是為了對(duì)象之間的溝通,而是為了能處理靜態(tài)數(shù)據(jù)成員,靜態(tài)成員函數(shù)沒(méi)有this指針。既然它沒(méi)有指向某一對(duì)象,也就無(wú)法對(duì)一個(gè)對(duì)象中的非靜態(tài)成員進(jìn)行默認(rèn)訪問(wèn)2022-06-06C語(yǔ)言數(shù)據(jù)結(jié)構(gòu)中堆排序的分析總結(jié)
堆是計(jì)算機(jī)科學(xué)中一類特殊的數(shù)據(jù)結(jié)構(gòu)的統(tǒng)稱,通常是一個(gè)可以被看做一棵完全二叉樹的數(shù)組對(duì)象。而堆排序是利用堆這種數(shù)據(jù)結(jié)構(gòu)所設(shè)計(jì)的一種排序算法。本文將通過(guò)圖片詳細(xì)介紹堆排序,需要的可以參考一下2022-04-04C++中形參和實(shí)參的區(qū)別及說(shuō)明
這篇文章主要介紹了C++中形參和實(shí)參的區(qū)別及說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-02-02一篇文章帶你用C語(yǔ)言玩轉(zhuǎn)結(jié)構(gòu)體
本文主要介紹C語(yǔ)言 結(jié)構(gòu)體的知識(shí),學(xué)習(xí)C語(yǔ)言肯定需要學(xué)習(xí)結(jié)構(gòu)體,這里詳細(xì)說(shuō)明了結(jié)構(gòu)體并附示例代碼,供大家參考學(xué)習(xí),有需要的小伙伴可以參考下2021-09-09C++ 字符串string和整數(shù)int的互相轉(zhuǎn)化操作
這篇文章主要介紹了C++ 字符串string和整數(shù)int的互相轉(zhuǎn)化操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-12-12