数字图像处理|基于OpenCV的图像配准之后的透视变换

【数字图像处理|基于OpenCV的图像配准之后的透视变换】??在通过SIFT、SURF或者ORB进行特征点检测,生成了特征点和特征点描述子的vector后,如何进一步的进行对于图像的矫正。这个时候就用到了opencv的另外两个函数findHomography和perspectiveTransform。
??findHomography是用来计算两张图像的单应性矩阵的。opencv的官方文档中有详细的使用说明:
数字图像处理|基于OpenCV的图像配准之后的透视变换
文章图片

??前两个参数分别是通过之前的特征检测找到的特征点,第三个参数为计算单应性矩阵的方法,默认为使用所有的点。第四个参数仅在第三个参数为CV_RANSAC时使用,为最大允许的特征点对间二次投影的误差。
??perspectiveTransform函数为通过单应性矩阵生成校正之后的图像。
数字图像处理|基于OpenCV的图像配准之后的透视变换
文章图片

??前两个参数为原始图像和矫正之后的图像的点的集合。只能为2维或3维的向量。这里的点的集合指的是图像的位置排布,和像素值没有任何关系。第三个参数即为之前求出的单应性矩阵。
??注意:生成的矫正图像为点的集合,即为vector向量,并不是图像,生成的只是原始图像与校正图像的位置对应关系,图像的生成在下面的例子中会说明。
示例:

int main() { Mat img_1 = imread("00068.jpg"); Mat img_2 = imread("00069.jpg"); if (!img_1.data || !img_2.data) { cout << "error reading images " << endl; return -1; }ORB orb; vector keyPoints_1, keyPoints_2; Mat descriptors_1, descriptors_2; orb(img_1, Mat(), keyPoints_1, descriptors_1); orb(img_2, Mat(), keyPoints_2, descriptors_2); BruteForceMatcher matcher; vector matches; matcher.match(descriptors_1, descriptors_2, matches); double max_dist = 0; double min_dist = 100; //-- Quick calculation of max and min distances between keypoints for( int i = 0; i < descriptors_1.rows; i++ ) { double dist = matches[i].distance; if( dist < min_dist ) min_dist = dist; if( dist > max_dist ) max_dist = dist; } printf("-- Max dist : %f \n", max_dist ); printf("-- Min dist : %f \n", min_dist ); //-- Draw only "good" matches (i.e. whose distance is less than 0.6*max_dist ) //-- PS.- radiusMatch can also be used here. std::vector< DMatch > good_matches; vector leftPoint,rightPoint; for( int i = 0; i < descriptors_1.rows; i++ ) { if( matches[i].distance < 0.6*max_dist ) { good_matches.push_back( matches[i]); leftPoint.push_back(keyPoints_1[matches[i].queryIdx].pt); //保存左图像的关键点 rightPoint.push_back(keyPoints_2[matches[i].trainIdx].pt); //保存右图像的关键点 } }Mat Homography = findHomography(leftPoint,rightPoint,CV_RANSAC,3); //生成单应性矩阵 cout< CorrectImg; //根据单应性矩阵校正之后的点 vector ponits; //保存图像的所有的点 for(int i=0; i(i); for(int j=0; j= img_1.cols || y >= img_1.rows) { count++; continue; } uchar* t = img_trans.ptr(y); t[x*3]= p[j*3]; t[x*3+1]= p[j*3+1]; t[x*3+2]= p[j*3+2]; count++; } }imshow("CorrectImg",img_trans); waitKey(); return 0; }

    推荐阅读