2011-12-15 18 views
10

que estoy utilizando para compilar y ejecutar código de Features2D + Homography to find a known object tutorial, y yo estoy recibiendo este error de ejecucióncv OpenCV :: findHomography error de ejecución

OpenCV Error: Assertion failed (npoints >= 0 && points2.checkVector(2) == npoint 
s && points1.type() == points2.type()) in unknown function, file c:\Users\vp\wor 
k\ocv\opencv\modules\calib3d\src\fundam.cpp, line 1062 

. después de la depuración, encuentro que el programa se está bloqueando en la función findHomography.

Unhandled exception at 0x760ab727 in OpenCVTemplateMatch.exe: Microsoft C++ exception: cv::Exception at memory location 0x0029eb3c.. 

en el Introduction de OpenCV, el capítulo "cv espacio de nombres" dice que

Algunos de los nombres externos actuales o futuros OpenCV puede entrar en conflicto con STL u otras bibliotecas. En este caso, use los especificadores de espacio de nombres explícitos para resolver los conflictos de nombres:

Cambié mi código y uso en todas partes los especificadores explícitos del espacio de nombres, pero el problema no se solucionó. Si puede, ayúdeme en este problema, o diga qué función hace lo mismo que buscar Homografía y no bloquee el programa.

Y este es mi código

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

void readme(); 

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

    cv::Mat img_object = cv::imread(argv[1], CV_LOAD_IMAGE_GRAYSCALE); 
    cv::Mat img_scene = cv::imread(argv[2], CV_LOAD_IMAGE_GRAYSCALE); 

    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; 

    cv::SurfFeatureDetector detector(minHessian); 

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

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

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

    cv::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 
    cv::FlannBasedMatcher matcher; 
    std::vector<cv::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<cv::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]); } 
    } 

    cv::Mat img_matches; 
    cv::drawMatches(img_object, keypoints_object, img_scene, keypoints_scene, 
     good_matches, img_matches, cv::Scalar::all(-1), cv::Scalar::all(-1), 
     std::vector<char>(), cv::DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS); 

    //-- Localize the object 
    std::vector<cv::Point2f> obj; 
    std::vector<cv::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); 
    } 

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

    //-- Get the corners from the image_1 (the object to be "detected") 
    std::vector<cv::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<cv::Point2f> scene_corners(4); 

    cv::perspectiveTransform(obj_corners, scene_corners, H); 

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

    //-- Show detected matches 
    cv::imshow("Good Matches & Object detection", img_matches); 

    cv::waitKey(0); 
    return 0; 
} 

/** @function readme */ 
void readme() 
{ std::cout << " Usage: ./SURF_descriptor <img1> <img2>" << std::endl; } 
+1

No se ve como un problema de espacio de nombres. Si miras tu primer mensaje de error, dice que una afirmación ha fallado (probablemente para la función 'findHomography'): parece que al menos una de tus matrices de puntos de entrada para' findHomography' no tenía suficientes puntos en ella. ¿Puedes publicar un fragmento que muestre cómo usas 'findHomography' y cómo generas los puntos? –

+0

vea más arriba, edité mi pregunta – haykart

+1

Hmmm ... Pruebe 'std :: cout'ing' obj.size() 'y' scene.size() 'justo antes de hacer' findHomography' - quizás el optimizador pueda ' t encuentra cualquier buena coincidencia entre 'obj' y' scene' y así 'findHomography' no tiene suficiente para hacer los cálculos con. –

Respuesta

5

Hoy me encuentro con el mismo problema con este código de ejemplo. @ matemático-café estaba justo allí no se extrajeron características, por lo tanto obj y la escena estaban vacías. Reemplacé las imágenes de prueba y funcionó. A partir de las imágenes de estilo de textura, no puede extraer las características de SURF.

Otra forma es bajar el parámetro minHessianve.g. `int minHessian = 20;

o utilizar el detector característica RÁPIDO cambiando algunas líneas:

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

    FastFeatureDetector detector(minHessian); 
1

I tenían el mismo problema y me seguido la solución por MMH. Sólo escribir

cv::Mat H = cv::findHomography(cv::Mat(obj), cv::Mat(scene), CV_RANSAC); cv::perspectiveTransform(cv::Mat(obj_corners), cv::Mat(scene_corners), H);

resuelto el problema.

3

La respuesta real está dentro del mensaje de error:

npoints >= 0 && points2.checkVector(2) == npoints && points1.type() == points2.type() 

traducción legible por el hombre, tiene que cumplir con estas afirmaciones:

  • Su entrada debe tener un número positivo de puntos (en la práctica un findHomography necesita 4 o más puntos).

  • Su lista de puntos 'objeto' y 'escena' debe tener el mismo número de puntos.

  • Su lista de puntos 'objeto' y 'escena' debe tener el mismo tipo de puntos.

1

más probable es que el problema está aquí:

if(matches[i].distance < 3*min_dist) 

La desigualdad estricta no es lo que desea. Si min_dist == 0, una combinación muy buena, ignorará todos los puntos de distancia cero.Reemplace con:

if(matches[i].distance <= 3*min_dist) 

y debería ver buenos resultados para las imágenes que combinan bien.

Para salir con gracia, También me gustaría añadir, por ejemplo .:

if (good_matches.size() == 0) 
{ 
    std::cout<< " --(!) No good matches found " << std::endl; return -2; 
} 
1

es necesario agregar una condición antes de findHomography

if(obj.size()>3){ 
    ///-- Get the corners from the image_1 (the object to be "detected") 
    vector<Point2f> obj_corners(4); 
    obj_corners[0] = Point(0,0); obj_corners[1] = Point(img_object.cols, 0); 
    obj_corners[2] = Point(img_object.cols, img_object.rows); obj_corners[3] = Point(0, img_object.rows); 

    Mat H = findHomography(obj, scene,CV_RANSAC ); 
    perspectiveTransform(obj_corners, scene_corners, H); 
    ///-- Draw lines between the corners (the mapped object in the scene - image_2) 
    for(int i = 0; i < 4; ++i) 
     line(fram_tmp, scene_corners[i]+offset, scene_corners[(i + 1) % 4]+offset, Scalar(0, 255, 0), 4); 
} 
Cuestiones relacionadas