countNonZero 函数在 openCV 中给出断言错误
countNonZero function gives an assertion error in openCV
我尝试使用 countNonZero() 函数获得水平投影,如下所示。
Mat src = imread(INPUT_FILE, CV_LOAD_IMAGE_COLOR);
Mat binaryImage = src.clone();
cvtColor(src, src, CV_BGR2GRAY);
Mat horizontal = Mat::zeros(1,binaryImage.cols, CV_8UC1);
for (int i = 0; i<binaryImage.cols; i++)
{
Mat roi = binaryImage(Rect(0, 0, 1, binaryImage.rows));
horizontal.at<int>(0,i) = countNonZero(roi);
cout << "Col no:" << i << " >>" << horizontal.at<int>(0, i);
}
但是在调用countonZero()函数的那一行发生了错误。错误如下。
OpenCV Error: Assertion failed (src.channels() == 1 && func != 0) in cv::countNo
nZero, file C:\builds_4_PackSlave-win32-vc12-shared\opencv\modules\core\src\st
at.cpp, line 549
谁能指出错误?
顺便说一句,您可以使用 reduce
作为参数 CV_REDUCE_SUM
来计算水平投影。
一个最小的例子:
Mat1b mat(4, 4, uchar(0));
mat(0,0) = uchar(1);
mat(0,1) = uchar(1);
mat(1,1) = uchar(1);
// mat is:
//
// 1100
// 0100
// 0000
// 0000
// Horizontal projection, result would be a column matrix
Mat1i reducedHor;
cv::reduce(mat, reducedHor, 1, CV_REDUCE_SUM);
// reducedHor is:
//
// 2
// 1
// 0
// 0
// Vertical projection, result would be a row matrix
Mat1i reducedVer;
cv::reduce(mat, reducedVer, 0, CV_REDUCE_SUM);
// reducedVer is:
//
// 1200
// Summary
//
// 1100 > 2
// 0100 > 1
// 0000 > 0
// 0000 > 0
//
// vvvv
// 1200
您可以像这样将其用于图像:
// RGB image
Mat3b img = imread("path_to_image");
// Gray image, contains values in [0,255]
Mat1b gray;
cvtColor(img, gray, CV_BGR2GRAY);
// Binary image, contains only 0,1 values
// The sum of pixel values will equal the count of non-zero pixels
Mat1b binary;
threshold(gray, binary, 1, 1, THRESH_BINARY);
// Horizontal projection
Mat1i reducedHor;
cv::reduce(binary, reducedHor, 1, CV_REDUCE_SUM);
// Vertical projection
Mat1i reducedVer;
cv::reduce(binary, reducedVer, 0, CV_REDUCE_SUM);
断言 src.channels() == 1
意味着图像应该有 1 个通道,即它必须是灰色的,而不是彩色的。您在 roi
上调用 countNonZero
,它是 binaryImage
的子图像,它是 src
的克隆,最初是彩色的。
我想你想写 cvtColor(binaryImage, binaryImage, CV_BGR2GRAY);
。在这种情况下,这是有道理的。但是,我没有看到你在任何地方再次使用 src
,所以也许你不需要这个中间图像。如果你这样做,不要调用 "binary",因为 "binary" 在计算机视觉中通常代表黑白图像,只有两种颜色。您的图片是 "gray",因为它有各种黑白色调。
关于你原来的任务,Miki说得对,你应该用cv::reduce
。他已经为您提供了如何使用它的示例。
我尝试使用 countNonZero() 函数获得水平投影,如下所示。
Mat src = imread(INPUT_FILE, CV_LOAD_IMAGE_COLOR);
Mat binaryImage = src.clone();
cvtColor(src, src, CV_BGR2GRAY);
Mat horizontal = Mat::zeros(1,binaryImage.cols, CV_8UC1);
for (int i = 0; i<binaryImage.cols; i++)
{
Mat roi = binaryImage(Rect(0, 0, 1, binaryImage.rows));
horizontal.at<int>(0,i) = countNonZero(roi);
cout << "Col no:" << i << " >>" << horizontal.at<int>(0, i);
}
但是在调用countonZero()函数的那一行发生了错误。错误如下。
OpenCV Error: Assertion failed (src.channels() == 1 && func != 0) in cv::countNo
nZero, file C:\builds_4_PackSlave-win32-vc12-shared\opencv\modules\core\src\st
at.cpp, line 549
谁能指出错误?
顺便说一句,您可以使用 reduce
作为参数 CV_REDUCE_SUM
来计算水平投影。
一个最小的例子:
Mat1b mat(4, 4, uchar(0));
mat(0,0) = uchar(1);
mat(0,1) = uchar(1);
mat(1,1) = uchar(1);
// mat is:
//
// 1100
// 0100
// 0000
// 0000
// Horizontal projection, result would be a column matrix
Mat1i reducedHor;
cv::reduce(mat, reducedHor, 1, CV_REDUCE_SUM);
// reducedHor is:
//
// 2
// 1
// 0
// 0
// Vertical projection, result would be a row matrix
Mat1i reducedVer;
cv::reduce(mat, reducedVer, 0, CV_REDUCE_SUM);
// reducedVer is:
//
// 1200
// Summary
//
// 1100 > 2
// 0100 > 1
// 0000 > 0
// 0000 > 0
//
// vvvv
// 1200
您可以像这样将其用于图像:
// RGB image
Mat3b img = imread("path_to_image");
// Gray image, contains values in [0,255]
Mat1b gray;
cvtColor(img, gray, CV_BGR2GRAY);
// Binary image, contains only 0,1 values
// The sum of pixel values will equal the count of non-zero pixels
Mat1b binary;
threshold(gray, binary, 1, 1, THRESH_BINARY);
// Horizontal projection
Mat1i reducedHor;
cv::reduce(binary, reducedHor, 1, CV_REDUCE_SUM);
// Vertical projection
Mat1i reducedVer;
cv::reduce(binary, reducedVer, 0, CV_REDUCE_SUM);
断言 src.channels() == 1
意味着图像应该有 1 个通道,即它必须是灰色的,而不是彩色的。您在 roi
上调用 countNonZero
,它是 binaryImage
的子图像,它是 src
的克隆,最初是彩色的。
我想你想写 cvtColor(binaryImage, binaryImage, CV_BGR2GRAY);
。在这种情况下,这是有道理的。但是,我没有看到你在任何地方再次使用 src
,所以也许你不需要这个中间图像。如果你这样做,不要调用 "binary",因为 "binary" 在计算机视觉中通常代表黑白图像,只有两种颜色。您的图片是 "gray",因为它有各种黑白色调。
关于你原来的任务,Miki说得对,你应该用cv::reduce
。他已经为您提供了如何使用它的示例。