Filter OpenCV Mat for NAN values

As noted by user pSoLT, if you want to determine which values are NaN, simply compare the matrix with itself. For those elements that are not equal, those would be considered as NaN by the standard definition. You can create a new mask using that logic:

cv::Mat mask = cv::Mat(mat != mat);

mat here would be a matrix that contains NaN values and mask will be a CV_8UC1 (i.e. uchar) type matrix with each element being 0xFF if a value is NaN and 0x00 otherwise.

This post on OpenCV forums may also help: http://answers.opencv.org/question/2221/create-a-mask-for-nan-cells/


Edit (as of April 23, 2020)

As mentioned in the comments as well as one of the answers in this post, the above Boolean expression is buggy and can result in inconsistent behaviour. This is due to certain optimisation decisions that OpenCV makes. Please see this Github issue: https://github.com/opencv/opencv/issues/16465

The solution to this is to use cv::patchNaNs() to address this problem, which converts values that are NaN to a specific number.

To replicate creating the mask in the question, note that patchNaNs performs an in-place replacement of the values, so you would have to make two copies of the image, use the patchNaNs to set the NaN values to a distinct value per image then check to see the occurrence of both values at the same locations at the same time. In other words:

cv::Mat mat1 = mat.clone();
cv::Mat mat2 = mat.clone();
cv::patchNaNs(mat1, 128);
cv::patchNaNs(mat2, 200);
cv::Mat mask = mat1 == 128 & mat2 == 200;

mask will give you the results as expected in the original version of this answer.


I am posting this answer to be a reference for those who may be searching for how to filter out the nan's from a matrix.

Although it may not be the precise answer to your question, if you want to filter out those nan indices, there is a quick and easy way to do it.

In my case, I had a zero by zero division which ended up nans in my float matrix. To set those nan's to another value (in my case 0), the following method can be used:

cv::patchNaNs(mat, 0.0);

This method finds and replaces the nan indices with the given value.

Tags:

C++

Opencv

Nan

Mat