Red de conocimiento informático - Material del sitio web - ¿Cómo utilizar el algoritmo NCC para determinar la similitud de dos imágenes en opencv?

¿Cómo utilizar el algoritmo NCC para determinar la similitud de dos imágenes en opencv?

Implementación del método de valor hash de OpenCV para el cálculo de similitud de imágenes

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;

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)

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!"