¿Cómo utilizar el algoritmo NCC para determinar la similitud de dos imágenes en opencv?
Categoría: procesamiento de imágenes opencv 2014-12-25 21:27 180 personas leyeron comentarios (0) Recopilar informes.
Algoritmo de hash perceptual, su función es generar una cadena de "huellas dactilares" para cada imagen, y luego comparar las huellas dactilares de diferentes imágenes. Cuanto más cercanos son los resultados, más similares son las imágenes.
Pasos de implementación:
1. Reducir tamaño: Reduce la imagen a un tamaño de 8*8, con un total de 64 píxeles. La función de este paso es eliminar los detalles de la imagen, retener solo la información básica como estructura/luz y sombra, y descartar las diferencias de imagen causadas por diferentes tamaños/proporciones;
2. color: convierte la imagen reducida a 64 niveles de escala de grises, es decir, todos los píxeles tienen solo 64 colores;
3. Calcula el promedio: calcula el promedio en escala de grises de los 64 píxeles;
4. Comparar escalas de grises de píxeles: La escala de grises de cada píxel se compara con el valor promedio. Si es mayor o igual al valor promedio, se registrará como 1, y si es menor que el valor promedio, se registrará. registrado como 0;
5. Calcule el valor hash: combine los resultados de la comparación del paso anterior para formar un El entero de 64 bits es la huella digital de esta imagen. El orden de combinación no es importante, siempre y cuando todas las imágenes estén en el mismo orden;
6. Después de obtener la huella digital, puedes comparar diferentes imágenes para ver cuántos de los 64 bits son diferentes. Teóricamente, esto es equivalente a la "distancia de Hamming" (en teoría de la información, la distancia de Hamming entre dos cadenas de igual longitud es el número de caracteres diferentes en las posiciones correspondientes de las dos cadenas). Si el número de bits de datos diferentes no supera los 5, significa que las dos imágenes son muy similares; si es mayor que 10, significa que son dos imágenes diferentes.
El contenido anterior está tomado de: /blog/2011/07/principle_of_similar_image_search.html.
El siguiente es el código de prueba implementado con OpenCV:
[cpp] ¿Ver Plaincopyprint?
string str rcimagename = " src . jpg ";
cv::Mat matSrc, matSrc1, Mat src 2
mat src = CV::im; read(str sic imagename, CV_LOAD_IMAGE_COLOR);
CV_Assert(mat src. canales()= = 3);
cv::resize(matSrc , matSrc1, cv:: Tamaño ( 357, 419), 0, 0, cv:: INTER_NEAREST);
//cv:: flip (matSrc1, matSrc1, 1);
cv::resize(matSrc, matSrc2, cv::Size(2177, 3233), 0, 0, cv::INTER_lanc zos 4);
cv::Mat matDst1, matDst2
cv::resize( matSrc1, matDst1, cv::Tamaño(8, 8), 0, 0, cv::INTER_CUBIC);
cv::resize( matSrc2, matDst2, cv::Tamaño(8,8), 0,0,cv::INTER_CUBIC);
cv::cvtColor(matDst1, matDst1, CV_bgr 2 gris);
cv::cvtColor(matDst2, matDst2, CV_bgr 2 gris );
int iAvg1 = 0, iavg 2 = 0;
int arr1[64 ], arr 2[64];
for(int I = 0;i lt8;i) {
uchar * datos 1 = matdst 1. ptr lt;uchar gt㈠;
uchar * datos 2 = matdst 2 .
int tmp = I * 8;
for(int j = 0; j lt8 ;j ) {
int tmp 1 = tmp j; p>
arr 1[tmp 1]= datos 1[j]/4 * 4;
arr 2[tmp 1]= datos 2[j]/4 * 4;
iavg 1 = arreglo 1[tmp 1];
iavg 2 = arreglo 2[tmp 1]
}
}
iavg 1/= 64;
iavg 2/= 64;
para (int I = 0;ilt64;i) {
arr 1 [I]=(arr 1[I]gt;= iAvg1)? 1: 0;
arr 2[I]=(arr 2[I]gt;= iAvg2)? 1: 0;
}
int iDiffNum = 0;
for(int I = 0; i lt64; i )
si (
arr1[yo]! = arr2[i])
iDiffNum;
cout lt lt" iDiffNum = " lt ltiDiffNum lt ltendl
if(iDiffNum lt; = 5) p>
cout lt lt"¡Las dos imágenes son muy similares!" lt ltendl
else if(iDiffNum gt; 10)
cout lt lt"Son dos imágenes diferentes ! ” lt ltendl
Otro
cout lt “¡Las dos imágenes son algo similares!” lt ltendl
string str rcimagename = " src . jpg ";
cv::Mat matSrc, matSrc1, Mat src 2;
mat src = CV::im read(str sic imagename, CV_LOAD_IMAGE_COLOR);
CV_Assert( mat src . canales()== 3);
cv::resize(matSrc, matSrc1, cv::Size(357, 419), 0, 0, cv::INTER_NEAREST);
//cv::flip(matSrc1, matSrc1, 1);
cv::resize(matSrc, matSrc2, cv:: Tamaño(2177, 3233), 0, 0, cv: :INTER_lanc zos 4);
cv::Mat matDst1, matDst2
cv::resize(matSrc1, matDst1 ,cv::Tamaño(8,8),0,0, cv::INTER_CUBIC);
cv::resize(matSrc2, matDst2, cv::Size(8,8),0 , 0, cv::INTER_CUBIC);
cv ::cvtColor(matDst1, matDst1, CV_bgr 2 gris);
cv::cvtColor(matDst2, matDst2, CV _ bgr 2 gris);
int iAvg1 = 0, iavg 2); = 0;
int arr1[64], arr 2[64]
for(int I = 0;ilt8;i) {
uchar * datos 1 = matdst 1 . ptr lt;uchar gt㈠;
uchar * datos 2 = matdst 2 . >
for(int j = 0;j lt8;j) {
int tmp 1 = tmp j;
arr 1[tmp 1]= datos 1[j] /4 * 4;
arreglo 2[tmp 1]= datos 2[j]/4 * 4 ;
iavg 1 = arreglo 1[tmp 1];
iavg 2 = arreglo 2[tmp 1];
}
}
ia
vg 1/= 64;
iavg 2/= 64;
for(int I = 0;ilt64;i) {
arr 1[I ] =(arr 1[I] gt;= iAvg1)? 1: 0;
arr 2[I]=(arr 2[I]gt;= iAvg2)? 1: 0;
}
int iDiffNum = 0;
for(int I = 0; i lt64; i )
if (arr1[i]!= arr2[i])
iDiffNum;
cout lt lt" iDiffNum = " lt ltiDiffNum lt ltendl
if(iDiffNum lt; = 5)
cout lt lt "¡Las dos imágenes son muy similares!" lt "¡Son dos imágenes diferentes!"