利用区域生长算法祛除二值图像中的噪声区域

#include <cv.h>  
#include <highgui.h>  
#include <opencv2/imgproc/imgproc.hpp>    
#include <opencv2/highgui/highgui.hpp>    
#include <iostream>    
#include <vector>    


using namespace cv;
using namespace std;

void dispel(Mat &src, bool mode, float ratio, bool neighborhood);

int main()
{
	double t = (double)getTickCount();


//	char* OutPath = "C:\\Users\\Administrator\\Desktop\\psb0.jpg";
	Mat image = imread("1.bmp",-1);
	Mat Src;
	cvtColor(image,Src,CV_BGR2GRAY);
	Mat Dst = Mat::zeros(Src.size(), CV_8UC1);
	
	

	//二值化处理  
	for (int i = 0; i < Src.rows; ++i)
	{
		uchar* iData = Src.ptr<uchar>(i);
		for (int j = 0; j < Src.cols; ++j)
		{
			if (iData[j] == 0 || iData[j] == 255) continue;
			else if (iData[j] < 150)
			{
				iData[j] = 0;
				//cout<<'#';  
			}
			else if (iData[j] > 150)
			{
				iData[j] = 255;
				//cout<<'!';  
			}
		}
	}
	imshow("原图",Src);
	imwrite("1.jpg",Src);
	dispel(Src, 1, 0.2, 1);
	imshow("Src", Src);
	imwrite("2.jpg", Src);
	cout << "Image Binary processed." << endl;
	t = ((double)getTickCount() - t) / getTickFrequency();
	cout << "Time cost: " << t << " sec." << endl;
	waitKey(0);
	return 0;
}
/*
seed_filling() 利用种子填充法找到一个区域,运用迭代法

label 标记图像
neighborhood  0为四邻域 ,1 为8邻域
区域内的点的集合
要判断的点
*/
void seed_filling( Mat &label, vector<Point> &grow_point, Point grow_seed, bool neighborhood, int point_limit)
{
	
	label.at<unsigned char>(grow_seed.y, grow_seed.x) = 3;
//	if(grow_point.size()>point_limit)    return;
	if (neighborhood == 0)       //四邻域
	{
		

		if (grow_seed.x - 1 >= 0)
		{
			if (label.at<unsigned char>(grow_seed.y, grow_seed.x - 1) == 0)    //左
			{
				Point grow_seed_temp(grow_seed.x - 1, grow_seed.y);
				grow_point.push_back(grow_seed_temp);


				seed_filling(label, grow_point, grow_seed_temp, neighborhood, point_limit);

			}
		}
		if (grow_seed.x + 1 < label.cols)
		{
			if (label.at<unsigned char>(grow_seed.y, grow_seed.x + 1) == 0)    //右
			{
				Point grow_seed_temp(grow_seed.x + 1, grow_seed.y);
				grow_point.push_back(grow_seed_temp);


				seed_filling(label, grow_point, grow_seed_temp, neighborhood, point_limit);

			}
		}
		if (grow_seed.y - 1 >= 0)
		{
			if (label.at<unsigned char>(grow_seed.y - 1, grow_seed.x) == 0)         //上
			{
				Point grow_seed_temp(grow_seed.x, grow_seed.y - 1);
				grow_point.push_back(grow_seed_temp);


				seed_filling(label, grow_point, grow_seed_temp, neighborhood, point_limit);
			}
		}
		if (grow_seed.y + 1 < label.rows)
		{
			if (label.at<unsigned char>(grow_seed.y + 1, grow_seed.x) == 0)         //下
			{
				Point grow_seed_temp(grow_seed.x, grow_seed.y + 1);
				grow_point.push_back(grow_seed_temp);
				seed_filling(label, grow_point, grow_seed_temp, neighborhood, point_limit);
			}

		}
	}
	else                              //八邻域
	{
		

		for (int i = -1; i < 2; i++)
		{
			for (int j = -1; j < 2; j++)
			{

				if (grow_seed.y + i >= 0 && grow_seed.y + i < label.rows
					&&grow_seed.x + j>=0 && grow_seed.x +j< label.cols
					&&label.at<unsigned char>(grow_seed.y + i, grow_seed.x + j) == 0
					)

				{
					Point grow_seed_temp(grow_seed.x+j, grow_seed.y + i);
					grow_point.push_back(grow_seed_temp);
					seed_filling(label, grow_point, grow_seed_temp, neighborhood, point_limit);
				}


			}

		}



	}





}

/*//dispel()利用种子填充法用来祛除一副图像中的噪声小区域
src 与dst 均为单通道的图像
mode 用于表示祛除的小区域的颜色,0为白色,1为黑色
ratio表示祛除区域占整个图像的比例
neighborhood  0为四邻域 ,1 为8邻域
*/
void dispel(Mat &src, bool mode, float ratio, bool neighborhood)
{
	Mat label_image(src.size(), CV_8UC1, Scalar::all(0));                           //标签图像,用来标注每一个像素点被处理的情况         3表示已经经过处理或者不需要处理
	for (int i = 0; i < src.rows; i++)
	{
		unsigned char *data = label_image.ptr<unsigned char>(i);
		unsigned char *data0 = src.ptr<unsigned char>(i);
		for (int j = 0; j < src.cols; j++)
		{
			if (mode == 0)
			{
				if (data0[j] == 0)     data[j] = 3;
			}
			else
			{
				if (data0[j] == 255)     data[j] = 3;
			}

		}
	}

	for (int i = 0; i < src.rows; i++)
	{

		for (int j = 0; j < src.cols; j++)

		{
			unsigned char *data = label_image.ptr<unsigned char>(i);


			if (data[j] == 0)
			{
				vector<Point>   grow_point;             //一个区域的集合
				Point grow_seed(j, i);
				grow_point.push_back(grow_seed);
				seed_filling(label_image, grow_point, grow_seed, neighborhood, src.size().area()* ratio);
				cout << "点数" << grow_point.size() << endl;
				if (grow_point.size() < src.size().area()* ratio)
				{
					for (int a = 0; a < grow_point.size(); a++)
					{

						src.at<unsigned char>(grow_point[a].y, grow_point[a].x)=255* mode;

					}



				}
			}


		}

	}






}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值