如何在C ++中匹配两个不同的图像

时间:2017-02-12 02:57:44

标签: c++ opencv

我正在尝试重建解剖结构的3D模型。所以我想匹配一对X射线图像中的关键点。我通过使用以下代码尝试了它。但它没有给出正确的结果。

Mat tmp = cv::imread( "1.jpg", 1 );
Mat in  = cv::imread( "2.jpg", 1 );
cv::SiftFeatureDetector detector( 0.0001, 1.0 );
cv::SiftDescriptorExtractor extractor;
vector<KeyPoint> keypoints1, keypoints2;
detector.detect( tmp, keypoints1 );
detector.detect( in, keypoints2 );

Mat feat1,feat2;
drawKeypoints(tmp,keypoints1,feat1,Scalar(255, 255, 255),DrawMatchesFlags::DRAW_RICH_KEYPOINTS);
drawKeypoints(in,keypoints2,feat2,Scalar(255, 255, 255),DrawMatchesFlags::DRAW_RICH_KEYPOINTS);
imwrite( "feat1.bmp", feat1 );
imwrite( "feat2.bmp", feat2 );
int key1 = keypoints1.size();
int key2 = keypoints2.size();
printf("Keypoint1=%d \nKeypoint2=%d", key1, key2);

Mat descriptor1,descriptor2;
extractor.compute( tmp, keypoints1, descriptor1 );
extractor.compute( in, keypoints2, descriptor2 );

BruteForceMatcher<L2<float> > matcher;
std::vector< DMatch > matches;

matcher.match( descriptor1, descriptor2, matches );
double max_dist = 0; double min_dist = 100;

Mat img_matches;
for( int i = 0; i < descriptor1.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 );

std::vector< DMatch > good_matches;

for( int i = 0; i < descriptor1.rows; i++ )
{ if( matches[i].distance <= max(2*min_dist, 0.03) )
{ good_matches.push_back( matches[i]); }
}

drawMatches( tmp, keypoints1, in, keypoints2,
           good_matches, img_matches, Scalar::all(-1), Scalar::all(-1),
           vector<char>(), DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS );


namedWindow("SIFT", CV_WINDOW_AUTOSIZE );
imshow("SIFT", img_matches);
imwrite("sift_1.jpg",img_matches);
waitKey(0);

return 0;

这是两张图片

image 01

image 02

这是我从这段代码中得到的

Result image

这非常接近我的预期结果,但它也匹配错误的点。这显示了几点,但我需要更多的分数。

enter image description here

2 个答案:

答案 0 :(得分:2)

SIFT或SURF等特征探测器设计用于匹配具有丰富独特纹理的图像。它们不适用于非常稀有的二进制输入,例如您的示例。

您可能希望在原始X-Rays上试用它们以获得更多图像背景 或者,您可以在图像之间尝试更直接的全局对齐模型。

查看this link以了解与findTransformECC()功能对齐的一些选项。

另见the article here

答案 1 :(得分:0)

我认为你可能会尝试使用ITK,ITK旨在用2D或3D图像完成图像配准。