Ishanka
Ishanka

Reputation: 360

How to match two different image in C++

I'm trying to reconstruct a 3D model of a anatomical structure. So I want to match key points in pair of X ray images. I tried it by using following code. But it didn't give correct results.

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;

These are the two images

image 01

image 02

This is what i got from this code

Result image

This is very close to my expected result but it also matching wrong points. This shows few points but i need more points.

enter image description here

Upvotes: 3

Views: 1517

Answers (2)

V.Lee
V.Lee

Reputation: 51

I think you may try to use ITK, ITK is designed to complete image registration with 2D or 3D images.

Upvotes: 0

Adi Shavit
Adi Shavit

Reputation: 17295

Feature detectors like SIFT or SURF are designed to work and match images that have a rich and distinctive texture. They are not designed to work with very spares binary inputs like your examples.

You might want to try them on the original X-Rays for more image context.
Alternatively, you might try a more direct global alignment model between the images.

Check out this link for some options for alignment with the findTransformECC() function.

Also see the article here.

Upvotes: 2

Related Questions