我对OpenCV很新,所以我猜我犯了一些愚蠢的错误。
首先,我创建一个空cv::mat
矩阵mask
,CV_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
我做错了什么?
答案 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
,其中(根据断言)需要掩码:
因此,为了解决这个问题,您需要在阈值处理后转换(使用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
)。