use warpAffine of OpenCV to do image registration
我正在尝试使用 ORB 功能进行图像配准。
我在使用 warpAffine 时遇到了问题。编译器告诉无法将参数 \\'1\\' 从 cv::Mat * 转换为 cv::InputArray。
这是我的代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 | #pragma once // Standard C++ I/O library. #include <iostream> #include <string> #include <iomanip> #include <vector> // OpenCV library. #include <cv.h> #include <highgui.h> // OpenCV feature library. #include <opencv2/opencv.hpp> #include <opencv2/features2d/features2d.hpp> #include <nonfree/features2d.hpp> // main(). int main(int argv, char ** argc) { cv::Mat im_ref, im_cmp; std::string str_ref, str_cmp; // Read reference image. //std::cout<<"Input reference image filename:"; //std::cin>>str_ref; std::cout<<"-> Reading images."<<std::endl; str_ref ="F:\\\\CPPs\\\\ImageRegistration\\\\OpenCVTest\\\\206.png"; im_ref = cv::imread(str_ref); cv::imshow("Reference image", im_ref); // Read testing image. //std::cout<<"Input testing image filename:"; //std::cin>>str_cmp; str_cmp ="F:\\\\CPPs\\\\ImageRegistration\\\\OpenCVTest\\\\227.png"; im_cmp = cv::imread(str_cmp); cv::imshow("Testing image", im_cmp); std::cout<<"Press any key to continue."<<std::endl; cvWaitKey(0); // Feature detection. std::cout<<"-> Feature detection."<<std::endl; std::vector <cv::KeyPoint> key_ref, key_cmp; // Vectors for features extracted from reference and testing images. cv::Mat des_ref, des_cmp; // Descriptors for features of 2 images. cv::ORB orb1; // An ORB object. orb1(im_ref, cv::Mat(), key_ref, des_ref); // Feature extraction. orb1(im_cmp, cv::Mat(), key_cmp, des_cmp); // Show keypoints. std::cout<<"-> Show keypoints."<<std::endl; cv::Mat drawkey_ref, drawkey_cmp; // Output image for keypoint drawing. cv::drawKeypoints(im_ref, key_ref, drawkey_ref); // Generate image for keypoint drawing. cv::imshow("Keypoints of reference", drawkey_ref); cv::drawKeypoints(im_cmp, key_cmp, drawkey_cmp); cv::imshow("Keypoints of test", drawkey_cmp); cvWaitKey(0); // Matching. std::cout<<"-> Matching."<<std::endl; cv::FlannBasedMatcher matcher1(new cv::flann::LshIndexParams(20,10,2)); std::vector<cv::DMatch> matches1; matcher1.match(des_ref, des_cmp, matches1); // Match two sets of features. double max_dist = 0; double min_dist = 100; // Find out the minimum and maximum of all distance. for( int i = 0; i < des_ref.rows; i++ ) { double dist = matches1[i].distance; if( dist < min_dist ) min_dist = dist; if( dist > max_dist ) max_dist = dist; } cvWaitKey(0); // Eliminate relatively bad points. std::cout<<"-> Bad points elimination"<<std::endl; std::vector<cv::KeyPoint> kgood_ref, kgood_cmp; std::vector<cv::DMatch> goodMatch; for (int i=0; i<matches1.size(); i++) { if(matches1[i].distance < 2*min_dist) // Keep points that are less than 2 times of the minimum distance. { goodMatch.push_back(matches1[i]); kgood_ref.push_back(key_ref[i]); kgood_cmp.push_back(key_cmp[i]); } // end if } // end for cvWaitKey(0); // Calculate affine transform matrix. std::cout<<"-> Calculating affine transformation."<<std::endl; std::vector<cv::Point2f> frm1_feature, frm2_feature; const int p_size = goodMatch.size(); // * tmpP = new tmpPoint[p_size]; cv::Point2f tmpP; for(int i=0; i<goodMatch.size(); i++) { tmpP.x = kgood_ref[i].pt.x; tmpP.y = kgood_ref[i].pt.y; frm1_feature.push_back(tmpP); tmpP.x = kgood_cmp[i].pt.x; tmpP.y = kgood_cmp[i].pt.y; frm2_feature.push_back(tmpP); } cv::Mat affine_mat = cv::estimateRigidTransform(frm1_feature, frm2_feature, true); cv::Mat im_transformed; // Output results. cv::warpAffine(&im_cmp, &im_transformed, affine_mat, CV_INTER_LINEAR|CV_WARP_FILL_OUTLIERS); // error comes from here. cv::imshow("Transformed image", im_transformed); cvWaitKey(0); return 0; } |
在使用 Evgeniy 给出的答案之前,我已经得到了结果。
我使用的变换是
1 | //cv::warpAffine( im_cmp, im_transformed, affine_mat, cv::Size(im_cmp.cols, im_cmp.rows) ); |
转换后的结果很奇怪
我想要做的是最终得到一个参考图像和这个转换图像的合并图像。这实际上是我的第一步。这是使用warpAffine()的转换参数的问题吗?
最后,我想在这里得到一个类似示例的结果(在不同位置拍摄的两张图像,它们最终对齐)
您正在给出一个指针,但 wrapAffine 接受对 cv::Mat 的引用。
您可以像这样更改代码:
1 | cv::warpAffine(im_cmp, im_transformed, affine_mat, cv::Size(), CV_INTER_LINEAR|CV_WARP_FILL_OUTLIERS); |
只需删除 '