¿Cómo utilizar el algoritmo NCC en opencv para determinar la similitud de dos 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