OpenCV 均值函数因从 OpenCV 阈值函数创建的掩码而崩溃?

OpenCV mean function crashes with mask created from OpenCV threshold function?

我是 OpenCV 的新手,所以我想我犯了一些愚蠢的错误。

首先,我创建了一个空的 cv::mat 矩阵 mask,类型为 CV_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

我做错了什么?

正如@Dan Mašek 在评论中提到的,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)。

根据cv::threshold的文档:

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

Parameters:

  • src – input array (single-channel, 8-bit or 32-bit floating point).
  • dst – output array of the same size and type as src.

因此,由于您说 croppedDifferenceImageCV_32FC1 类型,因此 mask 输出变量将被重新分配并成为 CV_32FC1 类型(与您无关之前初始化它,因为它是一个不正确的类型)。

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

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

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

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

另请参阅 ,了解有关仅对 cv::Mat 使用逻辑运算而不是调用 cv::threshold 的建议。