国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > Python > 正文

OPENCV去除小連通區(qū)域,去除孔洞的實(shí)例講解

2020-02-15 21:58:03
字體:
供稿:網(wǎng)友

一、對于二值圖,0代表黑色,255代表白色。去除小連通區(qū)域與孔洞,小連通區(qū)域用8鄰域,孔洞用4鄰域。

函數(shù)名字為:void RemoveSmallRegion(Mat &Src, Mat &Dst,int AreaLimit, int CheckMode, int NeihborMode)

CheckMode: 0代表去除黑區(qū)域,1代表去除白區(qū)域; NeihborMode:0代表4鄰域,1代表8鄰域;

如果去除小連通區(qū)域CheckMode=1,NeihborMode=1去除孔洞CheckMode=0,NeihborMode=0

記錄每個像素點(diǎn)檢驗狀態(tài)的標(biāo)簽,0代表未檢查,1代表正在檢查,2代表檢查不合格(需要反轉(zhuǎn)顏色),3代表檢查合格或不需檢查 。

1.先對整個圖像掃描,如果是去除小連通區(qū)域,則將黑色的背景圖作為合格,像素值標(biāo)記為3,如果是去除孔洞,則將白色的色素點(diǎn)作為合格,像素值標(biāo)記為3。

2.掃面整個圖像,對圖像進(jìn)行處理。

void RemoveSmallRegion(Mat &Src, Mat &Dst,int AreaLimit, int CheckMode, int NeihborMode){	int RemoveCount = 0;	//新建一幅標(biāo)簽圖像初始化為0像素點(diǎn),為了記錄每個像素點(diǎn)檢驗狀態(tài)的標(biāo)簽,0代表未檢查,1代表正在檢查,2代表檢查不合格(需要反轉(zhuǎn)顏色),3代表檢查合格或不需檢查 	//初始化的圖像全部為0,未檢查	Mat PointLabel = Mat::zeros(Src.size(), CV_8UC1);	if (CheckMode == 1)//去除小連通區(qū)域的白色點(diǎn)	{		cout << "去除小連通域.";		for (int i = 0; i < Src.rows; i++)		{			for (int j = 0; j < Src.cols; j++)			{				if (Src.at<uchar>(i, j) < 10)				{					PointLabel.at<uchar>(i, j) = 3;//將背景黑色點(diǎn)標(biāo)記為合格,像素為3				}			}		}	}	else//去除孔洞,黑色點(diǎn)像素	{		cout << "去除孔洞";		for (int i = 0; i < Src.rows; i++)		{			for (int j = 0; j < Src.cols; j++)			{				if (Src.at<uchar>(i, j) > 10)				{					PointLabel.at<uchar>(i, j) = 3;//如果原圖是白色區(qū)域,標(biāo)記為合格,像素為3				}			}		}	}	vector<Point2i>NeihborPos;//將鄰域壓進(jìn)容器	NeihborPos.push_back(Point2i(-1, 0));	NeihborPos.push_back(Point2i(1, 0));	NeihborPos.push_back(Point2i(0, -1));	NeihborPos.push_back(Point2i(0, 1));	if (NeihborMode == 1)	{		cout << "Neighbor mode: 8鄰域." << endl;		NeihborPos.push_back(Point2i(-1, -1));		NeihborPos.push_back(Point2i(-1, 1));		NeihborPos.push_back(Point2i(1, -1));		NeihborPos.push_back(Point2i(1, 1));	}	else cout << "Neighbor mode: 4鄰域." << endl;	int NeihborCount = 4 + 4 * NeihborMode;	int CurrX = 0, CurrY = 0;	//開始檢測	for (int i = 0; i < Src.rows; i++)	{		for (int j = 0; j < Src.cols; j++)		{			if (PointLabel.at<uchar>(i, j) == 0)//標(biāo)簽圖像像素點(diǎn)為0,表示還未檢查的不合格點(diǎn)			{ //開始檢查				vector<Point2i>GrowBuffer;//記錄檢查像素點(diǎn)的個數(shù)				GrowBuffer.push_back(Point2i(j, i));				PointLabel.at<uchar>(i, j) = 1;//標(biāo)記為正在檢查				int CheckResult = 0;				for (int z = 0; z < GrowBuffer.size(); z++)				{					for (int q = 0; q < NeihborCount; q++)					{						CurrX = GrowBuffer.at(z).x + NeihborPos.at(q).x;						CurrY = GrowBuffer.at(z).y + NeihborPos.at(q).y;						if (CurrX >= 0 && CurrX<Src.cols&&CurrY >= 0 && CurrY<Src.rows) //防止越界 						{							if (PointLabel.at<uchar>(CurrY, CurrX) == 0)							{								GrowBuffer.push_back(Point2i(CurrX, CurrY)); //鄰域點(diǎn)加入buffer 								PointLabel.at<uchar>(CurrY, CurrX) = 1;   //更新鄰域點(diǎn)的檢查標(biāo)簽,避免重復(fù)檢查 							}						}					}				}				if (GrowBuffer.size()>AreaLimit) //判斷結(jié)果(是否超出限定的大小),1為未超出,2為超出 					CheckResult = 2;				else				{					CheckResult = 1;					RemoveCount++;//記錄有多少區(qū)域被去除				}				for (int z = 0; z < GrowBuffer.size(); z++)				{					CurrX = GrowBuffer.at(z).x;					CurrY = GrowBuffer.at(z).y;					PointLabel.at<uchar>(CurrY,CurrX)+=CheckResult;//標(biāo)記不合格的像素點(diǎn),像素值為2				}				//********結(jié)束該點(diǎn)處的檢查********** 			}		}	}	CheckMode = 255 * (1 - CheckMode);	//開始反轉(zhuǎn)面積過小的區(qū)域 	for (int i = 0; i < Src.rows; ++i)	{		for (int j = 0; j < Src.cols; ++j)		{			if (PointLabel.at<uchar>(i,j)==2)			{				Dst.at<uchar>(i, j) = CheckMode;			}			else if (PointLabel.at<uchar>(i, j) == 3)			{				Dst.at<uchar>(i, j) = Src.at<uchar>(i, j);							}		}	}	cout << RemoveCount << " objects removed." << endl;}            
發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 石台县| 上栗县| 明水县| 安龙县| 河东区| 密云县| 济南市| 武汉市| 扬中市| 淮南市| 汕头市| 宁安市| 梅州市| 九寨沟县| 南城县| 禹州市| 桑植县| 类乌齐县| 玉树县| 成安县| 黄陵县| 安龙县| 厦门市| 博野县| 太仓市| 凭祥市| 丰县| 济南市| 石台县| 吴川市| 郓城县| 比如县| 屯留县| 财经| 慈溪市| 贡觉县| 唐海县| 吉水县| 沙雅县| 鹰潭市| 孝昌县|