2020年12月31日 星期四

OpenCV findhomography(單應性矩陣)與warpperspective(透視變換)

隨著科技進步與市場競爭,許多公司會試著將機械手臂導入到產線上,同時搭配工業相機做位置辨識,如手眼機器人(eye to hand和eye in hand),其原因就是要配合現在少量多變化的產能需求,達到彈性製造。

為了做到手眼機器人的功能,因有兩個不同座標系(影像座標跟手臂座標),如下圖所示,因無法直接將影像座標給機器手臂使用,故需使用OpenCV findhomography(單應性矩陣),找出兩者之間的關係,再利用warpperspective(透視變換)做座標轉換。



又或物體因離相機遠近不同,雖然明明是一樣的距離,但從影像上看卻不一樣長,如下圖的伯朗大道一樣,近的道路很寬,遠的又小到不行。



而Homography其實就是一個3 x 3矩陣,如下圖所示,其中h_9設為常數1,同時可以發現Homography  矩陣尚有八個未知數,而一對影像與機械座標只能求出其中兩個解,表示在實際校正個過程,至少要有四對非共線影像與機械座標才能求出Homography 矩陣。


下列程式碼主要展示從一張有歪斜的影像中,經由座標轉換之後,擷取到一張沒歪斜影像,如下圖所示,左邊為歪斜影像,右邊則是方正影像,不過校正用的四組座標,我並非用影像處理計算而是簡單人員標記,所以可能看起來沒有到完全很正。


程式碼如下:
#include <opencv2/opencv.hpp>

using namespace cv;
using namespace std;

int main(){

	Mat SrcImg1 = imread("SrcImg.jpg", CV_LOAD_IMAGE_COLOR);
	Mat DstImg = Mat::zeros(Size(3500, 1500), CV_8SC1);

	vector PtData1, PtData2;

	PtData1.push_back(Point2f(513,627));
	PtData1.push_back(Point2f(233, 2000));
	PtData1.push_back(Point2f(3877, 2047));
	PtData1.push_back(Point2f(3855, 835));

	PtData2.push_back(Point2f(0, 0));
	PtData2.push_back(Point2f(0, 1500));
	PtData2.push_back(Point2f(3500, 1500));
	PtData2.push_back(Point2f(3500, 0));

	Mat HomogMat = findHomography(PtData1, PtData2, CV_RANSAC);
	warpPerspective(SrcImg1, DstImg, HomogMat, DstImg.size());
	imwrite("DstImg.bmp", DstImg);
return 0; }

SrcImg1

DstImg







沒有留言:

張貼留言