c++ opencv segmentation-fault surf object-detection

c++ - OpenCV presenta detección y coincidencia-segfault en las coincidencias de dibujo



segmentation-fault surf (2)

Siguiendo este ejemplo ,
Intento crear una aplicación para reconocer objetos en un video.
Mi programa se compone de los siguientes pasos (vea el ejemplo de código de cada paso a continuación):

  1. Lea la imagen del objeto que se va a reconocer en un objeto cv::Mat .
  2. Detecta los puntos clave en el objeto y calcula los descriptores.
  3. Lea cada fotograma del video,
  4. Detectar puntos clave y calcular descriptores del marco,
  5. Relaciona los descriptores del marco con las descripciones del objeto,
  6. Dibujar resultados.

Problema: el paso 6 ° causa una falla de segmentación (ver el código a continuación).
Pregunta: ¿Qué lo causa y cómo puedo solucionarlo?

¡Gracias!

Notas:

  1. El programa se ejecuta para varios marcos antes de segfault. El bloqueo se produce en el cuadro 23, que es el primer fotograma del video que tiene cualquier contenido (es decir, que no es completamente negro).
  2. Al eliminar la línea de drawMatches(...); no hay choques
  3. Ejecutando en Windows 7, OpenCV 2.4.2, MinGW.

Intento de depuración:

Ejecutar el programa a través de gdb produce el siguiente mensaje:

Program received signal SIGSEGV, Segmentation fault. 0x685585db in _fu156___ZNSs4_Rep20_S_empty_rep_storageE () from c:/opencv/build/install/bin/libopencv_features2d242.dll

Paso 1 - lectura de la imagen del objeto:

Mat object; object = imread(OBJECT_FILE, CV_LOAD_IMAGE_GRAYSCALE);

Paso 2 - Detección de puntos clave en el objeto y descriptores de computación:

SurfFeatureDetector detector(500); SurfDescriptorExtractor extractor; vector<KeyPoint> keypoints_object; Mat descriptors_object; detector.detect(object , keypoints_object); extractor.compute(object, keypoints_object, descriptors_object);

Pasos 3-6:

VideoCapture capture(VIDEO_FILE); namedWindow("Output",0); BFMatcher matcher(NORM_L2,true); vector<KeyPoint> keypoints_frame; vector<DMatch> matches; Mat frame, output, descriptors_frame; while (true) { //step 3: capture >> frame; if(frame.empty()) { break; } cvtColor(frame,frame,CV_RGB2GRAY); //step 4: detector.detect(frame, keypoints_frame); extractor.compute(frame, keypoints_frame, descriptors_frame); //step 5: matcher.match(descriptors_frame, descriptors_object, matches); //step 6: drawMatches(object, keypoints_object, frame, keypoints_frame, matches, output); imshow("Output", output); waitKey(1); }

Captura de pantalla justo antes del segfault:

Cuadro 22 (completamente negro):

Cuadro 23 (en el cual ocurre segfault):


¿Has intentado ejecutar tu programa en un depurador?

Apenas adivinar, drawmatch es segfaulting cuando no hay partidos para dibujar ?? intente agregar if (!matches.empty()) antes de drawMatches . Por cierto, ¿estás seguro de que las matches se vacían antes de llamar a matcher.matches(...) ? Si no, debe hacerlo manualmente en cada iteración de bucle.


El problema estaba en el orden de los parámetros en drawMatches .
El orden correcto es:

drawMatches(frame, keypoints_frame, object, keypoints_object, matches, output);

Explicación:

En el paso 5, estoy usando el método de matcher objeto matcher :

matcher.match(descriptors_frame, descriptors_object, matches);

La firma de este método es

void match( const Mat& queryDescriptors, const Mat& trainDescriptors, CV_OUT vector<DMatch>& matches, const Mat& mask=Mat() ) const;

Lo que significa que las matches contienen coincidencias de trainDescriptors con queryDescriptors .
En mi caso, los descriptores de tren son del object y los descriptores de consulta son del frame , por lo que matches contiene coincidencias del object al frame .

La firma de drawMatches es

void drawMatches( const Mat& img1, const vector<KeyPoint>& keypoints1, const Mat& img2, const vector<KeyPoint>& keypoints2, const vector<DMatch>& matches1to2, ... );

Al llamar drawMatches con el orden incorrecto de los parámetros:

drawMatches(object, keypoints_object, frame, keypoints_frame, matches, output);

el método busca las coordenadas de las coincidencias en la imagen incorrecta, lo que puede provocar el intento de acceder a los píxeles "fuera de los límites"; Por lo tanto, la falla de segmentación.