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 nan
s 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.