I have two instances of cv::Mat : m1 and m2. They are of the same numeric type and sizes. Is there any function in OpenCV that returns whether the matrices are identical (ha
Another way using a single function would be to use:
bool areIdentical = !cv::norm(img1,img2,NORM_L1);
Since L1 norm is calculated as ∑I|img1(I)−img2(I)|
reference: OpenCV norm
The problem of using cv::countNonZero
is that this function only works for one-channel images. If you want to work with multichannel images, you have to take care of each channel individually. The first step is to split an image into channels. As Antonio explained, you can use cv::split
function for this purpose. After splitting, you can use cv::countNonZero
for each channel and sum the results along all channels by using iteration. cv::Mat::channels
gives you the number of channels.
This is the code that I use to check whether two matrices are identical.
bool isEqual(cv::Mat firstImage, cv::Mat secondImage){
cv::Mat dst;
std::vector<cv::Mat>channels;
int count = 0;
cv::bitwise_xor(firstImage, secondImage, dst);
cv::split(dst, channels);
for (int ch = 0; ch<dst.channels();ch++){
count += cv::countNonZero(channels[ch]);
}
return count == 0 ? true : false;
}
This is the code I use to compare generic (not depending on dimensions or type of elements) cv::Mat
instances:
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;
}
I don't understand, why cv::Mat
does not have an operator ==
according to this implementation.