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.
因此,由于您说 croppedDifferenceImage
是 CV_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
的建议。
我是 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.
因此,由于您说 croppedDifferenceImage
是 CV_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
的建议。