【发布时间】:2017-07-11 09:31:42
【问题描述】:
我正在尝试在 opencv c++ 中拼接两个重叠的图像。我使用 ORB 进行特征匹配,并计算了两个图像之间的 Homography。现在使用这个 Homography 矩阵我想进一步添加两个图像。但我不知道如何更进一步。谁能告诉我接下来的步骤。 到目前为止我写的代码是:
detector->detect(img1, kp1,descriptors_img1);
detector->detect(img2, kp2,descriptors_img2);
Ptr<DescriptorExtractor> extractor = ORB::create();
extractor->compute(img1, kp1, descriptors_img1 );
extractor->compute(img2, kp2, descriptors_img2 );
if ( descriptors_img1.empty() )
cvError(0,"MatchFinder","1st descriptor empty",__FILE__,__LINE__);
if ( descriptors_img2.empty() )
cvError(0,"MatchFinder","2nd descriptor empty",__FILE__,__LINE__);
descriptors_img1.convertTo(descriptors_img1, CV_32F);
descriptors_img2.convertTo(descriptors_img2, CV_32F);
FlannBasedMatcher matcher;
std::vector<DMatch> matches;
matcher.match(descriptors_img1,descriptors_img2,matches);
double max_dist = 0; double min_dist = 100;
//-- Quick calculation of max and min distances between keypoints
for( int i = 0; i < descriptors_img1.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 3*min_dist )
std::vector< DMatch > good_matches;
for( int i = 0; i < descriptors_img1.rows; i++ )
{
if( matches[i].distance < 3*min_dist )
{
good_matches.push_back( matches[i]);
}
}
Mat img_matches;
drawMatches(img1,kp1,img2,kp2,good_matches,img_matches,Scalar::all(-1),
Scalar::all(-1),vector<char>(),DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS );
//-- Localize the object
std::vector<Point2f> obj;
std::vector<Point2f> scene;
for( int i = 0; i < good_matches.size(); i++ )
{
//-- Get the keypoints from the good matches
obj.push_back( kp1[ good_matches[i].queryIdx ].pt );
scene.push_back( kp2[ good_matches[i].trainIdx ].pt );
}
Mat H = findHomography( obj, scene, CV_RANSAC );
【问题讨论】:
-
Richard Szilesk 的“计算机视觉:算法和应用”的第 9 章和第 10 章应该为您提供了足够的信息。基本上,您需要将两个图像之一的所有像素的坐标转换为其他图像。通常两个图像中只有一部分重叠,因此生成的图像会更大,以便同时包含两者。您可以根据两个图像的角计算新的宽度和高度。
-
使用 warpImage 您可以将两个图像带到同一个坐标系,但是您必须决定为结果选择哪个图像的哪个像素。通常这是通过一些混合机制完成的,例如 alpha 混合/线性交叉混合,但最终取决于图像的同质性(亮度、运动视差等)