是否有一种直接的方法来创建一个掩码,将cv::Mat_<double>
中的值与NAN进行比较?
cv::Mat_<real> mat = ...
cv::Mat_<uchar> mask = (mat == NAN);
不工作,因为f == NAN
总是错误的,即使f
被指定为NAN
。而且,对于矩阵来说,isnan()
似乎没有过载。
发布于 2017-01-20 08:47:15
正如用户pSoLT所指出的,如果您想确定哪些值是NaN
,只需将矩阵与其本身进行比较。对于那些不相等的元素,这些元素将被视为NaN
按照标准的定义。您可以使用该逻辑创建一个新的掩码:
cv::Mat mask = cv::Mat(mat != mat);
这里的mat
将是一个包含NaN
值的矩阵,而mask
将是一个CV_8UC1
(即uchar
)类型的矩阵,如果一个值是NaN
和0x00
,则每个元素都是0xFF
。
在OpenCV论坛上的这篇文章也可能有所帮助:http://answers.opencv.org/question/2221/create-a-mask-for-nan-cells/
编辑(截至2020年4月23日)
正如注释中提到的,以及本文中的一个答案,上述布尔表达式是错误的,可能导致不一致的行为。这是由于OpenCV做出的某些优化决策。请看这个Github问题:https://github.com/opencv/opencv/issues/16465
解决这一问题的方法是使用cv::patchNaNs()
来解决这个问题,它将NaN
值转换为特定的数字。
要在问题中复制创建掩码,请注意patchNaNs
执行对值的就地替换,因此您必须制作图像的两个副本,使用patchNaNs
将NaN
值设置为每个图像的不同值,然后检查两个值在同一位置同时出现的情况。换言之:
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
将给出这个答案的原始版本中所期望的结果。
https://stackoverflow.com/questions/41759247
复制相似问题