OpenCV意味着功能崩溃与使用OpenCV阈值功能创建的掩码?

时间:2016-04-11 17:36:48

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

我对OpenCV很新,所以我猜我犯了一些愚蠢的错误。

首先,我创建一个空cv::mat矩阵maskCV_8U类型,并用零填充。然后我通过使用CV_32FC1检查cv::mat类型croppedDifferenceImage矩阵cv::threshold中的值,用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

我做错了什么?

2 个答案:

答案 0 :(得分:3)

根据cv::threshold的文件:

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

参数:

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

因此,由于您说croppedDifferenceImage的类型为CV_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的建议。

答案 1 :(得分:1)

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

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

由于您使用的是简单的阈值,因此您可以使用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)。