📄 match.c
字号:
/*Detects SIFT features in two images and finds matches between them.Copyright (C) 2006 Rob Hess <hess@eecs.oregonstate.edu>@version 1.1.1-20070330
*/
//---OpenCV的库文件-----------#pragma comment (lib,"cv")
#pragma comment (lib,"highgui")
#pragma comment (lib, "cxcore")
//---gsl的库文件-----------
#pragma comment (lib, "libgsl.a")
#include "sift.h"#include "imgfeatures.h"#include "kdtree.h"#include "utils.h"#include "xform.h"#include <cv.h>#include <cxcore.h>#include <highgui.h>#include <stdio.h>
#include <iostream.h>/* the maximum number of keypoint NN candidates to check during BBF search */#define KDTREE_BBF_MAX_NN_CHKS 200/* threshold on squared ratio of distances between NN and 2nd NN */#define NN_SQ_DIST_RATIO_THR 0.49/******************************** Globals ************************************/char img1_file[] = ".\\beaver.png"; //怎么VC下一个点就够了的 .net下需要两个点char img2_file[] = ".\\beaver_xform.png";
//char img1_file[] = ".\\034.JPG"; //怎么VC下一个点就够了的 .net下需要两个点
//char img2_file[] = ".\\035.JPG";
double imgzoom_scale=1.0; //显示匹配结果图的缩放比例
IplImage* stacked;
/**************************other functions **************************************/
//----鼠标响应函数(用于根据鼠键响应缩放匹配结果的窗口大小)
void on_mouse( int event, int x, int y, int flags, void* param ) ;
//---改变匹配结果图像的大小------------------------
void resize_img();
/********************************** Main *************************************/int main( int argc, char** argv ){
IplImage* img1, * img2;
struct feature* feat1, * feat2, * feat;
struct feature** nbrs;
struct kd_node* kd_root;
CvPoint pt1, pt2;
double d0, d1;
int n1, n2, k, i, m = 0;
//------------内存存储器------------
CvMemStorage* memstorage = cvCreateMemStorage(0);
//-----------up_seq存储img1匹配出的特征点的坐标-----------
CvSeq *up_seq = cvCreateSeq( CV_SEQ_ELTYPE_POINT,
sizeof(CvSeq),
sizeof(CvPoint),
memstorage);
//-----------down_seq存储img2匹配出的特征点的坐标-----------
CvSeq *down_seq = cvCreateSeq( CV_SEQ_ELTYPE_POINT,
sizeof(CvSeq),
sizeof(CvPoint),
memstorage);
img1 = cvLoadImage( img1_file, 1 ); if( ! img1 ) fatal_error( "unable to load image from %s", img1_file ); img2 = cvLoadImage( img2_file, 1 ); if( ! img2 ) fatal_error( "unable to load image from %s", img2_file );
stacked = stack_imgs( img1, img2 );
fprintf( stderr, "Finding features in %s...\n", img1_file ); n1 = sift_features( img1, &feat1 );
fprintf( stderr, "Finding features in %s...\n", img2_file ); n2 = sift_features( img2, &feat2 );
//----------显示img1的SIFT特征---------
if(1)
{
draw_features( img1, feat1, n1 );
cvNamedWindow( "img1_feature", 1 );
cvShowImage( "img1_feature", img1 );
}
//----------显示img2的SIFT特征---------
if(1)
{
draw_features( img2, feat2, n2 );
cvNamedWindow( "img2_feature", 1 );
cvShowImage( "img2_feature", img2 );
}
kd_root = kdtree_build( feat2, n2 );
for( i = 0; i < n1; i++ ) { feat = feat1 + i; k = kdtree_bbf_knn( kd_root, feat, 2, &nbrs, KDTREE_BBF_MAX_NN_CHKS ); if( k == 2 ) { d0 = descr_dist_sq( feat, nbrs[0] ); d1 = descr_dist_sq( feat, nbrs[1] ); if( d0 < d1 * NN_SQ_DIST_RATIO_THR ) { pt1 = cvPoint( cvRound( feat->x ), cvRound( feat->y ) );
pt2 = cvPoint( cvRound( nbrs[0]->x ), cvRound( nbrs[0]->y ) );
//---------存储单个点坐标到点序列中----------
cvSeqPush(up_seq,&pt1);
cvSeqPush(down_seq,&pt2);
pt2.y += img1->height; cvLine( stacked, pt1, pt2, CV_RGB(255,0,255), 1, 8, 0 ); m++; feat1[i].fwd_match = nbrs[0];
} } free( nbrs ); }
fprintf( stderr, "Found %d total matches\n", m );
//---------存储匹配点的坐标到文件-----------------
cvSave("upimg_matched_points.xml", up_seq, NULL, "matched_points_up", cvAttrList(NULL,NULL));
cvSave("downimg_matched_points.xml", down_seq, NULL, "matched_points_down", cvAttrList(NULL,NULL));
fprintf( stderr, "%d 个匹配的点的坐标已分别保存到文件:\n upimg_matched_points.xml和downimg_matched_points.xml\n", m );
resize_img();
cvWaitKey( 0 ); /* UNCOMMENT BELOW TO SEE HOW RANSAC FUNCTION WORKS Note that this line above: feat1[i].fwd_match = nbrs[0]; is important for the RANSAC function to work. */ /* { CvMat* H; H = ransac_xform( feat1, n1, FEATURE_FWD_MATCH, lsq_homog, 4, 0.01, homog_xfer_err, 3.0, NULL, NULL ); if( H ) { IplImage* xformed; xformed = cvCreateImage( cvGetSize( img2 ), IPL_DEPTH_8U, 3 ); cvWarpPerspective( img1, xformed, H, CV_INTER_LINEAR + CV_WARP_FILL_OUTLIERS, cvScalarAll( 0 ) ); cvNamedWindow( "Xformed", 1 ); cvShowImage( "Xformed", xformed ); cvWaitKey( 0 ); cvReleaseImage( &xformed ); cvReleaseMat( &H ); } } */
//------释放内存存储器-----------
cvReleaseMemStorage( &memstorage ); cvReleaseImage( &stacked ); cvReleaseImage( &img1 ); cvReleaseImage( &img2 ); kdtree_release( kd_root ); free( feat1 ); free( feat2 ); return 0;}
void on_mouse( int event, int x, int y, int flags, void* param )
{
if( (event==CV_EVENT_LBUTTONUP) && (flags==CV_EVENT_FLAG_CTRLKEY) )
{
}
if( (event==CV_EVENT_LBUTTONUP) && (flags==CV_EVENT_FLAG_ALTKEY) )
//ALT和鼠标左键开始按下的时候放大匹配结果图
{
//---------特征点匹配函数--------------
if(imgzoom_scale<1.5)
{
imgzoom_scale=1.1*imgzoom_scale;
}
else imgzoom_scale=1.0;
//----放大匹配结果图-----
resize_img();
}
if( (event==CV_EVENT_RBUTTONUP) && (flags==CV_EVENT_FLAG_ALTKEY) )
//ALT和鼠标右键开始按下的时候缩小匹配结果图
{
//---------特征点匹配函数--------------
if(imgzoom_scale>0.0)
{
imgzoom_scale=0.9*imgzoom_scale;
}
else imgzoom_scale=0.5;
//----缩小匹配结果图-----
resize_img();
//printf("%f\n",imgzoom_scale);
}
}
//--------------改变匹配结果图像的大小------------------------
void resize_img()
{
IplImage* resize_stacked;
resize_stacked=cvCreateImage(cvSize( (int)(stacked->width*imgzoom_scale), (int)(stacked->height*imgzoom_scale) ),
stacked->depth,
stacked->nChannels);
//----缩放匹配结果图的大小------
cvResize(stacked, resize_stacked, CV_INTER_AREA );
printf("\n同时ALT键和鼠标右键按下将缩小匹配结果图\n\n");
printf("同时ALT键和鼠标左键按下将放大匹配结果图\n");
cvNamedWindow( "Matches", 1 );
//---------鼠键响应函数--------------
cvSetMouseCallback("Matches", on_mouse, 0 );
cvShowImage( "Matches", resize_stacked);
cvWaitKey( 0 );
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -