【问题标题】:OpenCV mean function crashes with mask created from OpenCV threshold function?OpenCV 平均函数因 OpenCV 阈值函数创建的掩码而崩溃?
【发布时间】:2016-08-02 00:23:01
【问题描述】:

我对 OpenCV 很陌生,所以我想我犯了一些愚蠢的错误。

首先,我创建一个空的cv::mat 矩阵maskCV_8U 类型并用零填充它。然后,我通过使用cv::threshold 检查CV_32FC1 类型cv::mat 矩阵croppedDifferenceImage 中的值,用0 或255 填充矩阵。然后我使用mask 作为cv::mean 函数的参数。

cv::Mat mask = cv::Mat(croppedDifferenceImage.rows, croppedDifferenceImage.cols, CV_8U, cv::Scalar(0));
cv::threshold(croppedDifferenceImage, mask, 3.2, 255, CV_THRESH_BINARY);
double mean = cv::mean(croppedDifferenceImage, mask)[0];

但我总是遇到消息崩溃:

/build/buildd/opencv-2.4.8+dfsg1/modules/core/src/stat.cpp:565: error: (-215) mask.empty() || mask.type() == CV_8U in function mean

我做错了什么?

【问题讨论】:

  • 您使用 opencv 2.4.0 而不是 opencv 3 的任何原因?
  • 不知道有没有什么原因。我刚加入这个项目,对 opencv 也很陌生。
  • mask的类型是什么?根据threshold 的文档,目的地是“与 src 相同的大小和类型”。这意味着您将 CV_32FC1 作为掩码传递给 mean,这是无效的。
  • croppedDifferenceImage 是彩色图像还是灰度图像?
  • @mask "CV_32FC1 类型 cv::mat 矩阵croppedDifferenceImage 中的值" -- 单通道。另请注意,断言没有提及任何有关深度的内容。

标签: c++ opencv image-processing matrix threshold


【解决方案1】:

根据cv::threshold的文档:

double threshold(InputArray src, OutputArray dst, double thresh, double maxval, int type)

参数:

  • src – 输入数组(单通道、8 位或 32 位浮点)。
  • dst – 与 src 大小和类型相同的输出数组。

因此,既然你说croppedDifferenceImageCV_32FC1 类型,mask 输出变量将被重新分配并变成CV_32FC1 类型(不管你之前是否初始化它,因为它是一个不正确的类型)。

接下来将此掩码传递给cv::mean,这(根据断言)需要掩码:

  • 不能为空
  • 类型为 CV_8U(该特定检查与通道数无关)。

所以,为了解决这个问题,你需要转换(使用Mat::convertTo)阈值后的掩码:

cv::threshold(croppedDifferenceImage, mask, 3.2, 255, CV_THRESH_BINARY);
mask.convertTo(mask, CV_8U)
double mean = cv::mean(croppedDifferenceImage, mask)[0];

另请参阅 Miki's answer 以获取有关仅在 cv::Mat 上使用逻辑运算而不是调用 cv::threshold 的建议。

【讨论】:

    【解决方案2】:

    正如@Dan Mašek 在 cmets 中提到的,threshold 的结果将与输入具有相同的类型。因此,在您的情况下,由于您传递的是 CV_32FC1 矩阵,mask 的类型将是 CV_32FC1,这不是 mean 所期望的。

    基本上,您需要确保将CV_8UC1 类型的掩码传递给mean

    不要将mask 转换为正确的类型,因为您使用的是简单阈值,您可以使用Mat 逻辑运算,这将始终为您提供CV_8UC1 结果:

    Mat mask = croppedDifferenceImage > 3.2;
    double mean = cv::mean(croppedDifferenceImage, mask)[0];
    

    否则,您可以将mask 转换为正确的类型:

    Mat mask;
    threshold(croppedDifferenceImage, mask, 3.2, 255, CV_THRESH_BINARY);
    mask.convertTo(mask, CV_8U);
    
    double mean = cv::mean(croppedDifferenceImage, mask)[0];
    

    还请记住,您不需要预先分配 OpenCV 操作的结果(即OutputArray)。

    【讨论】:

      猜你喜欢
      • 2016-01-07
      • 2021-05-20
      • 2014-10-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多