2012-06-15 11 views
5

Estoy tratando de detectar un objeto del siguiente código que involucra el detector de surf, no quiero dibujar coincidencias, quiero dibujar un rectángulo alrededor del objeto detectado, pero de alguna manera no puedo obtener la Homografía correcta, por favor, ¿alguien puede señalar dónde estoy yendo mal?Dibujando rectángulo alrededor del objeto detectado usando SURF

#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

alguna manera incapaces de qué manera? ¿No estás obteniendo suficientes coincidencias, la homografía calculada es simplemente errónea? tal vez tienes algunos partidos fuera de los objetos? – penelope

+0

@penelope las coincidencias son lo suficientemente buenas, pero el rectángulo que se supone que está alrededor del objeto no está cerca, así que supongo que estoy calculando las coordenadas incorrectas. – sum2000

Respuesta

4

Si desea ver las dos imágenes con un rectángulo delimitador para el segundo alrededor del objeto detectado es necesario utilizar img_matches matriz y no imagen cuando se dibuja las líneas.

Si desea ver sólo la imagen con el objeto marcado y no el par de imágenes (como se define por las líneas de dibujo en imagen), sólo tiene que cambiar el código para:

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);

y mostrar la imagen en una nueva ventana

imshow("Result", image);

Cuestiones relacionadas