我是opencv / C ++的初学者,希望您能帮助解决一个看似简单的问题。举个例子,我有这个图像:
......并且会忽略背景,背景总是白色,图像总是黑白的,只留下云才能算上三件事:
我知道要达到2,用它减去第3个。
谢谢!
答案 0 :(得分:1)
这是一个非常简单的方法
答案 1 :(得分:0)
您可以使用此代码进行计数以查找图像中的黑色像素。应用相同的逻辑来计算白色像素。
#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";
}
答案 2 :(得分:0)
首先,您可以使用cv::countNonZero(img)
来计算非黑色像素。因此,您可以使用(img.rows * img.cols) - cv::countNonZero(img)
来计算黑色像素。
现在,请尝试以下操作:首先,计算黑色像素。然后尝试使用形态开口去除clould中的那些白色斑点。然后,再次计算黑色像素。现在你可以从第二个计数中减去第一个计数,然后你就可以获得这些blob中的白色像素数量。
然而,这种方法不准确,因为形态开口也会在外面稍微改变云。另一种方法是在另一个答案中建议的方法,使用泛光填充来填充周围的黑色白色像素。
顺便提一下,形态开放就像这样:
cv::Mat element = cv::getStructuringElement(cv::MORPH_ELLIPSE, cv::Size(2 * openingRadius + 1, 2 * openingRadius + 1));
cv::morphologyEx(mat, mat, cv::MORPH_OPEN, element);
或者,与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);
答案 3 :(得分:0)
您需要的所有工具都是cv::findContour
和cv::drawContour
。首先,你需要摆脱白色背景,然后用云做你的工作:
findContours(the_image, contours, hierarchy, CV_RETR_LIST , CV_CHAIN_APPROX_NONE );
从轮廓中找到第二个大矢量(轮廓),这就是云的边界。顺便说一下,最大的一个是白色背景的外轮廓。然后...
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
是第二个大轮廓的索引。
现在在test_img中,你有一个完全是白色的云。现在使用countNonZero来获取云的像素数(num1)。此外,您必须将此图像(作为蒙版)与原始图像相乘,然后您将拥有原始图像但没有白色背景。再次使用countNonZero获取云中白色像素的数量(num2)。最后num1-num2
为您提供云中黑色像素的数量。如果您在使用findContur
时遇到问题,请与我联系。