2011-09-04 25 views
17

Tengo una pregunta sobre objetos que coinciden con OpenCV. Estoy usando el algoritmo SURF implementado en opencv 2.3 para detectar primero las características en cada imagen, y luego extraer los descriptores de estas características. El problema al hacer coincidir usando Brute Force Matcher, no sé cómo juzgo que las dos imágenes coinciden o no, ¡así es como cuando estoy usando dos imágenes diferentes hay líneas entre los descriptores en las dos imágenes!OpenCV - Comparación de objetos utilizando descriptores SURF y BruteForceMatcher

Estas salidas de mi código, las dos imágenes -compararlas- son similares o diferentes, la imagen resultante indica que las dos imágenes coinciden.

La pregunta es: ¿cómo puedo distinguir entre las dos imágenes?

verdadera coincidencia:

http://store1.up-00.com/Jun11/hxM00286.jpg

Falso juego !! :

http://store1.up-00.com/Jun11/D5H00286.jpg

Mi código:

Mat image1, outImg1, image2, outImg2; 

// vector of keypoints 
vector<KeyPoint> keypoints1, keypoints2; 

// Read input images 
image1 = imread("C://Google-Logo.jpg",0); 
image2 = imread("C://Alex_Eng.jpg",0); 

SurfFeatureDetector surf(2500); 
surf.detect(image1, keypoints1); 
surf.detect(image2, keypoints2); 
drawKeypoints(image1, keypoints1, outImg1, Scalar(255,255,255), DrawMatchesFlags::DRAW_RICH_KEYPOINTS); 
drawKeypoints(image2, keypoints2, outImg2, Scalar(255,255,255), DrawMatchesFlags::DRAW_RICH_KEYPOINTS); 

namedWindow("SURF detector img1"); 
imshow("SURF detector img1", outImg1); 

namedWindow("SURF detector img2"); 
imshow("SURF detector img2", outImg2); 

SurfDescriptorExtractor surfDesc; 
Mat descriptors1, descriptors2; 
surfDesc.compute(image1, keypoints1, descriptors1); 
surfDesc.compute(image2, keypoints2, descriptors2); 

BruteForceMatcher<L2<float>> matcher; 
vector<DMatch> matches; 
matcher.match(descriptors1,descriptors2, matches); 

nth_element(matches.begin(), matches.begin()+24, matches.end()); 
matches.erase(matches.begin()+25, matches.end()); 

Mat imageMatches; 
drawMatches(image1, keypoints1, image2, keypoints2, matches, imageMatches, Scalar(255,255,255)); 

namedWindow("Matched"); 
imshow("Matched", imageMatches); 

cv::waitKey(); 
return 0; 

Respuesta

17

el problema estaba en utilizando sólo la fuerza bruta Matcher, he encontrado métodos para obtener un conjunto de buenos partidos entre dos puntos de vista en "OpenCV 2 Visión por Computador Programación de Aplicaciones Cookbook"

Ch9: Matching imágenes mediante consenso muestra aleatoria

Están utilizando K-vecinos más cercanos y RANSAC

Y gracias

+2

¡Este libro resulta muy útil! –

+1

Deberías aceptar tu respuesta. –

8

Para la eliminación de valores atípicos RANSAC + homografía es un buen método cuando se comparan dos imágenes planas.

La homografía es el modelo que RANSAC intentará usar para comparar puntos de ambas imágenes y encontrará el mejor conjunto de puntos que se ajuste mejor al modelo de proyección de la homografía (la transformación de un plano a otro).

cv::findHomography(srcPoints,dstPoints, RANSAC, status); 

La función anterior devolverá un estado de la matriz que tiene un 1 para los índices considerados inliers y 0 para los índices considerados anómalos, por lo que puede eliminar los valores atípicos mediante la comprobación de esta matriz de estado.

+1

El uso de 'LMEDS' (' Calib3d.LMEDS' en Android) me da mejores resultados, no sé por qué, en mi proyecto de curso, RANSAC en Matlab dio muy buenos resultados. ¡Pero definitivamente, la eliminación de elementos extraños es imprescindible! – Mustafa

3

Necesita modificar su Hessian, 2500 es demasiado. Pruebe 50. Cuando usa un gran Hessian, el resultado es una gran cantidad de puntos clave, lo que resulta innecesario. Otra información sobre SURF es que su marcador debe ser más rico, con más detalles.

Cuestiones relacionadas