使用opencv对图像进行透视变换
一.什么是透視變換
透視變換就是透視變換(Perspective Transformation)是指利用透視中心、像點、目標點三點共線的條件,按透視旋轉定律使承影面(透視面)繞跡線(透視軸)旋轉某一角度,破壞原有的投影光線束,仍能保持承影面上投影幾何圖形不變的變換。簡單的來說就是把一張斜著看的二維圖形變為俯瞰的二維圖像,透視變換再計算機視覺中相當常用,因為計算機采集的圖形并非規整的圖像,比如再使用自動倒車,賽道識別等方面都需要使用透視變換來改變計算機所采集的的信息,比如:
二.代碼演示:?
目標是把這張圖片:
變為:
?
?首先是打開圖片
frame = imread("test3.jpg", 1); 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)));然后使確定矩形的四個點,這里我們讓用戶自己再圖片上進行點擊,我們可以使用openCV自帶的函數setmousecallback,用法如下:
這里共有三個參數:
第一個:窗口名稱
第二個:鼠標的響應函數和回調函數
第三個:回調函數的參數
我們在第二個參數中寫一個返回值void的函數On_mouse,其中識別鼠標按下的回調的參數是:EVENT_LBUTTONDOWN
setMouseCallback("test", On_mouse, 0);然后我們期望用戶點擊后在用戶點擊的地方顯示一個點,我們可以使用circle函數,所以On_mouse函數如下:
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++;} }然后我們把輸入的四個點的坐標存在in_point這個數組里
最后我們使用getPerspectiveTransform和warpPerspective函數進行透視變換:
temp = getPerspectiveTransform(in_point, out_point); warpPerspective(frame, result, temp, frame.size());這里注意我們輸入點的順序是:左上,右上,左下,右下。
完整代碼:
#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 << "請依次點擊需要變換的四邊形的左上角,右上角,左下角,右下角" << endl;cout << "點選取好后單擊Enter" << endl;frame = imread("test3.jpg", 1); //test3.jpg是我自己在這個目錄下的文件,也可以替換為圖片的絕對路徑,但是要注意使用雙斜杠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 << "轉換完成" << endl;waitKey(0);} }return 0; }?
?
?
?
總結
以上是生活随笔為你收集整理的使用opencv对图像进行透视变换的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: html中marquee标签添加2条,H
- 下一篇: CISAW信息安全保障人员