為了做到手眼機器人的功能,因有兩個不同座標系(影像座標跟手臂座標),如下圖所示,因無法直接將影像座標給機器手臂使用,故需使用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