Tengo dos instancias de cv :: Mat: m1 y m2. Son del mismo tipo y tamaño numérico. ¿Hay alguna función en OpenCV que devuelva si las matrices son idénticas (tienen todos los mismos valores)?cómo comprobar si dos matrices son idénticas en OpenCV
Respuesta
Use cv::compare combinado con cv::countNonZero.
pregunta Un SO que pueden ayudar aún más a OpenCV compare two images and get different pixels
Según lo mencionado por Acme, puede utilizar cv::compare
aunque no es tan limpia como se podría esperar.
En el siguiente ejemplo, se llama cv::compare
utilizando el !=
operator:
// Get a matrix with non-zero values at points where the
// two matrices have different values
cv::Mat diff = a != b;
// Equal if no elements disagree
bool eq = cv::countNonZero(diff) == 0;
Es de suponer que sería más rápido para recorrer simplemente mediante la comparación de los elementos sin embargo? Si conoce el tipo que usted podría utilizar la función STL equal:
bool eq = std::equal(a.begin<uchar>(), a.end<uchar>(), b.begin<uchar>());
'bool eq = cv :: countNonZero (a! = B) == 0;'. Creo que esto es razonablemente limpio. Lo más molesto es que tienes que invertir el operador de comparación en comparación con lo que realmente quieres saber ('! =' En lugar de '==') ya que no hay función 'countZero()'. – nobar
El cv :: Mat puede o no ser continuo, no estoy seguro de que el relleno de bytes por cada fila tenga el mismo valor. – StereoMatching
Sí, pero creo que los iteradores Mat se encargan de esto por usted? http://docs.opencv.org/modules/core/doc/basic_structures.html#mat-begin –
Como se ha mencionado por Acme y Tim, puede utilizar cv::compare
. Este es el código que utilizo para comparar mi cv::Mat
:
bool matIsEqual(const cv::Mat mat1, const cv::Mat mat2){
// treat two empty mat as identical as well
if (mat1.empty() && mat2.empty()) {
return true;
}
// if dimensionality of two mat is not identical, these two mat is not identical
if (mat1.cols != mat2.cols || mat1.rows != mat2.rows || mat1.dims != mat2.dims) {
return false;
}
cv::Mat diff;
cv::compare(mat1, mat2, diff, cv::CMP_NE);
int nz = cv::countNonZero(diff);
return nz==0;
}
Es importante resaltar que la función cv::countNonZero
only works with cv::Mat
of one channel, por lo que si es necesario comparar dos cv::Mat
imágenes, primero se necesita para convertir su cv::Mat
de esta manera:
Mat gray1, gray2;
cvtColor(InputMat1, gray1, CV_BGR2GRAY);
cvtColor(InputMat2, gray2, CV_BGR2GRAY);
donde InputMat1
y InputMat2
son el cv::Mat
desea comparar. Después de que se puede llamar a la función:
bool equal = matsEqual(gray1, gray2);
Tomé el código de este sitio: OpenCV: compare whether two Mat is identical
espero que esto ayude.
Al convertir las imágenes a escala de grises, pierde información y es posible que cree imágenes idénticas de 2 colores originalmente diferentes. – Antonio
Este es el código que utilizo para comparar genérica (no en función de las dimensiones o tipo de elementos) cv::Mat
casos:
bool matIsEqual(const cv::Mat Mat1, const cv::Mat Mat2)
{
if(Mat1.dims == Mat2.dims &&
Mat1.size == Mat2.size &&
Mat1.elemSize() == Mat2.elemSize())
{
if(Mat1.isContinuous() && Mat2.isContinuous())
{
return 0==memcmp(Mat1.ptr(), Mat2.ptr(), Mat1.total()*Mat1.elemSize());
}
else
{
const cv::Mat* arrays[] = {&Mat1, &Mat2, 0};
uchar* ptrs[2];
cv::NAryMatIterator it(arrays, ptrs, 2);
for(unsigned int p = 0; p < it.nplanes; p++, ++it)
if(0!=memcmp(it.ptrs[0], it.ptrs[1], it.size*Mat1.elemSize()))
return false;
return true;
}
}
return false;
}
No entiendo, ¿por qué cv::Mat
no tiene un operador ==
de acuerdo con este implementación.
Puedo usar este:
bool areEqual(const cv::Mat& a, const cv::Mat& b) {
cv::Mat temp;
cv::bitwise_xor(a,b,temp); //It vectorizes well with SSE/NEON
return !(cv::countNonZero(temp));
}
Si usted tiene que hacer esta operación varias veces, usted puede hacer esto en una clase, tienen temp
como miembro y evitar que la imagen que se asignarán cada vez. Detalle: make temp
mutable para que areEqual
pueda ser un método const
.
Tenga en cuenta que cv::countNonZero
only works with cv::Mat
of one channel. Es exagerado, pero en ese caso uno podría usar cv::split
para dividir cada canal en imágenes separadas y hacer cv::countNonZero
en ellas.
El siguiente funcionará también para matrices de múltiples canales:
bool isEqual = (sum(img1 != img2) == Scalar(0,0,0,0));
Desde sum acepta matrices con 1 a 4 canales, y devuelve un Scalar
, donde el elemento en [0] es el resultado de la suma para el primer canal, y así sucesivamente.
Otra forma utilizando una única función sería utilizar:
bool areIdentical = !cv::norm(img1,img2,NORM_L1);
Desde norma L1 se calcula como ∑I|img1(I)−img2(I)|
referencia: OpenCV norm
- 1. ¿Comprobar PHP si las matrices son idénticas?
- 2. Detectando si dos imágenes son visualmente idénticas
- 3. ¿Cómo puedo verificar si dos líneas son idénticas en vim?
- 4. jQuery: cómo comprobar si dos elementos son iguales.
- 5. ¿cómo puedo comprobar que dos sectores de matrices numpy son iguales (o se superponen)?
- 6. ¿Son estas 2 declaraciones idénticas?
- 7. ¿Cómo dos cadenas idénticas no se igualan?
- 8. Cómo comprobar openCV en Ubuntu 9.10
- 9. La multiplicación de matrices en OpenCV
- 10. Compara dos matrices, ¿hay elementos comunes entre las dos matrices?
- 11. ¿Cómo comprobar si dos objetos son del mismo tipo en Actionscript?
- 12. ¿Cómo puedo comprobar si dos elementos DOM envueltos en jQuery son iguales?
- 13. ¿Cómo comprobar si dos cadenas son una coincidencia parcial en C#?
- 14. ¿Cómo puedo verificar si dos matrices contienen los mismos elementos en Perl?
- 15. LINQ: compruebe si dos listas son iguales
- 16. ¿Cómo comprobar si una cadena contiene dos caracteres de asterisco?
- 17. Cómo comprobar si dos expresiones <Func <T, bool>> son las mismas
- 18. ¿Cómo comprobar estáticamente que dos razones son iguales?
- 19. ¿Cómo comparo dos matrices en scala?
- 20. Tiempo-complejidad de comprobar si dos conjuntos son iguales en Python
- 21. Comparando dos matrices en Matlab
- 22. ¿Cómo combinaría dos matrices en Objective-C?
- 23. ¿Determina si dos cadenas son similares en Javascript?
- 24. Cómo comprobar si las imágenes son de caché
- 25. ¿Cómo comprobar si un parámetro contiene dos subcadenas utilizando Mockito?
- 26. ¿Cómo mezclar dos matrices en Java?
- 27. Comprueba si dos elementos son los mismos
- 28. Shellscript acción si dos archivos son diferentes
- 29. Comprueba si dos vectores son iguales
- 30. cómo comprobar si IsNumeric
yo era la edición de la respuesta, porque era incompleto, pero debo decir que 'cv :: countNonZero' no funciona para imágenes multicanal. – Antonio