二值图像分析:按面积过滤噪点案例分析

二值图像分析:按面积过滤噪点案例分析

[二值图像分析:连通组件寻找算法]中分享了OpenCV中对于二值图像连通组件信息提取的方法,在[二值图像分析:二值图像轮廓提取]中分享了轮廓相关信息提取的方法。在实际应用中,有时候需要按照噪点的面积来过滤掉一些噪声块。

1.通过轮廓提取

对于上面的问题,有一种解决办法是,通过轮廓提取来得到每个轮廓的面积,然后根据面积填充这些轮廓:

double start = static_cast<double>(getTickCount());
//轮廓提取
vector<vector<Point>> contours;
vector<Vec4i>hierarchy;
findContours(binaryImage,contours,hierarchy,RETR_TREE,CHAIN_APPROX_SIMPLE,Point());
for(int i=0;i<contours.size();++i)
{
    
    
	if(contourArea(contours[i])<50)
	{
    
    
		drawContours(srcImage,contours,i,Scalar(255,255,255),-1,8);
	}
}	
double end= ((double)getTickCount() - start) / getTickFrequency();
//以毫秒输出
cout << "所用时间为:" << end*1000 << "ms" << endl;

输出:

所用时间为:2499.35ms

实际上上面的代码处理的是一张1292*968像素的图片,里面有10000+的小区域块。

2.通过连通区域

Mat labels = Mat::zeros(binaryImage.size(),CV_32S);
Mat stats,centroids;

double start = static_cast<double>(getTickCount());
int labelNums = connectedComponentsWithStats(binaryImage,labels, stats, centroids,4, 4);

int w = srcImage.cols,h = srcImage.rows;
for(int row=0;row<h;++row)
{
    
    
	for(int col=0;col<w;++col)
	{
    
    
		//获取labels每个位置的值,该值就是原图中对应位置像素点所属的连通区域类标签
		int label = labels.at<int>(row,col);
		if(label == 0)	//label=0为背景区域,不用管
			continue;
		if(stats.at<int>(label,CC_STAT_AREA)<50)
		{
    
    
			srcImage.at<Vec3b>(row,col)=Vec3b(255,255,255);
		}
	}
}

double end= ((double)getTickCount() - start) / getTickFrequency();

//以毫秒输出
cout << "所用时间为:" << end*1000 << "ms" << endl;

输出:

所用时间为:56.5649ms

可以看出,对于同样的图像要完成按面积过滤噪声块,连通区域分析处理起来更快更高效。

猜你喜欢

转载自blog.csdn.net/PecoHe/article/details/114360673