简体   繁体   English

计数黑白图像的像素(OpenCV / C ++)

[英]Count pixels of a black and white image (OpenCV / C++ )

I am a beginner to opencv / C ++ and would like your help with a problem that seems simple. 我是opencv / C ++的初学者,希望为您提供一个看似简单的问题的帮助。 As an example, I have this image: 例如,我有此图像:

图片范例

... And would disregard the background, which will always be white, and the image is always black and white, leaving only the cloud to be able to count three things: ...并且将忽略背景,背景将始终为白色,图像始终为黑白,仅留下云就可以计算三件事:

  1. The number of pixels of the figure (cloud only, disregarding the background). 图形的像素数(仅云,不考虑背景)。
  2. The number of white pixels. 白色像素数。 (cloud only) (仅限云)
  3. The number of black pixels. 黑色像素数。 (cloud only) (仅限云)

I know that to achieve 2, with a subtraction with it the 3rd. 我知道要达到2,请减去3。

Thanks! 谢谢!

Here's a very simple method 这是一个非常简单的方法

  • Count the black pixels (3) 计算黑色像素(3)
  • Flood-fill with black starting at any corner 从任何角落开始以黑色填充洪水
  • Count the number of remaining white pixels (2) 计算剩余的白色像素数(2)
  • Add results (2) and (3) to get (1) 将结果(2)和(3)相加得到(1)

You can use this code to count to find black pixel in an image.Apply same logic for counting white pixels. 您可以使用此代码进行计数以查找图像中的黑色像素。

#include<opencv2/opencv.hpp>
#include<opencv2/highgui/highgui.hpp>

using namespace std;
using namespace cv;

int main()
{

Mat img = imread("/home/jordan/opencv/Test/edge_detection/img2.bmp",0);
cout<<"cols= "<<img.cols<<"row= "<<img.rows<<"\n";
int i,j,count=0;
for(i=0;i<img.cols;i++)
{
for(j=0;j<img.rows;j++)
{
int k=img.at<uchar>(j,i);
if(k==0)
{  
count++;
cout<<"col="<<i<<"row="<<j<<"k= "<< k<<"\t\n";
}
}
} 
cout<<"count="<<count<<"\n";
}

First of all, you can use cv::countNonZero(img) to count non-black pixels. 首先,您可以使用cv::countNonZero(img)来计数非黑色像素。 Thus you can use (img.rows * img.cols) - cv::countNonZero(img) to count black pixels. 因此,您可以使用(img.rows * img.cols) - cv::countNonZero(img)来计数黑色像素。

Now, try the following: First, count the black pixels. 现在,尝试以下操作:首先,计算黑色像素。 Then try to use morphological opening to remove those white blobs inside the clould. 然后尝试使用形态学开口来去除血块内部的那些白色斑点。 Afterwards, count the black pixels again. 之后,再次计数黑色像素。 Now you can substract the first count from the second one and you'll get the amount of white pixels inside those blobs. 现在,您可以从第二个计数中减去第一个计数,然后获得这些斑点内的白色像素数量。

However, this method will not be accurate, because the morphological opening will also alter the cloud a bit on the outside. 但是,此方法将不准确,因为形态学开口还会在外部稍微改变云层。 An alternative would be the method suggested in an other answer, to use flood fill to fill the surrounding white pixels with black. 一种替代方法是在另一个答案中建议的方法,即使用泛洪填充将周围的白色像素填充为黑色。

Morphological opening works like this by the way: 形态学开放的方式如下:

cv::Mat element = cv::getStructuringElement(cv::MORPH_ELLIPSE, cv::Size(2 * openingRadius + 1, 2 * openingRadius + 1));
cv::morphologyEx(mat, mat, cv::MORPH_OPEN, element);

Or, with cuda: 或者,使用cuda:

cv::Mat element = cv::getStructuringElement(cv::MORPH_ELLIPSE, cv::Size(2 * openingRadius + 1, 2 * openingRadius + 1));
cv::cuda::createMorphologyFilter(cv::MORPH_OPEN, CV_8UC1, element)->apply(gpuMat, gpuMat);

All the tools you need are cv::findContour and cv::drawContour . 您需要的所有工具都是cv::findContourcv::drawContour First of all you need to get rid of the white background, then do your jobs with the cloud: 首先,您需要摆脱白色背景,然后使用云进行工作:

findContours(the_image, contours, hierarchy, CV_RETR_LIST , CV_CHAIN_APPROX_NONE );

from contours, find the second big vector(contour) and that is the cloud's boundry. 从轮廓中找到第二个大矢量(轮廓),这就是云的边界。 The biggest one by the way, would be the outer contour of the white background. 顺便说一句,最大的是白色背景的外轮廓。 Then... 然后...

cv::Mat test_img = cv::Mat::zeros(the_img.size(),CV_8U);
drawContours(test_img , contours, contourIdx, Scalar(255,255,255), CV_FILLED ,8);

contourIdx is the index of that second big contour. contourIdx是第二个大轮廓的索引。 Now in test_img you have a cloud that is white completely. 现在,在test_img中,您的云将完全变成白色。 Now use countNonZero to get the number of cloud's pixels(num1). 现在使用countNonZero来获取云的像素数(num1)。 In further you have to multiply this image (as a mask) to the original image and then you have the original image but without the white background. 此外,您还必须将此图像(作为蒙版)乘以原始图像,然后获得原始图像,但没有白色背景。 Use countNonZero again to have the number of the white pixels in the cloud(num2). 再次使用countNonZero以使云中的白色像素数(num2)。 And finally num1-num2 gives you the number of black pixels in the cloud. 最后, num1-num2给出了云中黑色像素的数量。 Comment for me if you had trouble with findContur . 如果您在findContur方面遇到问题,请为我发表评论。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM