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

歡迎訪(fǎng)問(wèn) 生活随笔!

生活随笔

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

编程问答

使用opencv对图像进行透视变换

發(fā)布時(shí)間:2024/1/1 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 使用opencv对图像进行透视变换 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

一.什么是透視變換

透視變換就是透視變換(Perspective Transformation)是指利用透視中心、像點(diǎn)、目標(biāo)點(diǎn)三點(diǎn)共線(xiàn)的條件,按透視旋轉(zhuǎn)定律使承影面(透視面)繞跡線(xiàn)(透視軸)旋轉(zhuǎn)某一角度,破壞原有的投影光線(xiàn)束,仍能保持承影面上投影幾何圖形不變的變換。簡(jiǎn)單的來(lái)說(shuō)就是把一張斜著看的二維圖形變?yōu)楦╊亩S圖像,透視變換再計(jì)算機(jī)視覺(jué)中相當(dāng)常用,因?yàn)橛?jì)算機(jī)采集的圖形并非規(guī)整的圖像,比如再使用自動(dòng)倒車(chē),賽道識(shí)別等方面都需要使用透視變換來(lái)改變計(jì)算機(jī)所采集的的信息,比如:

二.代碼演示:?

目標(biāo)是把這張圖片:

變?yōu)?#xff1a;

?

?首先是打開(kāi)圖片

frame = imread("test3.jpg", 1); frame1 = frame.clone();

這里先定義兩張一樣的圖片,一張用于用戶(hù)輸入,一張用于數(shù)據(jù)處理

然后調(diào)整一下圖片的大小,這里我測(cè)試了一下,把圖片都變成正方形可以使變換的更加準(zhǔn)確

Size a = frame.size(); resize(frame, frame, Size(max(a.height,a.width), max(a.height ,a.width))); resize(frame1, frame1, Size(max(a.height, a.width), max(a.height, a.width)));

然后使確定矩形的四個(gè)點(diǎn),這里我們讓用戶(hù)自己再圖片上進(jìn)行點(diǎn)擊,我們可以使用openCV自帶的函數(shù)setmousecallback,用法如下:

這里共有三個(gè)參數(shù):

第一個(gè):窗口名稱(chēng)

第二個(gè):鼠標(biāo)的響應(yīng)函數(shù)和回調(diào)函數(shù)

第三個(gè):回調(diào)函數(shù)的參數(shù)

我們?cè)诘诙€(gè)參數(shù)中寫(xiě)一個(gè)返回值void的函數(shù)On_mouse,其中識(shí)別鼠標(biāo)按下的回調(diào)的參數(shù)是:EVENT_LBUTTONDOWN

setMouseCallback("test", On_mouse, 0);

然后我們期望用戶(hù)點(diǎn)擊后在用戶(hù)點(diǎn)擊的地方顯示一個(gè)點(diǎn),我們可以使用circle函數(shù),所以O(shè)n_mouse函數(shù)如下:

int num_point = 0, out_size = 0; void On_mouse(int event, int x, int y, int flags, void*) {if (event == EVENT_LBUTTONDOWN) {in_point[num_point] = Point(x, y);cout << x << ' ' << y << endl;circle(frame1, in_point[num_point], 6, Scalar(0, 255, 0), -1);imshow("test", frame1);num_point++;} }

然后我們把輸入的四個(gè)點(diǎn)的坐標(biāo)存在in_point這個(gè)數(shù)組里

最后我們使用getPerspectiveTransform和warpPerspective函數(shù)進(jìn)行透視變換:

temp = getPerspectiveTransform(in_point, out_point); warpPerspective(frame, result, temp, frame.size());

這里注意我們輸入點(diǎn)的順序是:左上,右上,左下,右下。

完整代碼:

#include<opencv2/opencv.hpp> #include<iostream> using namespace std; using namespace cv; Mat frame,frame1; Point2f in_point[4]; Point2f out_point[4]; int num_point = 0, out_size = 0; void On_mouse(int event, int x, int y, int flags, void*) {if (event == EVENT_LBUTTONDOWN) {in_point[num_point] = Point(x, y);cout << x << ' ' << y << endl;circle(frame1, in_point[num_point], 6, Scalar(0, 255, 0), -1);imshow("test", frame1);num_point++;} } int main(){cout << "請(qǐng)依次點(diǎn)擊需要變換的四邊形的左上角,右上角,左下角,右下角" << endl;cout << "點(diǎn)選取好后單擊Enter" << endl;frame = imread("test3.jpg", 1); //test3.jpg是我自己在這個(gè)目錄下的文件,也可以替換為圖片的絕對(duì)路徑,但是要注意使用雙斜杠frame1 = frame.clone();Size a = frame.size();resize(frame, frame, Size(max(a.height,a.width), max(a.height ,a.width)));resize(frame1, frame1, Size(max(a.height, a.width), max(a.height, a.width)));imshow("test", frame);setMouseCallback("test", On_mouse, 0);while (1) {if (waitKey(10) == 13) {out_size = std::max(in_point[1].x - in_point[0].x, in_point[3].x - in_point[2].x);out_point[0] = Point2f(0.0, 0.0);out_point[1] = Point2f(out_size * 1.0, 0.0);out_point[2] = Point2f(0.0, out_size * 1.0);out_point[3] = Point2f(out_size * 1.0, out_size * 1.0);Mat temp, result;temp = getPerspectiveTransform(in_point, out_point);warpPerspective(frame, result, temp, frame.size());imshow("result", result);cout << "轉(zhuǎn)換完成" << endl;waitKey(0);} }return 0; }

?


?

?

?

總結(jié)

以上是生活随笔為你收集整理的使用opencv对图像进行透视变换的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

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