Exemple #1
1
int getFeatures(Mat &object, Mat &frame, Mat &homography, vector<KeyPoint> &keypoints_object,
    vector<KeyPoint> &keypoints_scene, vector<DMatch> &good_matches) {

    Ptr<SIFT> detector = SIFT::create();

    // Detect features and compute descriptors
    Mat descriptors_object, descriptors_scene;
    detector->detectAndCompute(object, noArray(), keypoints_object, descriptors_object);
    detector->detectAndCompute(frame, noArray(), keypoints_scene, descriptors_scene);

    // Match descriptors using FLANN
    FlannBasedMatcher matcher;
    vector<DMatch> matches;
    matcher.match(descriptors_object, descriptors_scene, matches);

    // Check if too few matches are found
    if (matches.size() <= 4) {
        cout << "Error: too few matches were found" << endl;
        return -1;
    }

    // Find minimum and maximum distances between descriptors
    double max_dist = 0;
    double min_dist = 100;
    for (int i = 0; i < descriptors_object.rows; i++) {
        double dist = matches[i].distance;
        if (dist < min_dist) min_dist = dist;
        if (dist > max_dist) max_dist = dist;
    }

    // If there are sufficient matches, filter to find higher-quality subset
    int minMatches = 8;
    for (int i = 0; i < descriptors_object.rows; i++) {
        if (matches[i].distance < 3*min_dist && matches.size() > minMatches) {
            good_matches.push_back(matches[i]);
        }
    }
    // If there are too few good matches, use all matches
    if (good_matches.size() <= minMatches) {
        for (int i = 0; i < matches.size(); i++) {
            if (i < good_matches.size()) {
                good_matches[i] = matches[i];
            } else {
                good_matches.push_back(matches[i]);
            }
        }
    }

    vector<Point2f> obj, scene;
    for (int i = 0; i < good_matches.size(); i++) {
        // Determine keypoints from the matches
        obj.push_back(keypoints_object[ good_matches[i].queryIdx ].pt);
        scene.push_back(keypoints_scene[ good_matches[i].trainIdx ].pt);
    }

    // Transform pixel coordinates between images
    homography = findHomography(obj, scene, CV_RANSAC);
    return good_matches.size();
}
Exemple #2
0
void main()
{
	//Give the names of the images to be registered
	const char* imRef_name = "834-r1.png";
	const char* imNxt_name = "835-r1.png";
	int hessianThresh = 100, ransacThresh = 3;;
	Mat mask, H12;
	// Read images
	Mat img1 = imread(imRef_name, CV_LOAD_IMAGE_GRAYSCALE);
	Mat img2 = imread(imNxt_name, CV_LOAD_IMAGE_GRAYSCALE);
	Mat img2Out;	// Registered image2 wrt image1

	// Check to see if images exist
	if(img1.empty() || img2.empty())
	{
		printf("Can’t read one of the images\n");
		exit(0);
	}

	// detecting keypoints
	printf("Finding keypoints ... ");
	SURF ImgSurf(hessianThresh);
	vector<KeyPoint> keypoints1, keypoints2;
	ImgSurf(img1, mask, keypoints1);
	ImgSurf(img2, mask, keypoints2);
	// computing descriptors
	SurfDescriptorExtractor extractor;
	Mat descriptors1, descriptors2;
	extractor(img1,mask,keypoints1,descriptors1,TRUE);
	extractor(img2, mask, keypoints2, descriptors2, TRUE);

	// Match the points
	printf("\nMatching keypoints ... ");
	FlannBasedMatcher matcher;
	std::vector< DMatch > matches;
	matcher.match( descriptors1, descriptors2, matches );

	// Extract indices of matched points
    vector<int> queryIdxs( matches.size() ), trainIdxs( matches.size() );
    for( size_t i = 0; i < matches.size(); i++ )
    {
        queryIdxs[i] = matches[i].queryIdx;
        trainIdxs[i] = matches[i].trainIdx;
    }

	// Extract matched points from indices
    vector<Point2f> points1; KeyPoint::convert(keypoints1, points1, queryIdxs);
    vector<Point2f> points2; KeyPoint::convert(keypoints2, points2, trainIdxs);

	// Use RANSAC to find the homography
	printf("\nComputing homography ... ");
    H12 = findHomography( Mat(points2), Mat(points1), CV_RANSAC, ransacThresh );
	
	// Warp the second image according to the homography
	warpPerspective(img2, img2Out, H12, cvSize(img2.cols, img2.rows), INTER_LINEAR);

	// Write result to file
	imwrite("im2reg.png",img2Out);
	printf("\nDone!!!.... ");
}
Exemple #3
0
vector<DMatch> GraphicEnd::match( Mat desp1, Mat desp2 )
{
    cout<<"GraphicEnd::match two desp"<<endl;
    FlannBasedMatcher matcher;
    vector<DMatch> matches;

    if (desp1.empty() || desp2.empty())
    {
        return matches;
    }
    double max_dist = 0, min_dist = 100;
    matcher.match( desp1, desp2, matches);

    for (int i=0; i<desp1.rows; i++)
    {
        double dist = matches[ i ].distance;
        if (dist < min_dist)
            min_dist = dist;
        if (dist > max_dist)
            max_dist = dist;
    }

    //return matches;

    vector<DMatch> good_matches;
    for (size_t i=0; i<matches.size(); i++)
    {
        if (matches[ i ].distance <= max(4*min_dist, _match_min_dist))
        {
            good_matches.push_back(matches[ i ]);
        }
    }
    return good_matches;
}
void detectSiftMatchWithOpenCV(const char* img1_path, const char* img2_path, MatrixXf &match) {
  Mat img1 = imread(img1_path);   
  Mat img2 = imread(img2_path);   

  SiftFeatureDetector detector;
  SiftDescriptorExtractor extractor;
  vector<KeyPoint> key1;
  vector<KeyPoint> key2;
  Mat desc1, desc2;
  detector.detect(img1, key1);
  detector.detect(img2, key2);
  extractor.compute(img1, key1, desc1);
  extractor.compute(img2, key2, desc2);

  FlannBasedMatcher matcher;
  vector<DMatch> matches;
  matcher.match(desc1, desc2, matches);

  match.resize(matches.size(), 6);
  cout << "match count: " << matches.size() << endl;
  for (int i = 0; i < matches.size(); i++) {
    match(i, 0) = key1[matches[i].queryIdx].pt.x;
    match(i, 1) = key1[matches[i].queryIdx].pt.y;
    match(i, 2) = 1;
    match(i, 3) = key2[matches[i].trainIdx].pt.x;
    match(i, 4) = key2[matches[i].trainIdx].pt.y;
    match(i, 5) = 1;
  }
  
}
int match(vector<DMatch> &match, frame &f1, frame &f2)
{
	vector<DMatch> matches;
  FlannBasedMatcher matcher;
  matcher.match(f1.desp, f2.desp, matches);
  
  static reader pd("../config/config.ini");
  
  double min_distance = 9999;
  double match_threshold = atof(pd.get("match_threshold").c_str());
  
  for (int i = 0; i < matches.size(); ++i)
  {
    if (matches[i].distance < min_distance)
    {
      min_distance = matches[i].distance;
    }
  }
  
  for (int i = 0; i < matches.size(); ++i)
  {
    if (matches[i].distance < (min_distance * match_threshold))
    {
      match.push_back(matches[i]);
    }
  }
  
  return match.size();
}
Exemple #6
0
bool RelicScn::Match_an_Obj(RelicObj obj)
{
	string message;

	FlannBasedMatcher matcher;
	vector<DMatch> matches;

	matcher.match(obj.descriptors, this->descriptors, matches);
	vector<DMatch> good_matches = Get_Good_Matches(matches);

	//-- Localize the object
	std::vector<Point2f> obj_points;
	std::vector<Point2f> scn_points;
	for (size_t i = 0; i < good_matches.size(); i++)
	{
		//-- Get the keypoints from the good matches
		obj_points.push_back(obj.keypoints[good_matches[i].queryIdx].pt);
		scn_points.push_back(this->keypoints[good_matches[i].trainIdx].pt);
	}
	Mat H = cv::findHomography(obj_points, scn_points, RANSAC);

	std::vector<Point2f> obj_corners(4);
	
	obj_corners[0] = cvPoint(0, 0);
	obj_corners[1] = cvPoint(obj.img_width-1, 0);
	obj_corners[2] = cvPoint(obj.img_width-1, obj.img_height-1);
	obj_corners[3] = cvPoint(0, obj.img_height-1);

	std::vector<Point2f> possible_obj_corners(4);
	perspectiveTransform(obj_corners, possible_obj_corners, H);
	BOOST_LOG_TRIVIAL(info) << "原始目标物体大小(像素): " << contourArea(obj_corners);
	BOOST_LOG_TRIVIAL(info) << "检测到的物体大小(像素): " << contourArea(possible_obj_corners);
	this->corners = possible_obj_corners;
	double possible_target_area = contourArea(possible_obj_corners);
	double whole_scene_area = this->img_gray.rows*this->img_gray.cols;
	BOOST_LOG_TRIVIAL(info) << "环境图像大小(像素): " << whole_scene_area;
	double ratio = possible_target_area / whole_scene_area;
	BOOST_LOG_TRIVIAL(info) << "检测到的目标占全图比例: " << ratio;
	if (ratio>0.03 && ratio<1)
	{
		for (int i;i < possible_obj_corners.size();i++)
		{
			if (possible_obj_corners[i].x < 0 || possible_obj_corners[i].y < 0)
			{
				BOOST_LOG_TRIVIAL(info) << "未能检测到目标物体!";
				return false;
			}
		}
		BOOST_LOG_TRIVIAL(info) << "成功检测到目标物体!";
		return true;
	} 
	else
	{
		BOOST_LOG_TRIVIAL(info) << "未能检测到目标物体!";
		return false;
	}
}
Exemple #7
0
int compare(Mat img_1, Mat img_2) {
  //-- Step 1: Detect the keypoints using SURF Detector
  int minHessian = 400;

  SurfFeatureDetector detector( minHessian );

  std::vector<KeyPoint> keypoints_1, keypoints_2;

  detector.detect( img_1, keypoints_1 );
  detector.detect( img_2, keypoints_2 );

  //-- Step 2: Calculate descriptors (feature vectors)
  SurfDescriptorExtractor extractor;

  Mat descriptors_1, descriptors_2;

  extractor.compute( img_1, keypoints_1, descriptors_1 );
  extractor.compute( img_2, keypoints_2, descriptors_2 );

  //-- Step 3: Matching descriptor vectors using FLANN matcher
  FlannBasedMatcher matcher;
  std::vector< DMatch > matches;
  matcher.match( descriptors_1, descriptors_2, matches );

  double max_dist = 0; double min_dist = 100;

  //-- Quick calculation of max and min distances between keypoints
  for( int i = 0; i < descriptors_1.rows; i++ ) { 
    double dist = matches[i].distance;
    if( dist < min_dist ) min_dist = dist;
    if( dist > max_dist ) max_dist = dist;
  }

  //-- Draw only "good" matches (i.e. whose distance is less than 2*min_dist,
  //-- or a small arbitary value ( 0.02 ) in the event that min_dist is very
  //-- small)
  //-- PS.- radiusMatch can also be used here.
  std::vector< DMatch > good_matches;

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

  // Mat img_matches;
  // drawMatches( img_1, keypoints_1, img_2, keypoints_2,
  //              good_matches, img_matches, Scalar::all(-1), Scalar::all(-1),
  //              vector<char>(), DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS );

  // //-- Show detected matches
  // imshow( "Good Matches", img_matches );

  waitKey(0);

  return good_matches.size();
}
int PlayedCard::computeSurfGoodMatches(vector<KeyPoint> keypoints_1, vector<KeyPoint> keypoints_2, Mat descriptors_1, Mat descriptors_2) {

	//-- Step 3: Matching descriptor vectors using FLANN matcher
	FlannBasedMatcher matcher;
	vector< DMatch > matches;
	matcher.match(descriptors_1, descriptors_2, matches);

	filterMatchesByAbsoluteValue(matches, 0.125);
	filterMatchesRANSAC(matches, keypoints_1, keypoints_2);

	return (int)matches.size();
}
Exemple #9
0
int main(int argc, char* argv[])
{
	VideoCapture camera;
	camera.set(CV_CAP_PROP_FRAME_WIDTH, WIDTH);
	camera.set(CV_CAP_PROP_FRAME_HEIGHT, HEIGHT);
	camera.open(0);
	
	//checkOpenCL();
	Ptr<FeatureDetector> detector = FeatureDetector::create("STAR");
	//Ptr<DescriptorExtractor> extractor = DescriptorExtractor::create("FREAK");
	BriefDescriptorExtractor extractor;
	FlannBasedMatcher matcher;
	std::vector< DMatch > matches;
	Mat descriptor[2];

	int k = 0;
	camera >> image;
	detector->detect(image, keypoint[1]);
	extractor.compute(image, keypoint[1], descriptor[1]);
	for (bool loop = true; loop; )
	{
		switch (waitKey(10))
		{
		case 'q':
			loop = false;
			break;
		}
		camera >> image;
		if (image.empty())
			break;

		// detect features
		detector->detect(image, keypoint[k % 2]);
		extractor.compute(image, keypoint[k % 2], descriptor[k % 2]);
		try {
			matcher.match(descriptor[0], descriptor[1], matches);
		}
		catch (Exception ex)
		{
			printf("%s", ex.msg);
		}
		printf("%d\n", keypoint[k % 2].size());
		for (int i = 0; i < keypoint[k % 2].size(); i++)
		{
			Point2f pt = keypoint[k % 2][i].pt;
			circle(image, Point(pt.x, pt.y), 3, Scalar(0, 0, 255));
		}
		k++;
		imshow("image", image);
	}
	return 0;
}
Exemple #10
0
/**
 * @brief featuredetector::testFeatures
 * FLANN based matching.
 * Algorithm is taken from
 * http://docs.opencv.org/doc/tutorials/features2d/feature_flann_matcher/feature_flann_matcher.html
 * @return Matched points image.
 */
Mat featuredetector::testFeatures(){
    cv::Mat im1, im2;

    //Grayscale the images.
    if(_image1.channels() == 3)
        cv::cvtColor(_image1,im1, CV_BGR2GRAY);
    else _image1.copyTo(im1);
    if(_image2.channels() == 3)
        cv::cvtColor(_image2,im2, CV_BGR2GRAY);
    else _image2.copyTo(im2);


    int minH = 100; // (should be around ~100)
    Ptr<xfeatures2d::SURF> detector =  xfeatures2d::SURF::create(minH);
    detector->setHessianThreshold(minH);

    std::vector<KeyPoint> keypoints1, keypoints2;
    Mat descriptors1, descriptors2;
    detector->detectAndCompute( im1, Mat(), keypoints1, descriptors1 );
    detector->detectAndCompute( im2, Mat(), keypoints2, descriptors2 );

    FlannBasedMatcher matcher;

    std::vector<DMatch> matches;
    matcher.match( descriptors1, descriptors2, matches );
    double maxDist = 0; double minDist = 80;



    for( int i = 0; i < descriptors1.rows; i++ )
    { double dist = matches[i].distance;
        if( dist < minDist ) minDist = dist;
        if( dist > maxDist ) maxDist = dist;
    }
    std::vector< DMatch > goodMatches;

    for( int i = 0; i < descriptors1.rows; i++ )
    { if( matches[i].distance <= max(2*minDist, 0.02) )
        { goodMatches.push_back( matches[i]); }
    }



    Mat matchMat;
    drawMatches( im1, keypoints1, im2, keypoints2,
                 goodMatches, matchMat, Scalar::all(-1), Scalar::all(-1),
                 vector<char>(), DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS );

    imshow( "Matches", matchMat );
    return matchMat;
}
Exemple #11
0
/*
 * @function main
 * @brief Main function
 */
int flann( int argc, char** argv )
{
  if( argc != 3 )
  { readme(); return -1; }
  Mat img_1 = imread( argv[1], IMREAD_GRAYSCALE );
  Mat img_2 = imread( argv[2], IMREAD_GRAYSCALE );
  if( !img_1.data || !img_2.data )
  { std::cout<< " --(!) Error reading images " << std::endl; return -1; }
  //-- Step 1: Detect the keypoints using SURF Detector, compute the descriptors
  int minHessian = 400;
  Ptr<SURF> detector = SURF::create();
  detector->setHessianThreshold(minHessian);
  std::vector<KeyPoint> keypoints_1, keypoints_2;
  Mat descriptors_1, descriptors_2;
  detector->detectAndCompute( img_1, Mat(), keypoints_1, descriptors_1 );
  detector->detectAndCompute( img_2, Mat(), keypoints_2, descriptors_2 );
  //-- Step 2: Matching descriptor vectors using FLANN matcher
  FlannBasedMatcher matcher;
  std::vector< DMatch > matches;
  matcher.match( descriptors_1, descriptors_2, matches );
  double max_dist = 0; double min_dist = 100;
  //-- Quick calculation of max and min distances between keypoints
  for( int i = 0; i < descriptors_1.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 2*min_dist,
  //-- or a small arbitary value ( 0.02 ) in the event that min_dist is very
  //-- small)
  //-- PS.- radiusMatch can also be used here.
  std::vector< DMatch > good_matches;
  for( int i = 0; i < descriptors_1.rows; i++ )
  { if( matches[i].distance <= max(2*min_dist, 0.02) )
    { good_matches.push_back( matches[i]); }
  }
  //-- Draw only "good" matches
  Mat img_matches;
  drawMatches( img_1, keypoints_1, img_2, keypoints_2,
               good_matches, img_matches, Scalar::all(-1), Scalar::all(-1),
               vector<char>(), DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS );
  //-- Show detected matches
  imshow( "Good Matches", img_matches );
  for( int i = 0; i < (int)good_matches.size(); i++ )
  { printf( "-- Good Match [%d] Keypoint 1: %d  -- Keypoint 2: %d  \n", i, good_matches[i].queryIdx, good_matches[i].trainIdx ); }
  waitKey(0);
  return 0;
}
Exemple #12
0
vector<DMatch> GraphicEnd::match( vector<PLANE>& p1, vector<PLANE>& p2 )
{
    cout<<"GraphicEnd::match two planes"<<endl;
    FlannBasedMatcher matcher;
    vector<DMatch> matches;
    cv::Mat des1(p1.size(), 4, CV_32F), des2(p2.size(), 4, CV_32F);
    for (size_t i=0; i<p1.size(); i++)
    {
        pcl::ModelCoefficients c = p1[i].coff;
        float m[1][4] = { c.values[0], c.values[1], c.values[2], c.values[3] };
        Mat mat = Mat(1,4, CV_32F, m);
        mat.row(0).copyTo( des1.row(i) );
    }

    for (size_t i=0; i<p2.size(); i++)
    {
        pcl::ModelCoefficients c = p2[i].coff;
        float m[1][4] = { c.values[0], c.values[1], c.values[2], c.values[3] };
        Mat mat = Mat(1,4, CV_32F, m);
        mat.row(0).copyTo( des2.row(i) );
    }

    matcher.match( des1, des2, matches);

    return matches;
    double max_dist = 0, min_dist = 100;

    for (int i=0; i<des1.rows; i++)
    {
        double dist = matches[ i ].distance;
        if (dist < min_dist)
            min_dist = dist;
        if (dist > max_dist)
            max_dist = dist;
    }

    vector<DMatch> good_matches;
    for (size_t i=0; i<matches.size(); i++)
    {
        if (matches[ i ].distance <= 3*min_dist)
        {
            good_matches.push_back(matches[ i ]);
        }
    }
    return good_matches;
}
Exemple #13
0
//Realiza el Matching entre puntos
void computeMatching(Mat& img1, Mat& img2,vector<KeyPoint>& keypoints1,vector<KeyPoint>& keypoints2, vector<DMatch>& matches ){
        // computing descriptors
        #if _SURF_
        SurfDescriptorExtractor extractor;
        #else if _SIFT_
        SiftDescriptorExtractor extractor;
        #endif
        Mat descriptors1, descriptors2;
        extractor.compute(img1, keypoints1, descriptors1);
        extractor.compute(img2, keypoints2, descriptors2);

        FlannBasedMatcher matcher;
        matcher.match(descriptors1,descriptors2,matches);

        double max_dist = 0; double min_dist = 100;

        //-- Quick calculation of max and min distances between keypoints
        for( int i = 0; i < descriptors1.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 2*min_dist )
         //-- PS.- radiusMatch can also be used here.
         std::vector< DMatch > good_matches;

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

         //-- Draw only "good" matches
         Mat img_matches;
         drawMatches( img1, keypoints1, img2, keypoints2,
                        good_matches, img_matches, Scalar::all(-1), Scalar::all(-1),
                        vector<char>(), DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS );

         //-- Show detected matches
         imshow( "Good Matches", img_matches );
}
Exemple #14
0
bool findMatch(CvPoint &offset, FlannBasedMatcher matcher, SurfFeatureDetector detector, SurfDescriptorExtractor extractor, Mat des_object[])
{
	bool noMatch = true;
	Mat des_image, img_matches;
	vector<KeyPoint> kp_image;
	vector<vector<DMatch > > matches;
	vector<DMatch > good_matches;
	int iter = 0;
	Mat image = imread("/home/pi/opencv/photo.jpg" , CV_LOAD_IMAGE_GRAYSCALE );
	detector.detect( image, kp_image );
	extractor.compute( image, kp_image, des_image );
	while ( noMatch )
	{
		//printf("before kp and des detection 2\n");
	    	
		
		matcher.knnMatch(des_object[iter], des_image, matches, 2);
		for(int i = 0; i < min(des_image.rows-1,(int) matches.size()); i++) //THIS LOOP IS SENSITIVE TO SEGFAULTS
		{
		    if((matches[i][0].distance < 0.6*(matches[i][1].distance)) && ((int) matches[i].size()<=2 && (int) matches[i].size()>0))
		    {
			good_matches.push_back(matches[i][0]);
		    }
		}
		
		//printf("Number of matches: %d\n", good_matches.size());
		if (good_matches.size() >= 10)
		{
			CvPoint center = cvPoint(0,0);
			for ( int z = 0 ; z < good_matches.size() ; z++ )
			{
				int index = good_matches.at(z).trainIdx;
				center.x += kp_image.at(index).pt.x;
				center.y += kp_image.at(index).pt.y;
			}
			center.x = center.x/good_matches.size();
			center.y = center.y/good_matches.size();
			int radius = 5;
			circle( image, center, radius, {0,0,255}, 3, 8, 0 );
			namedWindow("test");
			imshow("test", image);
			imwrite("centerPoint.jpg", image);
			waitKey(5000);
			int offsetX = center.x - image.cols/2;
			int offsetY = center.y - image.rows/2;
			offset = cvPoint(offsetX, offsetY);			
			noMatch = false;
		}
		//printf("draw good matches\n");
		//Show detected matches
		if ( iter++ == 3 || !noMatch )
			break;
		
		good_matches.clear();
	}
	return noMatch;
}
Exemple #15
0
void findTopFiveFLANNMatches(Mat hqDesc, vector<Mat>* keyframeDesc, vector<vector< DMatch >>* matchVec, vector<int>* matchIndices){
	FlannBasedMatcher matcher;
	int index = 0;

	//Calculate matches between high quality image and 
	for (vector<Mat>::iterator it = keyframeDesc->begin(); it != keyframeDesc->end(); ++it){
		vector< DMatch > matches;

		//calculate initial matches
		Mat kfDesc = *it;
		matcher.match(hqDesc, kfDesc, matches);

		//determine good matches
		double max_dist = 0; double min_dist = 100;

		//-- Quick calculation of max and min distances between keypoints
		for (int i = 0; i < hqDesc.rows; i++)
		{
			double dist = matches[i].distance;
			if (dist < min_dist) min_dist = dist;
			if (dist > max_dist) max_dist = dist;
		}

		std::vector< DMatch > good_matches;
		for (int i = 0; i < hqDesc.rows; i++)
		{
			if (matches[i].distance <= max(2 * min_dist, 0.02))
			{
				good_matches.push_back(matches[i]);
			}
		}


		matchVec->push_back(good_matches);
		index++;
	}
	//pickTopFive
	pickTopFive(matchVec, matchIndices);
	index = 0;
}
Exemple #16
0
static void match(Mat& img1, Mat& img2, Mat& depth1, Mat& depth2) {
	SurfFeatureDetector detector(400);
	vector<KeyPoint> keypoint1, keypoint2;
	detector.detect(img1, keypoint1);
	detector.detect(img2, keypoint2);

	SurfDescriptorExtractor extractor;
	Mat des1, des2;
	extractor.compute(img1, keypoint1, des1);
	extractor.compute(img2, keypoint2, des2);

	FlannBasedMatcher matcher;
	vector< vector< DMatch > > matches;
	matcher.radiusMatch(des1, des2, matches, 0.2);

	Mat key = img1;
	Mat space( 1024, 640 , CV_8UC3, CV_RGB(0, 0, 0));

	vector< Point > ref1, ref2;
	for(vector< vector<DMatch> >::iterator iter = matches.begin(); iter != matches.end(); iter++) {
		if( iter -> size() > 0) {
			DMatch match = iter->at(0);
			line( key, keypoint1[match.queryIdx].pt, keypoint2[match.trainIdx].pt, CV_RGB(255,0,0), 1);
			
			if( depth1.at<uint16_t>(keypoint1[match.queryIdx].pt) / 10 > 0 )  {
			circle( space, 
				Point( depth1.at<uint16_t>(keypoint1[match.queryIdx].pt) / 10, keypoint1[match.queryIdx].pt.x),
				5,
				CV_RGB(255, 0, 0));
			}

			if( depth1.at<uint16_t>(keypoint1[match.queryIdx].pt) > 0 && depth2.at<uint16_t>(keypoint2[match.trainIdx].pt) > 0)  {
				ref1.push_back( Point( depth1.at<uint16_t>(keypoint1[match.queryIdx].pt), keypoint1[match.queryIdx].pt.x) );
				ref2.push_back( Point( depth2.at<uint16_t>(keypoint2[match.trainIdx].pt), keypoint2[match.trainIdx].pt.x) );
			}
		}
	}
	imshow( "keypoint", key);
	imshow( "space", space);
}
Exemple #17
0
int main(int argc, char** argv)
{
	std::vector<KeyPoint> keypoints_1;
	vector<vector<KeyPoint>>keypoints = vector<vector<KeyPoint>>();
	//////////////////////////////////////////////////////////////////////////
	Ptr<FeatureDetector> detector = xfeatures2d::SIFT::create();
	Ptr<DescriptorExtractor> extractor = xfeatures2d::SIFT::create();
	//Ptr<DescriptorMatcher> matcher = new FlannBasedMatcher();
	FlannBasedMatcher* matcher = new FlannBasedMatcher();
	//////////////////////////////////////////////////////////////////////////
	Mat image, descriptor, homography;
	Mat posters[7], descriptors[7];
	vector<DMatch> matches = vector<DMatch>();

	//detects and extracts the local features
	openImage("poster_test.jpg", image);

	detector->detect(image, keypoints_1);
	extractor->compute(image, keypoints_1, descriptor);

	for (int i = 0;i < 7;i++)
	{
		vector<KeyPoint> keypoint;
		openImage("poster" + std::to_string(i + 1) + ".jpg", posters[i]);
		detector->detect(posters[i], keypoint);
		extractor->compute(posters[i], keypoint, descriptors[i]);
		keypoints.push_back(keypoint);
	}

	matcher->match(descriptor, descriptors[5], matches);

	filterMatchesByAbsoluteValue(matches, 90);

	homography = filterMatchesRANSAC(matches, keypoints_1, keypoints[5]);

	showResult(image, keypoints_1, posters[5], keypoints[5], matches, homography);

	return 0;
}
 std::vector< DMatch > matcher (Mat descripteur1,Mat descripteur2){
    //renvoie les indices des "bons" points uniquement

    //on recupere les zones en communs
    FlannBasedMatcher matcher;
    std::vector<DMatch> matches;

    if(descripteur1.type()!=CV_32F) {
        descripteur1.convertTo(descripteur1, CV_32F);//pb de types -< le match prend des descriptors float et non binaires
    }

    if(descripteur2.type()!=CV_32F) {
        descripteur2.convertTo(descripteur2, CV_32F);
    }

    matcher.match( descripteur1, descripteur2, matches );

    double dmax = 0; double dmin= 1000;

    //calcul des distances max et min entre les matches
    for( int i = 0; i < matches.size(); i++ )
    {
        double d = matches[i].distance;
        if( d<dmin )
            dmin=d;
        if( d>dmax)
            dmax=d;
    }

    //on veut ne garder que les "bonnes zones communes" -> définir "bonnes zones" !!!
    std::vector<DMatch> bonMatches;
    for (int i=0;i<matches.size();i++)
    {
        if (matches[i].distance<=2*dmin) //2*distance minimale est fixé arbitrairement
            bonMatches.push_back(matches[i]);
    }
     return bonMatches;

}
//static void matchDescriptors( const Mat& queryDescriptors, const vector<Mat>& trainDescriptors,
                       //vector<DMatch>& matches, FlannBasedMatcher& descriptorMatcher )
static void matchDescriptors( const Mat& queryDescriptors, const vector<Mat>& trainDescriptors,
                       vector<DMatch>& matches, FlannBasedMatcher& descriptorMatcher, const vector<Mat>& trainImages, const vector<string>& trainImagesNames )

{
    cout << "< Set train descriptors collection in the matcher and match query descriptors to them..." << endl;

    descriptorMatcher.add( trainDescriptors );
    descriptorMatcher.train();

    descriptorMatcher.match( queryDescriptors, matches );

    CV_Assert( queryDescriptors.rows == (int)matches.size() || matches.empty() );

    cout << "Number of matches: " << matches.size() << endl;
    cout << ">" << endl;

    for( int i = 0; i < trainDescriptors.size(); i++){

        std::vector< std::vector< DMatch> > matches2;

        std::vector< DMatch > good_matches;

        descriptorMatcher.knnMatch( queryDescriptors, trainDescriptors[i], matches2, 2);
        CV_Assert( queryDescriptors.rows == (int)matches2.size() || matches2.empty() );

        for (int j = 0; j < matches2.size(); ++j){
            const float ratio = 0.8; // As in Lowe's paper; can be tuned
            if (matches2[j][0].distance < ratio * matches2[j][1].distance){
                good_matches.push_back(matches2[j][0]);
            }

        }

        cout << "currentMatchSize : " << good_matches.size() << endl;

    }

    
}
Exemple #20
0
std::vector<DMatch> Match::vecMatches(Mat * img1, Mat * img2,
		Mat &descriptors_object, vector<KeyPoint> &keypoints_object,
		vector<KeyPoint> &keypoints_scene)
{
	Mat img_object = *img1;
	Mat img_scene = *img2;

	/*
	  if( !img_object.data || !img_scene.data )
	  { std::cout<< " --(!) Error reading images " << std::endl; return -1; }
	 */

	//-- Step 1: Detect the keypoints using SURF Detector
	int minHessian = 400;

	SurfFeatureDetector detector(minHessian);

	//std::vector<KeyPoint> keypoints_object, keypoints_scene;

	detector.detect(img_object, keypoints_object); //TODO: use the third argument here? from previous match?
	detector.detect(img_scene, keypoints_scene);

	//-- Step 2: Calculate descriptors (feature vectors)
	SurfDescriptorExtractor extractor;

	Mat /*descriptors_object,*/ descriptors_scene;

	extractor.compute(img_object, keypoints_object, descriptors_object);
	extractor.compute(img_scene, keypoints_scene, descriptors_scene);

	//-- Step 3: Matching descriptor vectors using FLANN matcher
	FlannBasedMatcher matcher;
	std::vector<DMatch> matches;
	matcher.match(descriptors_object, descriptors_scene, matches);

	return matches;
}
    void tryFindImage_features(Mat input)
    {
    	/* Сравниваем входящее изрображение с набором эталонов и выбираем наиболее подходящее */

    	resize(input, input, Size(SIGN_SIZE, SIGN_SIZE), 0, 0);

    	vector<KeyPoint> keyPoints;
    	_detector.detect(input, keyPoints);

    	Mat descriptors;
    	_extractor.compute(input, keyPoints, descriptors);

    	int max_value = 0, max_position = 0; 

    	for(int i=0; i < 5; i++)
    	{
    		vector< vector<DMatch> > matches;

    		_matcher.knnMatch(descriptors, _train_descriptors[i], matches, 50);

    		int good_matches_count = 0;
		   
		    for (size_t j = 0; j < matches.size(); ++j)
		    { 
		        if (matches[j].size() < 2)
		                    continue;
		       
		        const DMatch &m1 = matches[j][0];
		        const DMatch &m2 = matches[j][1];
		            
		        if(m1.distance <= 0.7 * m2.distance)        
		            good_matches_count++;    
		    }

		    if(good_matches_count > max_value)
		    {
		    	max_value = good_matches_count;
		    	max_position = i;
		    }
    	}

    	cout << STATUS_STR << "Detected sign: " << _train_sign_names[max_position] << endl;
    }
/**
 * @function main
 */
int main(int, char **argv)
{



    image1 = imread(argv[1], 1);
    image2 = imread(argv[2], 1);
    rows = image1.rows;
    cols = image1.cols;


    namedWindow("image1", WINDOW_AUTOSIZE);
    imshow("image1", image1);
    namedWindow("image2", WINDOW_AUTOSIZE);
    imshow("image2", image2);

    Mat image1_gray;
    Mat image2_gray;


    /// Converts an image from one color space to another.
    cvtColor(image1, image1_gray, COLOR_BGR2GRAY);
    cvtColor(image2, image2_gray, COLOR_BGR2GRAY);

    /// Detector parameters
    int blockSize = 2;
    int apertureSize = 3;
    double k = 0.04;

    /// Detecting corners
    /*
       void ocl::cornerHarris(const oclMat& src, oclMat& dst, int blockSize, int ksize, double k, int bordertype=cv::BORDER_DEFAULT)

       src – Source image. Only CV_8UC1 and CV_32FC1 images are supported now.
       dst – Destination image containing cornerness values. It has the same size as src and CV_32FC1 type.
       blockSize – Neighborhood size
       ksize – Aperture parameter for the Sobel operator
       k – Harris detector free parameter
       bordertype – Pixel extrapolation method. Only BORDER_REFLECT101, BORDER_REFLECT, BORDER_CONSTANT and BORDER_REPLICATE are supported now.
     */

    Mat image1dst;
    Mat image2dst;

    image1dst = Mat::zeros(image1.size(), CV_32FC1);
    image2dst = Mat::zeros(image2.size(), CV_32FC1);


    cornerHarris(image1_gray, image1dst, blockSize, apertureSize, k, BORDER_DEFAULT);
    cornerHarris(image2_gray, image2dst, blockSize, apertureSize, k, BORDER_DEFAULT);

    int threshHarris = 100;

    /// Normalizing
    /*
       void normalize(InputArray src, OutputArray dst, double alpha=1, double beta=0, int norm_type=NORM_L2, int dtype=-1, InputArray mask=noArray() )
       src – input array.
       dst – output array of the same size as src .
       alpha – norm value to normalize to or the lower range boundary in case of the range normalization.
       beta – upper range boundary in case of the range normalization; it is not used for the norm normalization.
       normType – normalization type (see the details below).
       dtype – when negative, the output array has the same type as src; otherwise, it has the same number of channels as src and the depth =CV_MAT_DEPTH(dtype).
       mask – optional operation mask.
     */

    Mat image1dst_norm;
    Mat image2dst_norm;

    normalize(image1dst, image1dst_norm, 0, 255, NORM_MINMAX, CV_32FC1, Mat());
    normalize(image2dst, image2dst_norm, 0, 255, NORM_MINMAX, CV_32FC1, Mat());

    /*
       On each element of the input array, the function convertScaleAbs performs three operations sequentially: scaling, taking an absolute value, conversion to an unsigned 8-bit type:

     */

    Mat image1dst_norm_scaled;
    Mat image2dst_norm_scaled;

    convertScaleAbs(image1dst_norm, image1dst_norm_scaled);
    convertScaleAbs(image2dst_norm, image2dst_norm_scaled);

    KeyPoint kp;

    for (int j = 0; j < image1dst_norm.rows; j++) {
	for (int i = 0; i < image1dst_norm.cols; i++) {
	    if ((int) image1dst_norm.at < float >(j, i) > threshHarris) {

		kp.pt.x = (float) j;
		kp.pt.y = (float) i;
		//necessaire je ne sais pas pk
		kp.size = 100.0;
		keypoints1.push_back(kp);

	    }
	}
    }

    for (int j = 0; j < image2dst_norm.rows; j++) {
	for (int i = 0; i < image2dst_norm.cols; i++) {
	    if ((int) image2dst_norm.at < float >(j, i) > threshHarris) {


		kp.pt.x = (float) j;
		kp.pt.y = (float) i;
		//necessaire je ne sais pas pk
		kp.size = 100.0;
		keypoints2.push_back(kp);

	    }
	}
    }


    BriefDescriptorExtractor briefDesc(64);

    Mat descriptors1, descriptors2;
    briefDesc.compute(image1, keypoints1, descriptors1);
    briefDesc.compute(image2, keypoints2, descriptors2);

    //Ptr<DescriptorMatcher> matcher =  new FlannBasedMatcher(DescriptorMatcher::create("Flann"));
    FlannBasedMatcher matcher;

    Mat descriptorAuxKp1;
    Mat descriptorAuxKp2;


    vector < int >associateIdx;

    for (int i = 0; i < descriptors1.rows; i++) {
	//on copie la ligne i du descripteur, qui correspond aux différentes valeurs données par le descripteur pour le Keypoints[i]
	descriptors1.row(i).copyTo(descriptorAuxKp1);

//ici on va mettre que les valeurs du descripteur des keypoints de l'image 2 que l'on veut comparer aux keypoints de l'image1 en cours de traitement
	descriptorAuxKp2.create(0, 0, CV_8UC1);


	//associateIdx va servir à faire la transition entre les indices renvoyés par matches et ceux des Keypoints
	associateIdx.erase(associateIdx.begin(), associateIdx.end());


	for (int j = 0; j < descriptors2.rows; j++) {

	    float p1x = keypoints1[i].pt.x;
	    float p1y = keypoints1[i].pt.y;
	    float p2x = keypoints2[j].pt.x;
	    float p2y = keypoints2[j].pt.y;

	    float distance = sqrt(pow((p1x - p2x), 2) + pow((p1y - p2y), 2));

	    //parmis les valeurs dans descriptors2 on ne va garder que ceux dont les keypoints associés sont à une distance définie du keypoints en cours, en l'occurence le ieme ici.
	    if (distance < 10) {

		descriptorAuxKp2.push_back(descriptors2.row(j));
		associateIdx.push_back(j);

	    }


	}
	//ici on ne matche qu'un keypoints de l'image1 avec tous les keypoints gardés de l'image 2
        matcher.add(descriptorAuxKp1);
        matcher.train();

	matcher.match(descriptorAuxKp2, matches);

	//on remet à la bonne valeur les attributs de matches
	for (int idxMatch = 0; idxMatch < matches.size(); idxMatch++) {
	    //on a comparer le keypoints i
	    matches[idxMatch].queryIdx = i;
	    //avec le keypoints2 j
	    matches[idxMatch].trainIdx = associateIdx[matches[idxMatch].trainIdx];
	}

	//on concatene les matches trouvés pour les points précedents avec les nouveaux
	matchesWithDist.insert(matchesWithDist.end(), matches.begin(), matches.end());


    }



//ici on trie les matchesWithDist par distance des valeurs des descripteurs et non par distance euclidienne
    nth_element(matchesWithDist.begin(), matchesWithDist.begin() + 24, matchesWithDist.end());
    // initial position
    // position of the sorted element
    // end position

    Mat imageMatches;
    Mat matchesMask;
    drawMatches(image1, keypoints1,	// 1st image and its keypoints
		image2, keypoints2,	// 2nd image and its keypoints
		matchesWithDist,	// the matches
		imageMatches,	// the image produced
		Scalar::all(-1),	// color of the lines
		Scalar(255, 255, 255)	//color of the keypoints
	);


    namedWindow(matches_window, CV_WINDOW_AUTOSIZE);
    imshow(matches_window, imageMatches);
    imwrite("resultat.png", imageMatches);



    /// Create a window and a trackbar
    namedWindow(transparency_window, WINDOW_AUTOSIZE);
    createTrackbar("Threshold: ", transparency_window, &thresh, max_thresh, interface);








    interface(0, 0);

    waitKey(0);
    return (0);
}
int main(int argc, char** argv)
{
  if(argc != 3)
  {
    return -1;
  }
  
  Mat img_object = imread(argv[1],1);
  Mat img_scene = imread(argv[2],1);
  //String ImageName = (argv[3]);
  
  if(!img_object.data || !img_scene.data)
  {
    cout << "--(!)Error leyendo imagenes " << endl;
    return -1;
  }
  
  int minHessian = 400;
  SurfFeatureDetector detector(minHessian);
  
  vector<KeyPoint>keypoints_object, keypoints_scene;
  detector.detect( img_object, keypoints_object );
  detector.detect( img_scene, keypoints_scene );
  
  //-- Step 2: Calculate descriptors (feature vectors)
  
  Mat descriptors_object, descriptors_scene;
  
  SurfDescriptorExtractor extractor;
  extractor.compute( img_object, keypoints_object, descriptors_object );
  extractor.compute( img_scene, keypoints_scene, descriptors_scene );
  
  //-- Step 3: Matching descriptor vectors using FLANN matcher
  FlannBasedMatcher matcher;
  
  vector< DMatch > matches;
  matcher.match( descriptors_object, descriptors_scene, matches );
  
  //////////////////////////////////////////////////////////////////////////////
  
  double max_dist = 0; double min_dist = 100;

  //-- Quick calculation of max and min distances between keypoints
  for( int i = 0; i < descriptors_object.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 );
  
  cout << "Initializing Good Matches" << endl;
  //-- Draw only "good" matches (i.e. whose distance is less than 3*min_dist )
  vector< DMatch > good_matches;
  
  for( int i = 0; i < descriptors_object.rows; i++ )
  { 
    if( matches[i].distance < 3*min_dist )
     { 
       good_matches.push_back( matches[i]); 
     }
  }
  
  Mat img_matches;
  namedWindow("Good Matches & Object detection", 0);
  drawMatches( img_object, keypoints_object, img_scene, keypoints_scene,
               good_matches, img_matches, Scalar::all(-1), Scalar(0,0,255),
               vector<char>() );
               
  //////////////////////////////////////////////////////////////////////////////
  cout << "Finding Object " << endl;
  //-- Localize the object
  vector<Point2f> obj;
  vector<Point2f> scene;
  
  for( int i = 0; i < good_matches.size(); i++ )
  {
    //-- Get the keypoints from the good matches
    obj.push_back( keypoints_object[ good_matches[i].queryIdx ].pt );
    scene.push_back( keypoints_scene[ good_matches[i].trainIdx ].pt );
  }
  
  Mat H = findHomography( obj, scene, CV_LMEDS );
  
  //-- Get the corners from the image_1 ( the object to be "detected" )
  vector<Point2f> obj_corners(4);
  obj_corners[0] = cvPoint(0,0); 
  obj_corners[1] = cvPoint( img_object.cols, 0);
  obj_corners[2] = cvPoint( img_object.cols, img_object.rows); 
  obj_corners[3] = cvPoint( 0, img_object.rows);
  vector<Point2f> scene_corners(4);
  
  perspectiveTransform( obj_corners, scene_corners, H);
  
  //-- Draw lines between the corners (the mapped object in the scene - image_2 )
  line( img_matches, scene_corners[0] + Point2f( img_object.cols, 0), 
                     scene_corners[1] + Point2f( img_object.cols, 0), Scalar(0, 255, 0), 4 );
  line( img_matches, scene_corners[1] + Point2f( img_object.cols, 0), 
                     scene_corners[2] + Point2f( img_object.cols, 0), Scalar( 0, 255, 0), 4 );
  line( img_matches, scene_corners[2] + Point2f( img_object.cols, 0), 
                     scene_corners[3] + Point2f( img_object.cols, 0), Scalar( 0, 255, 0), 4 );
  line( img_matches, scene_corners[3] + Point2f( img_object.cols, 0), 
                     scene_corners[0] + Point2f( img_object.cols, 0), Scalar( 0, 255, 0), 4 );
  
  //-- Show detected matches
  imwrite("../data/Example.jpg",img_matches );
  imshow( "Good Matches & Object detection", img_matches );
  cout << "Write image " << endl;
  
  waitKey(0);
  return 0;
}
Exemple #24
0
int main(int argc, char** argv) {
  gval_debug_init();

  // get options
  int showhelp = 0;
  unsigned int n_cluster = 0;

  int opt;
  while ((opt = getopt(argc, argv, "k:h")) != -1) {
    switch (opt) {
      case 'h':
        showhelp = 1;
        break;
      case 'k':
        n_cluster = atoi(optarg);
        break;
      default:
        showhelp = 1;
        break;
    }
  }

  if (showhelp || n_cluster <= 0 || argc - optind < 2) {
    fprintf(stderr, "Usage: %s -k n_cluster input_dir output\n", argv[0]);
    return EXIT_SUCCESS;
  }

  path p(argv[optind]);
  if (!exists(p) || !is_directory(p)) {
    fprintf(stderr, "%s is not a directory\n", argv[optind]);
    return EXIT_FAILURE;
  }

  BOWKMeansTrainer bow(n_cluster);

  directory_iterator dir_end;
  for (directory_iterator i(p); i != dir_end; i++) {
    if (i->path().extension() == DESCRIPTORS_EXT) {
      FILE* in = fopen(i->path().c_str(), "r");
      assert(in);
      int counter = 0;
      int nempty = 0;
      Mat* desc = (Mat*) gval_read_cvmat(in);
      while (desc != NULL) {
        counter++;
        if (!desc->empty()) {
          nempty++;
          bow.add(desc->clone());
        }
        gval_free_cvmat(desc);
        desc = (Mat*) gval_read_cvmat(in);
      }
      fclose(in);
      fprintf(stderr, "Read from file %s (%d/%d)\n",
          i->path().c_str(), nempty, counter);
    }
  }

  fprintf(stderr, "Clustering (%d descriptors, %d clusters)...",
      bow.descripotorsCount(), n_cluster);
  Mat voc = bow.cluster();
  fprintf(stderr, " Done\n");

  fprintf(stderr, "Counting document frequency...");
  int* dfcounter = (int*) calloc(n_cluster, sizeof(int));
  vector<Mat> all = bow.getDescriptors();
  FlannBasedMatcher matcher;
  matcher.add(vector<Mat>(1, voc));
  for (vector<Mat>::const_iterator it = all.begin();
      it != all.end(); it++) {
    vector<int> ct(n_cluster, 0);
    vector<DMatch> matches;
    matcher.match(*it, matches);
    for (vector<DMatch>::const_iterator jt = matches.begin();
        jt != matches.end(); jt++) {
      assert(jt->trainIdx >= 0 && jt->trainIdx < n_cluster);
      ct[jt->trainIdx] = 1;
    }

    for (int j = 0; j < n_cluster; j++) {
      dfcounter[j] += ct[j];
    }
  }
  int dtotal = all.size();
  fprintf(stderr, " Done\n");

  FILE* out = fopen(argv[optind + 1], "w");
  assert(out);
  gval_write_cvmat(&voc, out);
  fwrite(dfcounter, sizeof(int), n_cluster, out);
  fwrite(&dtotal, sizeof(int), 1, out);

  // debug
  fprintf(stderr, "total:%d\n", dtotal);
  for (int j = 0; j < n_cluster; j++) {
    fprintf(stderr, "%d:%d\n", j, dfcounter[j]);
  }

  fclose(out);
  fprintf(stderr, "Written to %s\n", argv[optind + 1]);

  free(dfcounter);

  return EXIT_SUCCESS;
}
/**
 * @function main
 * @brief Main function
 */
int main( int argc, char** argv )
{
 // if( argc != 3 )
 // { readme(); return -1; }

  Mat img_1 = imread( "/home/mac/Documents/PROJECT/SIFT/a.JPG", CV_LOAD_IMAGE_GRAYSCALE );
  Mat img_2 = imread( "/home/mac/Documents/PROJECT/SIFT/r.JPG", CV_LOAD_IMAGE_GRAYSCALE );

  if( !img_1.data || !img_2.data )
  { std::cout<< " --(!) Error reading images " << std::endl; return -1; }

  //-- Step 1: Detect the keypoints using SURF Detector
  int minHessian = 400;

  //SurfFeatureDetector detector( minHessian );
  cv::SiftFeatureDetector detector;
  std::vector<KeyPoint> keypoints_1, keypoints_2;

  detector.detect( img_1, keypoints_1 );
  detector.detect( img_2, keypoints_2 );

  //-- Step 2: Calculate descriptors (feature vectors)
  SurfDescriptorExtractor extractor;

  Mat descriptors_1, descriptors_2;

  extractor.compute( img_1, keypoints_1, descriptors_1 );
  extractor.compute( img_2, keypoints_2, descriptors_2 );

  //-- Step 3: Matching descriptor vectors using FLANN matcher
  FlannBasedMatcher matcher;
  std::vector< DMatch > matches;
  matcher.match( descriptors_1, descriptors_2, matches );

  double max_dist = 0; double min_dist = 100;

  //-- Quick calculation of max and min distances between keypoints
  for( int i = 0; i < descriptors_1.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 2*min_dist,
  //-- or a small arbitary value ( 0.02 ) in the event that min_dist is very
  //-- small)
  //-- PS.- radiusMatch can also be used here.
  std::vector< DMatch > good_matches;

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

  //-- Draw only "good" matches
  Mat img_matches;
  drawMatches( img_1, keypoints_1, img_2, keypoints_2,
               good_matches, img_matches, Scalar::all(-1), Scalar::all(-1),
               vector<char>(), DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS );

  //-- Show detected matches
  imshow( "Good Matches", img_matches );

  for( int i = 0; i < (int)good_matches.size(); i++ )
  { printf( "-- Good Match [%d] Keypoint 1: %d  -- Keypoint 2: %d  \n", i, good_matches[i].queryIdx, good_matches[i].trainIdx ); }

  waitKey(0);

  return 0;
}
Exemple #26
0
void imageCallback(const sensor_msgs::ImageConstPtr& msg)
	{	

	
	if (count1 ==0)
		{

		cv_bridge::CvImagePtr cv_ptr;
		try
		    {
		      cv_ptr = cv_bridge::toCvCopy(msg, sensor_msgs::image_encodings::BGR8);
		    }
		    catch (cv_bridge::Exception& e)
		    {
		      ROS_ERROR("cv_bridge exception: %s", e.what());
		      return;
		    }
			img_1 = cv_ptr->image;	
			imageToDraw = img_1;
                        count1++;
			img_tot=img_1; 
		}


	else
		{
			
		cv_bridge::CvImagePtr cv_ptr;
		try
		    {
		      cv_ptr = cv_bridge::toCvCopy(msg, sensor_msgs::image_encodings::BGR8);
		    }
		    catch (cv_bridge::Exception& e)
		    {
		      ROS_ERROR("cv_bridge exception: %s", e.what());
		      return;
		    }
   
			img_2 = cv_ptr->image;

   
			  if( !img_1.data || !img_2.data )
			  { std::cout<< " --(!) Error reading images " << std::endl;}

			// canny detection

			//dst.create(img_1.size(), img_1.type() );
			
    			namedWindow( window_name, CV_WINDOW_AUTOSIZE );

 			 /// Create a Trackbar for user to enter threshold
  			createTrackbar( "Min Threshold:", window_name, &lowThreshold, max_lowThreshold, CannyThreshold1 );

 			/// Show the image
 			CannyThreshold1(0, 0);
			CannyThreshold2(0, 0); 
			
			//img_1 = detected_edges_1;
			//img_2 = detected_edges_2;


			  //-- Step 1: Detect the keypoints using SURF Detector
			  int minHessian = 400;

			  SurfFeatureDetector detector( minHessian );

			  std::vector<KeyPoint> keypoints_1, keypoints_2;

			  detector.detect( img_1, keypoints_1 );
			  detector.detect( img_2, keypoints_2 );

			  //-- Step 2: Calculate descriptors (feature vectors)
			  SurfDescriptorExtractor extractor;

			  Mat descriptors_1, descriptors_2;

			  extractor.compute( img_1, keypoints_1, descriptors_1 );
			  extractor.compute( img_2, keypoints_2, descriptors_2 );

			  //-- Step 3: Matching descriptor vectors using FLANN matcher
			  FlannBasedMatcher matcher;
			  std::vector< DMatch > matches;
			  matcher.match( descriptors_1, descriptors_2, matches );

			  double max_dist = 0; double min_dist = 100;

			  //-- Quick calculation of max and min distances between keypoints
			  for( int i = 0; i < descriptors_1.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 2*min_dist,
			  //-- or a small arbitary value ( 0.02 ) in the event that min_dist is very
			  //-- small)
			  //-- PS.- radiusMatch can also be used here.
			  std::vector< DMatch > good_matches;
			  std::vector<KeyPoint> good_keypoints_1, good_keypoints_2;

			  for( int i = 0; i < descriptors_1.rows; i++ )
			  { if( matches[i].distance <= max(3*min_dist, 0.0) )
			    { good_matches.push_back( matches[i]); 
			      good_keypoints_1.push_back(keypoints_1[i]);			     
			      good_keypoints_2.push_back(keypoints_2[i]);
			     }
			  }

			  //-- Draw only "good" matches
			  Mat img_matches;
			  drawMatches( img_1, keypoints_1, img_2, keypoints_2,
				       good_matches, img_matches, Scalar::all(-1), Scalar::all(-1),
				       vector<char>(), DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS );

			  //-- Show detected matches
			  imshow( "Good Matches", img_matches );
			
			//float deltax, deltay;
                         float deltax[(int)good_matches.size()], deltay[(int)good_matches.size()];
			 float sum_deltax=0, sum_deltay=0;

			  for( int i = 0; i < (int)good_matches.size(); i++ )
			  { 
			   
			   // printf( "-- Good Match [%d] Keypoint 1: %d  -- Keypoint 2: %d  \n", i, good_matches[i].queryIdx, good_matches[i].trainIdx );
			   // cout << "-- Good Match Keypoint 1:" << keypoints_1[good_matches[i].queryIdx].pt.x << endl;
   			   // cout << "-- Good Match Keypoint 2:" << keypoints_2[good_matches[i].trainIdx].pt.x << endl;
				
				deltax[i] = keypoints_2[good_matches[i].trainIdx].pt.x - keypoints_1[good_matches[i].queryIdx].pt.x;
				deltay[i] = keypoints_2[good_matches[i].trainIdx].pt.y - keypoints_1[good_matches[i].queryIdx].pt.y;

			  sum_deltax=+deltax[i];
			  sum_deltay=+deltay[i];
		

			  }

			float av_deltax = sum_deltax/(int)good_matches.size();
			float av_deltay = sum_deltay/(int)good_matches.size();

			float av_deltax2 = 0, av_deltay2 =0;

			cout << "before: av_deltax " << av_deltax << " av_deltay " << av_deltay << endl;
			
			int count2=0;

			for( int i = 0; i < (int)good_matches.size(); i++ )
			  {
			  if ((abs(deltax[i]-av_deltax) < 50 ) & (abs(deltay[i]-av_deltay)<50))
			  	{
				av_deltax2 =+deltax[i];
				av_deltay2 =+deltay[i];
				count2++;	      			
				}
			  }
			
			if (count2>0)
			{av_deltax2 = -av_deltax2/count2;
			 av_deltay2 = -av_deltay2/count2;
			cout << "after: av_deltax " << av_deltax << " av_deltay " << av_deltay << endl;
			}
			
			else
			{cout << "ATTENZIONE:keeping the old value " << endl;
			av_deltax2=0;
			av_deltay2=0;}
			
			 Pt_new.x=Pt_old.x+av_deltax2;
			 Pt_new.y=Pt_old.y+av_deltay2;

			cout << "Pt_new.x " << Pt_new.x << " Pt_old.x " << Pt_old.x << endl;
			
			line(imageToDraw, Pt_new, Pt_old, Scalar(255, 255, 255), 2);
			
			imshow( "Trajectory", imageToDraw );

			//Stitcher stitcher = Stitcher::createDefault(); 
	
			//Mat rImg;

			//vector< Mat > vImg; 

			//vImg.push_back(img_1);  
 			//vImg.push_back(img_2);  

			//Stitcher::Status status = stitcher.stitch(vImg, rImg);
			//if (Stitcher::OK == status)   
 			//imshow("Stitching Result",rImg);  
  			//else  
  			//printf("Stitching fail.");  

			 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( keypoints_1[ good_matches[i].queryIdx ].pt );
			 scene.push_back( keypoints_2[ good_matches[i].trainIdx ].pt );
			 }
			 
			// Find the Homography Matrix
			 Mat H = findHomography( obj, scene, CV_RANSAC );
			 // Use the Homography Matrix to warp the images
			 cv::Mat result;
			 warpPerspective(img_1,result,H,cv::Size(img_1.cols+img_tot.cols,img_1.rows));
			 cv::Mat half(result,cv::Rect(0,0,img_tot.cols,img_tot.rows));
			 img_tot.copyTo(half);
			 imshow( "Result", result );


			


			Pt_old = Pt_new;
			img_1 = img_2;

		        waitKey(11);
		}
	}	
//SURF Extraction, with Flann Matcher
void surfAlgo (int, void*)
{
	int key=0, i=0;
	CvMemStorage *storage = cvCreateMemStorage(0);
	CvSeq *imageKeyPoints=0, *imageDescriptors = 0;
	vector<KeyPoint> keyPoints_orig, keyPoints_trans;
	Mat descriptor_orig, descriptor_trans;
	double max_dist=0;double min_dist=100;
	std::vector < DMatch > good_matches;
	
	FlannBasedMatcher matcher;
	std::vector<DMatch>matches;

	SurfFeatureDetector detector(1500);
	SurfDescriptorExtractor extractor;

	cvtColor (src_2,src_trans,CV_BGR2GRAY);
	cvtColor (src_1,src_orig,CV_BGR2GRAY);

	detector.detect(src_orig, keyPoints_orig);
	detector.detect(src_trans, keyPoints_trans);

	extractor.compute(src_orig, keyPoints_orig, descriptor_orig);
	extractor.compute(src_trans, keyPoints_trans, descriptor_trans);
	
	matcher.match(descriptor_orig, descriptor_trans, matches);
	
	for (int count=0;count<descriptor_orig.rows;count++)
	{
		double dist=matches[i].distance;
		if( dist < min_dist ) min_dist=dist;
		if (dist > max_dist) max_dist = dist;
	}

	
	for(int count = 0; count < descriptor_orig.rows; count++)
	{
		if( matches[count].distance < 3*min_dist )
			{
				good_matches.push_back( matches[count]);
			}
	}

	//drawKeypoints(src_trans, keyPoints_trans, src_trans, Scalar(0,0,255), DrawMatchesFlags::DRAW_RICH_KEYPOINTS);
	//drawKeypoints(src_orig, keyPoints_orig, src_orig, Scalar(255,0,0), DrawMatchesFlags::DRAW_RICH_KEYPOINTS);	
	
	//drawMatches ( src_orig, keyPoints_orig, src_trans, keyPoints_trans, matches, src_trans);

	drawMatches( src_orig, keyPoints_orig, src_trans, keyPoints_trans,good_matches,src_new,Scalar(0,0,255),Scalar(0,0,255),vector<char>(),DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS);

	std::vector<Point2f> obj;
	std::vector<Point2f> scene;

	for (int count=0; count<good_matches.size();count++)
	{
		obj.push_back(keyPoints_trans[ matches[count].queryIdx].pt);
		scene.push_back(keyPoints_orig[ matches[count].trainIdx].pt);
	}

/*	
 	Code work in progress

	Mat H = findHomography( obj, scene, CV_RANSAC );
	std::vector<Point2f> object_corners(4);
  	std::vector<Point2f> scene_corners(4);


	object_corners[0] = cvPoint (0,0);
       	object_corners[1] = cvPoint (src_trans.cols,0);
	object_corners[2]= cvPoint (src_trans.cols,src_trans.rows);
	object_corners[3] = cvPoint (0,src_trans.rows);

	perspectiveTransform( object_corners, scene_corners, H);

	line (src_new, scene_corners[0]+Point2f(src_trans.cols,0), scene_corners[1]+Point2f(src_trans.cols,0),Scalar(0,255,0),4);
	line (src_new, scene_corners[1]+Point2f(src_trans.cols,0), scene_corners[2]+Point2f(src_trans.cols,0),Scalar(0,255,0),4);
	line (src_new, scene_corners[2]+Point2f(src_trans.cols,0), scene_corners[3]+Point2f(src_trans.cols,0),Scalar(0,255,0),4);
	line (src_new, scene_corners[3]+Point2f(src_trans.cols,0), scene_corners[0]+Point2f(src_trans.cols,0),Scalar(0,255,0),4);
*/
	imwrite("/Users/brainwave/Desktop/testrun1.jpg",src_new);
	resize(src_new,src_new,Size(),0.3,0.3,CV_INTER_LINEAR);

	imshow(window_name, src_new);

}	
int main(int argc, char **argv) {
    if (argc != 3) {
        printUsage();
        return -1;
    }

    cv::Rect finalRect;
    vector<cv::Rect> boundingRects;
    vector<Point2f> tlPoints;
    vector<Point2f> brPoints;

    vidFileName = string(argv[1]);
    featFileName = string(argv[2]);

    // Get BOINC resolved file paths.
#ifdef _BOINC_APP_
    string resolved_vid_path;
    string resolved_feat_path;
    int retval = boinc_resolve_filename_s(vidFileName.c_str(), resolved_vid_path);
    if (retval) {
        cerr << "Error, could not open file: '" << vidFileName << "'" << endl;
        cerr << "Resolved to: '" << resolved_vid_path << "'" << endl;
        return false;
    }
    vidFileName = resolved_vid_path;

    retval = boinc_resolve_filename_s(featFileName.c_str(), resolved_feat_path);
    if (retval) {
        cerr << "Error, could not open file: '" << featFileName << "'" << endl;
        cerr << "Resolved to : '" << resolved_feat_path << "'" << endl;
        return false;
    }
    featFileName = resolved_feat_path;
#endif

    CvCapture *capture = cvCaptureFromFile(vidFileName.c_str());

    Mat descriptors_file;
    FileStorage infile(featFileName, FileStorage::READ);
    if (infile.isOpened()) {
        read(infile["Descriptors"], descriptors_file);
        infile.release();
    } else {
        cout << "Feature file " << featFileName << " does not exist." << endl;
        exit(-1);
    }
    cout << "Descriptors: " << descriptors_file.size() << endl;

    int framePos = cvGetCaptureProperty(capture, CV_CAP_PROP_POS_FRAMES);
    int total = cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_COUNT);

    double fps = cvGetCaptureProperty(capture, CV_CAP_PROP_FPS);
    int framesInThreeMin = (int)fps*180;

#ifdef _BOINC_APP_  
    boinc_init();
#endif

    cerr << "Video File Name: " << vidFileName << endl;
    cerr << "Feature File Name: " << featFileName << endl; 
    cerr << "Frames Per Second: " << fps << endl;
    cerr << "Frame Count: " << total << endl;
    cerr << "Number of Frames in Three Minutes: " << framesInThreeMin << endl;
//    cerr << "<slice_probabilities>" << endl;

    checkpoint_filename = "checkpoint.txt";

    if(read_checkpoint()) {
        if(checkpointVidFileName.compare(vidFileName)!=0 || checkpointFeatFileName.compare(featFileName)!=0) {
            cerr << "Checkpointed video or feature filename was not the same as given video or feature filename... Restarting" << endl;
        } else {
            cerr << "Continuing from checkpoint..." << endl;
        }
    } else {
        cerr << "Unsuccessful checkpoint read" << endl << "Starting from beginning of video" << endl;
    }

    skipNFrames(capture, percentages.size() * framesInThreeMin);
    framePos = cvGetCaptureProperty(capture, CV_CAP_PROP_POS_FRAMES);
    cerr << "Starting at Frame: " << framePos << endl;

    long start_time = time(NULL);

    while ((double)framePos/total < 1.0) {

        if (framePos % 10 == 0) {
            cout << "FPS: " << framePos/((double)time(NULL) - (double)start_time) << endl;
        }

        //cout << framePos/total << endl;
        Mat frame(cvarrToMat(cvQueryFrame(capture)));
        framePos = cvGetCaptureProperty(capture, CV_CAP_PROP_POS_FRAMES);

        SurfFeatureDetector detector(minHessian);

        vector<KeyPoint> keypoints_frame;

        detector.detect(frame, keypoints_frame);

        SurfDescriptorExtractor extractor;

        Mat descriptors_frame;

        extractor.compute(frame, keypoints_frame, descriptors_frame);

        cout << "keypoints detected: " << keypoints_frame.size() << endl;
        for (int i = 0; i < keypoints_frame.size(); i++) {
            cout << "\t" << keypoints_frame[i].pt.x << ", " << keypoints_frame[i].pt.y << " -- " << keypoints_frame[i].angle << " : " << keypoints_frame[i].size << " -- " << keypoints_frame[i].response << endl;
            cout << "\t\t(" << descriptors_frame.rows << ", " << descriptors_frame.cols << ") ";
            for (int j = 0; j < descriptors_frame.cols; j++) {
                cout << " " << descriptors_frame.at<float>(i,j);
            }
            cout << endl;
        }
        cout << endl;


        // Find Matches
        FlannBasedMatcher matcher;
        vector<DMatch> matches;
        matcher.match(descriptors_frame, descriptors_file, matches);

        double max_dist = 0;
        double min_dist = 100;
        double avg_dist = 0;

        for (int i=0; i<matches.size(); i++) {
            double dist = matches[i].distance;
            if(dist < min_dist) min_dist = dist;
            if(dist > max_dist) max_dist = dist;
        }

        //cout << "Max dist: " << max_dist << endl;
        cout << "Min dist: " << min_dist << endl;

        vector<DMatch> good_matches;

        for (int i=0; i<matches.size(); i++) {
            if (matches[i].distance <= 0.18 && matches[i].distance <= 2.0*min_dist) {
                good_matches.push_back(matches[i]);
                avg_dist += matches[i].distance;
            }
        }
        if (good_matches.size() > 0) {
        	avg_dist = avg_dist/good_matches.size();
        	cout << "Avg dist: " << avg_dist << endl;
        }

		// Localize object.
		vector<Point2f> matching_points;
		vector<KeyPoint> keypoints_matches;

		for (int i=0; i<good_matches.size(); i++) {
			keypoints_matches.push_back(keypoints_frame[good_matches[i].queryIdx]);
			matching_points.push_back(keypoints_frame[good_matches[i].queryIdx].pt);
		}

		// Code to draw the points.
		Mat frame_points;
#ifdef GUI
        drawKeypoints(frame, keypoints_matches, frame_points, Scalar::all(-1), DrawMatchesFlags::DEFAULT);
#endif

		//Get bounding rectangle.
		if (matching_points.size() == 0) {
			Point2f tlFrame(0, 0);
			Point2f brFrame(frame.cols, frame.rows);
			tlPoints.push_back(tlFrame);
			brPoints.push_back(brFrame);
		} else {
            cv::Rect boundRect = boundingRect(matching_points);
			
			//Calculate mean.
			Mat mean;
			reduce(matching_points, mean, CV_REDUCE_AVG, 1);
			double xMean = mean.at<float>(0,0);
			double yMean = mean.at<float>(0,1);
			
			//Calculate standard deviation.
			vector<int> xVals;
			vector<int> yVals;
			for (int i=0; i<matching_points.size(); i++) {
				xVals.push_back(matching_points[i].x);
				yVals.push_back(matching_points[i].y);
			}
			double xStdDev = standardDeviation(xVals, xMean);
			double yStdDev = standardDeviation(yVals, yMean);
			
			Point2f tlStdPoint(xMean-xStdDev/2, yMean+yStdDev/2);
			Point2f brStdPoint(xMean+xStdDev/2, yMean-yStdDev/2);
			
            cv::Rect stdDevRect(tlStdPoint, brStdPoint);

#ifdef GUI
			color = Scalar(0, 0, 255); // Blue, Green, Red
			rectangle(frame_points, boundRect.tl(), boundRect.br(), color, 2, 8, 0);
			color = Scalar(0, 255, 255); // Blue, Green, Red
			rectangle(frame_points, stdDevRect.tl(), stdDevRect.br(), color, 2, 8, 0);
#endif
			boundingRects.push_back(boundRect);
			tlPoints.push_back(boundRect.tl());
			brPoints.push_back(boundRect.br());
		}

		if (tlPoints.size() != 0) {
			
			// Calculate mean rectangle.
			Mat tlMean;
			Mat brMean;
			reduce(tlPoints, tlMean, CV_REDUCE_AVG, 1);
			reduce(brPoints, brMean, CV_REDUCE_AVG, 1);
			Point2f tlPoint(tlMean.at<float>(0,0), tlMean.at<float>(0,1));
			Point2f brPoint(brMean.at<float>(0,0), brMean.at<float>(0,1));
			
            cv::Rect averageRect(tlPoint, brPoint);
		
			// Calculate median rectangle.
			vector<int> tlxVals;
			vector<int> tlyVals;
			vector<int> brxVals;
			vector<int> bryVals;
			for (int i=0; i<tlPoints.size(); i++) {
				tlxVals.push_back(tlPoints[i].x);
				tlyVals.push_back(tlPoints[i].y);
				brxVals.push_back(brPoints[i].x);
				bryVals.push_back(brPoints[i].y);
			}
			int tlxMedian;
			int tlyMedian;
			int brxMedian;
			int bryMedian;
			tlxMedian = quickMedian(tlxVals);
			tlyMedian = quickMedian(tlyVals);
			brxMedian = quickMedian(brxVals);
			bryMedian = quickMedian(bryVals);
			//cout << "lt Median: " << tlxMedian << "," << tlyMedian << endl;
			//cout << "br Median: " << brxMedian << "," << bryMedian << endl;
			Point2i tlMedianPoint(tlxMedian, tlyMedian);
			Point2i brMedianPoint(brxMedian, bryMedian);

            cv::Rect medianRect(tlMedianPoint, brMedianPoint);			

#ifdef GUI
			color = Scalar(255, 0, 0); // Blue, Green, Red
			rectangle(frame_points, averageRect.tl(), averageRect.br(), color, 2, 8, 0);
			color = Scalar(0, 255, 0);
			rectangle(frame_points, medianRect.tl(), medianRect.br(), color, 2, 8, 0);
#endif

			finalRect = averageRect;
		}

		// Check for frames in three minutes mark.
		framesInThreeMin = 20;
		if (framePos != 0 && framePos % framesInThreeMin == 0.0) {
			double probability;
			if (tlPoints.empty() && brPoints.empty()) {
				probability = 0.0;
				
			} else {
				double frameDiameter = sqrt(pow((double)frame.cols, 2) * pow((double)frame.rows, 2));
				double roiDiameter = sqrt(pow((double)finalRect.width, 2) * pow((double)finalRect.height, 2));
				probability = 1-(roiDiameter/(frameDiameter*0.6));
			}
			if (probability < 0) probability = 0.0;
			percentages.push_back(probability);
#ifndef _BOINC_APP_
			cout << "Min Dist: " << min_dist << endl;
            cout << probability << endl;
#endif
			boundingRects.clear();
			tlPoints.clear();
			brPoints.clear();
		}

		// Update percent completion and look for checkpointing request.
#ifdef _BOINC_APP_
		boinc_fraction_done((double)framePos/total);

		if(boinc_time_to_checkpoint()) {
			cerr << "checkpointing" << endl;
			write_checkpoint();
			boinc_checkpoint_completed();
		}
#endif

#ifdef GUI
		imshow("SURF", frame_points);
		if(cvWaitKey(15)==27) break;
#endif
	}

	cerr << "<slice_probabilities>" << endl;
	for (int i=0; i<percentages.size(); i++) cerr << percentages[i] << endl;
	cerr << "</slice_probabilities>" << endl;

#ifdef GUI
    cvDestroyWindow("SURF");
#endif

    cvReleaseCapture(&capture);

#ifdef _BOINC_APP_
    boinc_finish(0);
#endif
    return 0;
}
/** @function main */
int main(  )

{
  // Apply SURF method to match images by camera in motion

  Mat img_object = imread("/home/hailong/Pictures/house_contour.png");//first input image location
  Mat img_scene = imread( "/home/hailong/Pictures/house_simulation_contour.png" );//second input image location

  if( !img_object.data || !img_scene.data )
  { std::cout<< " --(!) Error reading images " << std::endl; return -1; }

  //Detect the keypoints using SURF Detector
  int minhessian = 400;

  SurfFeatureDetector detector( minhessian );

  std::vector<KeyPoint> keypoints_object, keypoints_scene;

  detector.detect( img_object, keypoints_object );
  detector.detect( img_scene, keypoints_scene );

  //Calculate descriptors (feature vectors)
 SurfDescriptorExtractor extractor;

  Mat descriptors_object, descriptors_scene;

  extractor.compute( img_object, keypoints_object, descriptors_object );
  extractor.compute( img_scene, keypoints_scene, descriptors_scene );

  //Matching descriptor vectors using FLANN matcher
  FlannBasedMatcher matcher;
  std::vector< DMatch > matches;
  matcher.match( descriptors_object, descriptors_scene, matches );

  double max_dist = 0; double min_dist = 100;

  //Quick calculation of max and min distances between keypoints
  for( int i = 0; i < descriptors_object.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_object.rows; i++ )
  { if( matches[i].distance < 3*min_dist )
     { good_matches.push_back( matches[i]); }
  }

  Mat img_matches;
  drawMatches( img_object, keypoints_object, img_scene, keypoints_scene,
               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( keypoints_object[ good_matches[i].queryIdx ].pt );
    scene.push_back( keypoints_scene[ good_matches[i].trainIdx ].pt );
  }

  Mat H = findHomography( obj, scene, CV_RANSAC );

  //Get the corners from the image_1 ( the object to be "detected" )
  std::vector<Point2f> obj_corners(4);
  obj_corners[0] = cvPoint(0,0); obj_corners[1] = cvPoint( img_object.cols, 0 );
  obj_corners[2] = cvPoint( img_object.cols, img_object.rows ); obj_corners[3] = cvPoint( 0, img_object.rows );
  std::vector<Point2f> scene_corners(4);

  perspectiveTransform( obj_corners, scene_corners, H);

  //Draw lines between the corners (the mapped object in the scene - image_2 )
  line( img_matches, scene_corners[0] + Point2f( img_object.cols, 0), scene_corners[1] + Point2f( img_object.cols, 0), Scalar(0, 255, 0), 4 );
  line( img_matches, scene_corners[1] + Point2f( img_object.cols, 0), scene_corners[2] + Point2f( img_object.cols, 0), Scalar( 0, 255, 0), 4 );
  line( img_matches, scene_corners[2] + Point2f( img_object.cols, 0), scene_corners[3] + Point2f( img_object.cols, 0), Scalar( 0, 255, 0), 4 );
  line( img_matches, scene_corners[3] + Point2f( img_object.cols, 0), scene_corners[0] + Point2f( img_object.cols, 0), Scalar( 0, 255, 0), 4 );

  //Show detected matches
  imshow( "SURF Match Results", img_matches );

  waitKey(0);
  return 0;
  }
//
// Following an example from
// http:// ramsrigoutham.com/2012/11/22/panorama-image-stitching-in-opencv/
//
void calcHomographyFeature(const Mat& image1, const Mat& image2)
{
    static const char* difffeat = "Difference feature registered";

    Mat gray_image1;
    Mat gray_image2;
    // Convert to Grayscale
    if(image1.channels() != 1)
        cvtColor(image1, gray_image1, CV_RGB2GRAY);
    else
        image1.copyTo(gray_image1);
    if(image2.channels() != 1)
        cvtColor(image2, gray_image2, CV_RGB2GRAY);
    else
        image2.copyTo(gray_image2);

    //-- Step 1: Detect the keypoints using SURF Detector
    int minHessian = 400;

    SurfFeatureDetector detector(minHessian);

    std::vector<KeyPoint> keypoints_object, keypoints_scene;

    detector.detect(gray_image1, keypoints_object);
    detector.detect(gray_image2, keypoints_scene);

    //-- Step 2: Calculate descriptors (feature vectors)
    SurfDescriptorExtractor extractor;

    Mat descriptors_object, descriptors_scene;

    extractor.compute(gray_image1, keypoints_object, descriptors_object);
    extractor.compute(gray_image2, keypoints_scene, descriptors_scene);

    //-- Step 3: Matching descriptor vectors using FLANN matcher
    FlannBasedMatcher matcher;
    std::vector<DMatch> matches;
    matcher.match(descriptors_object, descriptors_scene, matches);

    double max_dist = 0; double min_dist = 100;

    //-- Quick calculation of max and min distances between keypoints
    for(int i = 0; i < descriptors_object.rows; i++)
    {
        double dist = matches[i].distance;
        if( dist < min_dist ) min_dist = dist;
        if( dist > max_dist ) max_dist = dist;
    }

    //-- Use only "good" matches (i.e. whose distance is less than 3*min_dist)
    std::vector<DMatch> good_matches;

    for(int i = 0; i < descriptors_object.rows; i++) {
        if(matches[i].distance < 3*min_dist) {
            good_matches.push_back( matches[i]);
        }
    }
    std::vector< Point2f > obj;
    std::vector< Point2f > scene;

    for(size_t i = 0; i < good_matches.size(); i++)
    {
        //-- Get the keypoints from the good matches
        obj.push_back( keypoints_object[ good_matches[i].queryIdx ].pt );
        scene.push_back( keypoints_scene[ good_matches[i].trainIdx ].pt );
    }

    // Find the Homography Matrix
    Mat H = findHomography( obj, scene, CV_RANSAC );
    // Use the Homography Matrix to warp the images
    Mat result;
    Mat Hinv = H.inv();
    warpPerspective(image2, result, Hinv, image1.size());

    cout << "--- Feature method\n" << H << endl;
    
    Mat imf1, resf;
    image1.convertTo(imf1, CV_64FC3);
    result.convertTo(resf, CV_64FC3);
    showDifference(imf1, resf, difffeat);
}