I have come up with some problem while I was working on real time object matching using SIFT feature detector. Here is my solution on video.
First I have created a struct to store matched keypoints.The struct contains location of keypoint in templateImage,location of keypoint in inputImage and similarity measure.Here I have used cross correlation of vectors as a similarity measure.
struct MatchedPair
{
Point locationinTemplate;
Point matchedLocinImage;
float correlation;
MatchedPair(Point loc)
{
locationinTemplate=loc;
}
}
I will select sort the matched keypoints according to their similarity so I will need a helper function that will tell std::sort()
to how to compare my MatchedPair
objects.
bool comparator(MatchedPair a,MatchedPair b)
{
return a.correlation>b.correlation;
}
Now the main code starts. I have used standard method to detect and descrypt features from both input image and templateImage.After computing features I have implemented my own matching function.This is the answer you are looking for
int main()
{
Mat templateImage = imread("template.png",IMREAD_GRAYSCALE);
VideoCapture cap("input.mpeg");
Mat frame;
vector<KeyPoint> InputKeypts,TemplateKeypts;
SiftFeatureDetector detector;
SiftDescriptorExtractor extractor;
Mat InputDescriptor,templateDescriptor,result;
vector<MatchedPair> mpts;
Scalar s;
cap>>frame;
cvtColor(image,image,CV_BGR2GRAY);
Mat outputImage =Mat::zeros(templateImage.rows+frame.rows,templateImage.cols+frame.cols,CV_8UC1);
detector.detect(templateImage,TemplateKeypts);
extractor.compute(templateImage,TemplateKeypts,templateDescriptor);
while( true)
{
mpts.clear();
cap>>frame;
outputImage=Mat::zeros(templateImage.rows+frame.rows,templateImage.cols+frame.cols,CV_8UC1);
cvtColor(frame,frame,CV_BGR2GRAY);
detector.detect(frame,InputKeypts);
extractor.compute(frame,InputKeypts,InputDescriptor);
for ( int i=0;i<templateDescriptor.rows;i++)
{
mpts.push_back(MatchedPair(TemplateKeypts[i].pt));
mpts[i].correlation =0;
for ( int j=0;j<InputDescriptor.rows;j++)
{
matchTemplate(templateDescriptor.row(i),InputDescriptor.row(j),result,CV_TM_CCOR_NORMED);
s=sum(result);
if(s.val[0]>mpts[i].correlation)
{
mpts[i].correlation=s.val[0];
mpts[i].matchedLocinImage=InputKeypts[j].pt;
}
}
}
frame.copyTo(outputImage(Rect(templateImage.cols,templateImage.rows,frame.cols,frame.rows)));
std::sort(mpts.begin(),mpts.end(),comparator);
for( int i=0;i<4;i++)
{
if ( mpts[i].correlation>0.90)
{
cv::line(outputImage,mpts[i].locationinTemplate,mpts[i].matchedLocinImage+Point(templateImage.cols,templateImage.rows),Scalar::all(255));
}
}
imshow("Output",outputImage);
waitKey(33);
}
}