过滤OpenCV Mat以获取NAN值

时间:2017-01-20 08:36:01

标签: c++ opencv nan mat

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

cv::Mat_<real> mat = ...
cv::Mat_<uchar> mask = (mat == NAN);

无效,因为f == NAN始终为false,即使f已分配NAN也是如此。对于矩阵来说似乎没有isnan()的重载。

4 个答案:

答案 0 :(得分:7)

如用户pSoLT所述,如果要确定哪些值为NaN,只需将矩阵与自身进行比较即可。对于那些不相等的元素,这些元素将被视为NaN by the standard definition。您可以使用该逻辑创建新的掩码:

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

mat这里的矩阵包含NaN个值,mask将是CV_8UC1(即uchar)类型矩阵,每个元素都是{ {1}}如果值为0xFF,则为NaN

OpenCV论坛上的这篇文章也可以提供帮助:http://answers.opencv.org/question/2221/create-a-mask-for-nan-cells/

答案 1 :(得分:2)

我将这个答案发布给那些正在寻找如何从矩阵中过滤出nan的人的参考。

尽管这可能不是您问题的精确答案,但是如果您想过滤掉那些nan索引,那么有一种快速简便的方法。

在我的情况下,我有一个zero by zero division,在我的nan矩阵中以float结尾。要将那些nan设置为另一个值(在我的情况下为0),可以使用以下方法:

cv::patchNaNs(mat, 0.0);

此方法查找nan索引并将其替换为给定值。

答案 2 :(得分:1)

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

答案 3 :(得分:0)

根据github issue,一种解决方法是使用255 - (mat == mat)代替mat != mat(这通常应该可以工作,但是目前是一个错误)。 rayryeng's double-patch approach更强大,但带来了明显的性能缺陷。

下面是一个最小的工作示例:

#include <iostream>
#include <string>


#include <opencv2/opencv.hpp>

cv::Mat1b is_nan(cv::Mat mat)
{
    return 255 - (mat == mat);
}


int main()
{
    cv::Mat mat(5, 7, CV_32FC1);
    cv::randu(mat, cv::Scalar(-1), cv::Scalar(1));
    mat.at<float>(0,0) = std::nan("");
    mat.at<float>(4,5) = std::nan("");
    
    std::cout << mat << std::endl;
    std::cout << is_nan(mat) << std::endl;
    return 0;
}

输出

[nan, -0.60148162, -0.19788112, 0.62877017, -0.12573405, -0.5024206, 0.54621011;
 0.52418745, -0.38441104, 0.40486339, -0.043105587, 0.58438003, -0.82831377, -0.8498795;
 -0.67315322, -0.40044156, 0.81130785, 0.41937166, -0.70057499, 0.53087986, -0.75143719;
 -0.9925428, 0.10302717, 0.99639863, -0.68201572, -0.6776439, -0.92362136, -0.14827734;
 0.69225526, 0.77520895, -0.47057521, -0.4584339, 0.9053328, nan, 0.62043273]
[255,   0,   0,   0,   0,   0,   0;
   0,   0,   0,   0,   0,   0,   0;
   0,   0,   0,   0,   0,   0,   0;
   0,   0,   0,   0,   0,   0,   0;
   0,   0,   0,   0,   0, 255,   0]