countNonZero 函数在 openCV 中给出断言错误

Posted

技术标签:

【中文标题】countNonZero 函数在 openCV 中给出断言错误【英文标题】:countNonZero function gives an assertion error in openCV 【发布时间】:2015-07-05 14:48:36 【问题描述】:

我尝试使用 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\2_4_PackSlave-win32-vc12-shared\opencv\modules\core\src\st
    at.cpp, line 549

谁能指出错误?

【问题讨论】:

binaryImage 是 src 的副本,它是 3 通道彩色图像。试试 cvtColor(src, binaryImage, CV_BGR2GRAY); 还有另一个错误:将 Horizo​​ntal.at(0,i) 切换为 Horizo​​ntal.at(0,i),因为您创建了 8 位数据类型。 我做了更改,错误已解决。感谢那。但现在我看到 countNonZero(roi) 函数返回的值始终为零。我还确认 binaryImage 不是完全黑色的图像。 (它到处都有黑白像素) 你换成cout了吗>" (0, i);也是? 输入矩阵的第一列完全为零吗?在每次迭代中,您都会阅读同一列!试试 Mat roi = binaryImage(Rect(i, 0, 1, binaryImage.rows)); 【参考方案1】:

断言src.channels() == 1 表示图像应该有 1 个通道,即它必须是灰色的,而不是彩色的。您在roi 上调用countNonZero,这是binaryImage 的子图像,它是src 的克隆,最初是彩色的。

我想你想写cvtColor(binaryImage, binaryImage, CV_BGR2GRAY);。在这种情况下,这是有道理的。但是,我没有看到您再次在任何地方使用src,因此您可能不需要此中间图像。如果您这样做,请不要称“二进制”,因为计算机视觉中的“二进制”通常代表黑白图像,只有两种颜色。您的图像是“灰色”的,因为它具有各种黑白色调。

关于你最初的任务,Miki 是对的,你应该使用cv::reduce。他已经给你举例说明了如何使用它。

【讨论】:

感谢您的回答。除了上述我必须改变的事情之外,Mat roi = binaryImage(Rect(0, 0, 1, binaryImage.rows));因此, Mat roi = binaryImage(Rect(i, 0, 1, binaryImage.rows));我只是在迭代同一列。【参考方案2】:

顺便说一句,您可以使用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);

【讨论】:

你能详细说明你的答案吗?什么是减少?它是一个函数吗?如果是这样,如何使用它? 对不起。这仍然没有任何意义。至少你甚至没有使用黑白图像来获得它的水平投影。 @SamithaChathuranga 我更新了我的答案,希望它对你更有意义。 这似乎更容易,即使这不是我的方法。我会尽快检查并回复结果。谢谢三木。

以上是关于countNonZero 函数在 openCV 中给出断言错误的主要内容,如果未能解决你的问题,请参考以下文章

opencv如何读取多边形区域内的像素值?

计算黑色像素比

opencv中cvCvtColor函数在哪个库

opencv中cvCvtColor函数在哪个库

Opencv+Python:在Opencv中绘制函数

opencv常用函数