2012-06-15 3 views
5

Ich versuche, ein Objekt aus dem folgenden Code mit Surf-Detektor zu erkennen, ich möchte keine Übereinstimmungen zeichnen, ich möchte ein Rechteck um das erkannte Objekt zeichnen, aber irgendwie kann ich nicht bekomme richtige Homographie, bitte kann jemand darauf hinweisen, wo ich falsch liege.Rechteck um das erkannte Objekt mit SURF zeichnen

#include <stdio.h> 
#include <iostream> 
#include "opencv2/core/core.hpp" 
#include "opencv2/features2d/features2d.hpp" 
#include "opencv2/highgui/highgui.hpp" 
#include "opencv2/imgproc/imgproc.hpp" 
#include "opencv2/calib3d/calib3d.hpp" 

using namespace cv; 

int main() 
{ 
    Mat object = imread("sample.jpeg", CV_LOAD_IMAGE_GRAYSCALE); 

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

    //Detect the keypoints using SURF Detector 
    int minHessian = 500; 

    SurfFeatureDetector detector(minHessian); 
    std::vector<KeyPoint> kp_object; 

    detector.detect(object, kp_object); 

    //Calculate descriptors (feature vectors) 
    SurfDescriptorExtractor extractor; 
    Mat des_object; 

    extractor.compute(object, kp_object, des_object); 

    FlannBasedMatcher matcher; 

    VideoCapture cap(0); 

    namedWindow("Good Matches",0); 
    cvResizeWindow("Good Matches",800,800); 

    std::vector<Point2f> obj_corners(4); 

    //Get the corners from the object 
    obj_corners[0] = (cvPoint(0,0)); 
    obj_corners[1] = (cvPoint(object.cols,0)); 
    obj_corners[2] = (cvPoint(object.cols,object.rows)); 
    obj_corners[3] = (cvPoint(0, object.rows)); 

    char key = 'a'; 
    int framecount = 0; 
    while (key != 27) 
    { 
     Mat frame; 
     cap >> frame; 

     if (framecount < 5) 
     { 
      framecount++; 
      continue; 
     } 

     Mat des_image, img_matches; 
     std::vector<KeyPoint> kp_image; 
     std::vector<vector<DMatch > > matches; 
     std::vector<DMatch > good_matches; 
     std::vector<Point2f> obj; 
     std::vector<Point2f> scene; 
     std::vector<Point2f> scene_corners(4); 
     Mat H; 
     Mat image; 

     cvtColor(frame, image, CV_RGB2GRAY); 

     detector.detect(image, kp_image); 
     extractor.compute(image, kp_image, des_image); 

     matcher.knnMatch(des_object, 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]); 
      } 
     } 

     //Draw only "good" matches 
    // drawMatches(object, kp_object, image, kp_image, good_matches, img_matches, Scalar::all(-1), Scalar::all(-1), vector<char>(),DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS); 

     if (good_matches.size() >= 4) 
     { 
      for(int i = 0; i < good_matches.size(); i++) 
      { 
       //Get the keypoints from the good matches 
       obj.push_back(kp_object[ good_matches[i].queryIdx ].pt); 
       scene.push_back(kp_image[ good_matches[i].trainIdx ].pt); 
      } 

      H = findHomography(obj, scene, CV_RANSAC); 

      perspectiveTransform(obj_corners, scene_corners, H); 

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

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

     key = waitKey(1); 
    } 
    return 0; 
} 
+0

irgendwie nicht in der Lage, in welcher Weise? Bekommst du nicht genug gute Übereinstimmungen, ist die berechnete Homographie einfach falsch? vielleicht hast du ein paar Streichhölzer außerhalb der Objekte? – penelope

+0

@penelope die Übereinstimmungen sind gut genug, aber das Rechteck, das um das Objekt herum sein soll, ist nicht um es herum, also vermute ich, dass ich falsche Koordinaten berechne. – sum2000

Antwort

4

Wenn beide Bilder mit einem Begrenzungsrechteck an die zweite eine um die erfasste Objekt sehen möchten Sie img_matches Array und nicht Bild verwenden müssen, wenn man die Linien zeichnen.

Wenn Sie nur das Bild mit dem markierten Objekt sehen mögen und nicht das Paar von Bildern (wie Sie durch Ziehen von Linien in Bild definieren), brauchen Sie nur, um Ihren Code zu ändern:

line(image, scene_corners[0], scene_corners[1], Scalar(0, 255, 0), 4);

line(image, scene_corners[1], scene_corners[2], Scalar(0, 255, 0), 4);

line(image, scene_corners[2], scene_corners[3], Scalar(0, 255, 0), 4);

line(image, scene_corners[3], scene_corners[0], Scalar(0, 255, 0), 4);

und zeigen das Bild in einem neuen Fenster

imshow("Result", image);