首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >过滤NAN值的OpenCV Mat

问过滤NAN值的OpenCV Mat
EN

Stack Overflow用户
提问于 2017-01-20 08:36:01
回答 4查看 10.9K关注 0票数 8

是否有一种直接的方法来创建一个掩码,将cv::Mat_<double>中的值与NAN进行比较?

代码语言:javascript
复制
cv::Mat_<real> mat = ...
cv::Mat_<uchar> mask = (mat == NAN);

不工作,因为f == NAN总是错误的,即使f被指定为NAN。而且,对于矩阵来说,isnan()似乎没有过载。

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2017-01-20 08:47:15

正如用户pSoLT所指出的,如果您想确定哪些值是NaN,只需将矩阵与其本身进行比较。对于那些不相等的元素,这些元素将被视为NaN 按照标准的定义。您可以使用该逻辑创建一个新的掩码:

代码语言:javascript
复制
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值设置为每个图像的不同值,然后检查两个值在同一位置同时出现的情况。换言之:

代码语言:javascript
复制
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将给出这个答案的原始版本中所期望的结果。

票数 12
EN

Stack Overflow用户

发布于 2020-03-19 03:34:56

我贴出这个答案是为了给那些正在寻找如何从矩阵中过滤掉nan的人提供参考。

虽然这可能不是你问题的准确答案,但是如果你想过滤掉那些nan指数,有一个快速而简单的方法。

在我的例子中,我有一个zero by zero division,它最终在我的float矩阵中得到了nan。要将这些nan设置为另一个值(在我的例子中是0),可以使用以下方法:

代码语言:javascript
复制
cv::patchNaNs(mat, 0.0);

此方法使用给定的值查找并替换nan索引。

票数 3
EN

Stack Overflow用户

发布于 2017-01-20 08:42:12

如果您想测试NaN的值,只需将其与自身进行比较。根据标准,NaN不等于任何其他数字,包括它本身,对于NaN,(fValue != fValue)应该是正确的。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/41759247

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档