是否有一种直接的方法来创建一个掩码,将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将给出这个答案的原始版本中所期望的结果。
发布于 2020-03-19 03:34:56
我贴出这个答案是为了给那些正在寻找如何从矩阵中过滤掉nan的人提供参考。
虽然这可能不是你问题的准确答案,但是如果你想过滤掉那些nan指数,有一个快速而简单的方法。
在我的例子中,我有一个zero by zero division,它最终在我的float矩阵中得到了nan。要将这些nan设置为另一个值(在我的例子中是0),可以使用以下方法:
cv::patchNaNs(mat, 0.0);此方法使用给定的值查找并替换nan索引。
发布于 2017-01-20 08:42:12
如果您想测试NaN的值,只需将其与自身进行比较。根据标准,NaN不等于任何其他数字,包括它本身,对于NaN,(fValue != fValue)应该是正确的。
https://stackoverflow.com/questions/41759247
复制相似问题