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

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

El algoritmo hash de percepción genera una cadena de "huellas dactilares" para cada imagen y luego compara 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 abandonar las diferencias de imagen causadas por diferentes tamaños/proporciones;

2. color: reduce la imagen reducida, Convierte a 64 niveles de escala de grises, es decir, todos los píxeles tienen un total de **** y solo 64 colores;

3. valores de escala de grises de los 64 píxeles;

4. Compare el valor de gris de los píxeles: compare el valor de gris de cada píxel con el valor promedio. Si es mayor o igual que el valor promedio, será. se registra como 1, y si es menor que el valor promedio, se registrará como 0

5. Calcule el valor hash: Calcule el valor Hash de todos los píxeles. Calcule el valor hash: los resultados de la comparación del paso anterior se combinan para formar un entero de 64 bits, que es la huella digital de la imagen. El orden de las combinaciones no importa, solo asegúrate de que todas las imágenes estén en el mismo orden;

6. Una vez que tengas la huella digital, puedes comparar diferentes imágenes para ver cuántos de los 64 bits son. diferente. 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 excede 5, las dos imágenes son similares; si el número es mayor que 10, las imágenes son 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 strSrcImageName = "src.jpg";

cv::Mat matSrc, matSrc1, matSrc2

matSrc = cv::imread; (strSrcImageName, CV_LOAD_IMAGE_COLOR );

CV_Assert(matSrc.channels() == 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: :Tamaño(2177 , 3233), 0, 0, cv::INTER_LANCZOS4);

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::resize(matSrc2, matDst2, cv::Tamaño(8, 8), 0, 0, cv::INTER_CUBIC)cvtColor(matDst2, matDst2, CV_BGR2GRAY); /p>

int iAvg1 = 0, iAvg2 = 0;

int arr1[64], arr2[64];

for (int i = 0; i lt; 8; i) {

uchar* datos1 = matDst1.ptrlt;uchargt;(i);

uchar* datos2 = matDst2.ptrlt;uchargt;(i);

int tmp = i * 8;

for (int j = 0; j lt; 8; j ) {

int tmp1 = tmp j;

arr1 [tmp1] = datos1[j] / 4 * 4;

arr2[tmp1] = datos2[j] / 4 * 4;

iAvg1 = arr1[tmp1 ];

p>

iAvg2 = arr2[tmp1];

}

}

iAvg1 /= 64; /p>

iAvg2 /= 64;

for (int i = 0; i lt; 64; i ) {

arr1[i] = (arr1[i] gt; = iPromedio1) ?1: 0

arr2[i] = (

arr2[i] gt; = iAvg2) ?1: 0;

}

int iDiffNum = 0;

for (int i = 0; i lt ; 64; i )

if (arr1[i] != arr2[i])

iDiffNum;

coutlt; "iDiffNum = "lt ;lt;iDiffNumlt;lt;endl;

if (iDiffNum lt;= 5)

coutlt;lt; "Las dos imágenes son muy similares.

"¡Las dos imágenes son muy similares!"lt;lt;endl;

else if (iDiffNum gt; 10)

coutlt;lt; "¡Son dos imágenes diferentes!" ; lt; endl;

else

coutlt; "Las dos imágenes son algo similares" lt; src.resize(matSrc, matSrc1, cv::Size(357, 419), 0, 0, cv::INTER_NEAREST);

//cv::flip(matSrc1, matSrc1, 1);

cv::resize(matSrc, matSrc2, cv::INTER_NEAREST);

//cv::flip(matSrc1, matSrc1, 1);

cv ::tamaño(2177, 3233):redimensionar(matSrc2, matDst2, cv::Tamaño(8, 8), 0, 0, cv::INTER_CUBIC);

cv::cvtColor(matDst1, matDst1 , CV_BGR2GRAY);

cv::cvtColor(matDst2, matDst2, CV_BGR2GRAY);

int iAvg1 = 0, iAvg2 = 0;

int arr1[ 64 ], arr2[64];

for (int i = 0; i lt; 8; i) {

uchar* data1 = matDst1.ptrlt; (i) ;

uchar* data2 = matDst2.ptrlt;uchargt;(i);

int tmp = i * 8;

for (int j = 0; j lt; 8 ; j ) {

int tmp1 = tmp j;

arr1[tmp1] = datos1[j] / 4 * 4;

arr2[tmp1] = datos2 [j] / 4 * 4;

iAvg1 = arr1[tmp1];

iAvg2 = arr2[tmp1];

}

}

iAvg1 /= 64;

iAvg2 /= 64;

para (int i = 0; i lt; 64; i ) {< / p>

arr1[i] = (arr1[i] gt; = iAvg1) ?1: 0;

arr2[i] = (arr2[i] gt; = iAvg2) ?1 : 0;

}

int iDiffNum = 0;

para (int i = 0; i lt; 64; i )

si (arr1[i] ! = arr2[i])

iDiffNum;

coutlt;lt; "iDiffNum = "lt;lt;iDiffNumlt;lt;endl;

if (iDiffNum) lt;= 5)

coutlt;lt; "Las dos imágenes son muy similares.

"¡Las dos imágenes son muy similares!"lt;lt;endl;

else if (iDiffNum gt; 10)

coutlt;lt; "¡Son dos imágenes diferentes!" ;lt;endl;

else

coutlt;lt; "¡Las dos imágenes son algo similares!"lt;lt;endl;

else