2012-04-04 11 views
8

Estoy tratando de implementar un programa que ingresará dos imágenes, una es una imagen de una caja sola y otra que incluye el cuadro en la escena. Básicamente, se supone que el programa busca puntos clave en estas dos imágenes y mostrará las imágenes con los puntos clave coincidentes. Eso es, al final, espero ver conectada una imagen adjunta de dos imágenes de entrada junto con sus puntos clave coincidentes. Mi código es el siguiente:Intentando unir dos imágenes usando tamizar en OpenCv, pero demasiadas coincidencias

#include <opencv2\opencv.hpp> 
#include <iostream> 

int main(int argc, const char* argv[]) { 
    cv::Mat input1 = cv::imread("input.jpg", 1); //Load as grayscale 
    //cv::cvtColor(input1,input1,CV_BGR2GRAY); 
    //second input load as grayscale 
    cv::Mat input2 = cv::imread("input2.jpg",1); 
    cv::SiftFeatureDetector detector; 
    //cv::SiftFeatureDetector 
    detector(
     1, 1, 
     cv::SIFT::CommonParams::DEFAULT_NOCTAVES, 
     cv::SIFT::CommonParams::DEFAULT_NOCTAVE_LAYERS, 
     cv::SIFT::CommonParams::DEFAULT_FIRST_OCTAVE, 
     cv::SIFT::CommonParams::FIRST_ANGLE); 
    std::vector<cv::KeyPoint> keypoints1; 
    detector.detect(input1, keypoints1); 
    // Add results to image and save. 
    cv::Mat output1; 
    cv::drawKeypoints(input1, keypoints1, output1); 
    cv::imshow("Sift_result1.jpg", output1); 
    cv::imwrite("Sift_result1.jpg",output1); 
    //keypoints array for input 2 
    std::vector<cv::KeyPoint> keypoints2; 
    //output array for ouput 2 
    cv::Mat output2; 
    //Sift extractor of opencv 
    cv::SiftDescriptorExtractor extractor; 
    cv::Mat descriptors1,descriptors2; 
    cv::BruteForceMatcher<cv::L2<float>> matcher; 
    cv::vector<cv::DMatch> matches; 
    cv::Mat img_matches; 
    detector.detect(input2,keypoints2); 
    cv::drawKeypoints(input2,keypoints2,output2); 
    cv::imshow("Sift_result2.jpg",output2); 
    cv::imwrite("Sift_result2.jpg",output2); 
    extractor.compute(input1,keypoints1,descriptors1); 
    extractor.compute(input2,keypoints2,descriptors2); 
    matcher.match(descriptors1,descriptors2,matches); 
    //show result 
    cv::drawMatches(input1,keypoints1,input2,keypoints2,matches,img_matches); 
    cv::imshow("matches",img_matches); 
    cv::imwrite("matches.jpg",img_matches); 
    cv::waitKey(); 
    return 0; 
} 

El problema es que hay dos muchas coincidencias de lo esperado. Traté de depurar el programa y busqué lo que está dentro de los vectores de los puntos clave, etc., todo parece estar bien, al menos creo que lo son, los puntos clave se detectaron con orientación, etc.

Estoy usando OpenCV v2.3 y revisé su documentación para los tipos de clases que estoy usando e intenté resolver el problema pero eso no funcionó. Estoy trabajando en esto durante 3 días, no fue una gran mejora.

Aquí hay una salida que obtengo de mi programa.

Debería haber eliminado la imagen.

Sé que no debería dar demasiadas coincidencias, porque he probado exactamente las mismas imágenes con otra implementación en matlab que era bastante buena.

Respuesta

6

En lugar de utilizar BruteForceMatcher intente utilizar FlannBasedMatcher y también calcule distancias máximas y mínimas entre los puntos clave para mantener solo las coincidencias adecuadas. Consulte "Feature Matching with FLANN" para ver un ejemplo.

+0

Gracias. El problema fue como dijiste, dibujando todos los partidos pero no solo los buenos. Ahora que estoy ordenando partidos y seleccionando el 15% con distancias mínimas. – bahti

+0

Espero que haya solucionado el problema. – MMH

+0

[Nuevo enlace] (http://docs.opencv.org/2.4/doc/tutorials/features2d/feature_flann_matcher/feature_flann_matcher.html) –

0

Tuve el mismo problema con SIFT. Utilicé knn matcher (K ​​= 3). y siguió el siguiente procedimiento iterativamente

{ 
Calculated best affine transform with least square method. 

Found out the transform for all keypoints in source image. 

Checked out MaxError and MinError. 

Points with Error near MaxError are removed from the matching list 
}