車牌斷裂區域的融合

在車牌識別中,經常會遇到車牌斷裂的情形。致使這種緣由的多是:執行形態學 操做時(開運算、閉運算)的結構元素過小,而車牌區域過大的情形。此時出現斷裂的車牌就須要進行區域的融合,使其斷裂的區域從新成爲一個連通域。車牌斷裂的情形好比有以下情形:

形態學操做致使車牌斷裂 形態學操做致使車牌斷裂: 原圖中A 和 9 的距離過長 原圖中A 和 9 的距離過長 對於出現的斷裂的情形,融合的算法取決於如何斷定所斷裂的區域具備某種聯繫? 融合算法首先應當考慮到情形斷定兩個區域之間的聯繫,便是否在同一水平、或者在同一豎直方向上,其次是要考慮車牌自己的特徵。如車牌的顏色分佈、字符紋理等先驗知識。同時,爲了不區域的錯誤融合,還應作一些區域距離上的限制。好比設定閾值,距離在該範圍以內的知足條件。算法

這裏給出區域融合的算法步驟: step 1. 獲取全部輪廓外接矩形放入集合A中。 step 2. 遍歷A,並考察矩形顏色的分佈,若目標顏色(藍、黃)比率較大,則放入候選矩形集合B中。 step 3. 考察集合B中矩形位置關係,若在同一水平(同一豎直)方向,而且知足限定的距離時,在兩個區域中畫線,使其融合。函數

對於區域融合,主要的難點在於如何合理的斷定區域的正確性。因爲咱們所取得的區域並不必定只包含有車牌區域,還有可能與噪聲粘連在一塊兒,這樣會致使區域過大過寬帶情形,區域位置變得不太明顯。這裏算法所取得方法是,計算區域的幾何中心,利用幾何中心評判區域的位置。 可靠性就會更高點。測試

區域的融合問題,目前只能想到這種方法,可能還有更好的算法更爲可靠。

繼昨天以後,進行上述算法,能夠獲得相要點結果。廢話很少說,看代碼:調試

<!-- lang: cpp -->
void MergeProbabilityRectArea(IplImage* img_rgb,IplImage* in_imgBin)

{ if(img_rgb == NULL || in_imgBin == NULL) return; if((img_rgb->depth != 8 && img_rgb->nChannels != 3) || (in_imgBin->depth != 8 && in_imgBin->nChannels != 1)) return;code

const int		nMinArea		=	40;                //定義最小面積
const int		nMaxDist		=	100;              //允許的最大距離
const int		nOffSet		=	20;                //允許的中心偏移量
int		count			=	0;
int		nRect			=	0;
CvRect*	tmp_rect		        =	0;
CvRect*	coarseRect		=	0;

coarseRect = FindAllAreaRect(in_imgBin,nRect);	    //找到全部的區域
tmp_rect   = new CvRect[nRect];
memset(tmp_rect,0,sizeof(CvRect)*nRect);

    //顯示測試
//for(int i=0;i<nRect;i++)
//	cvRectangle(img_rgb,cvPoint(coarseRect[i].x,coarseRect[i].y),
//		cvPoint(coarseRect[i].x+coarseRect[i].width,coarseRect[i].y+coarseRect[i].height),
//		CV_RGB(0,255,0),3);

//cvShowImage("img_rgb",img_rgb);
for(int i=0;i<nRect;i++)
{
	IplImage* img_tmp = NULL; 
	int area = coarseRect[i].width * coarseRect[i].height;
	img_tmp = GetRectImage(img_rgb,coarseRect[i]);
	float colorRate = GetColorDistributed(img_tmp,NULL,COLOR_BLUE);        //獲取區域顏色分佈的比率
	if(area < nMinArea || colorRate < 0.02)
		continue;
	tmp_rect[count++] = coarseRect[i];
	cvReleaseImage(&img_tmp);
}

for(int i=0;i<count;i++)
{
	for(int j=i+1;j<count;j++)
	{
		CvPoint irtCentroid,jrtCentroid;
		GetRectCentroid(tmp_rect[i],irtCentroid);
		GetRectCentroid(tmp_rect[j],jrtCentroid);
		
		//whether in the horizontal direction
		if(abs(irtCentroid.y -jrtCentroid.y) < nOffSet)
		{
			int dist = 0;
			int x = MIN(irtCentroid.x,jrtCentroid.x);
			if(x == irtCentroid.x)
			{
				dist = jrtCentroid.x - (irtCentroid.x + tmp_rect[i].width / 2);
			}
			else
			{
				dist = irtCentroid.x - (jrtCentroid.x + tmp_rect[j].width / 2);
			}
			if(dist < nMaxDist)
				DrawLine(in_imgBin,tmp_rect[i],tmp_rect[j]);
		}

            //豎直方向上也差很少,這裏代碼缺省
	}
}

delete [] coarseRect;
delete [] tmp_rect;
tmp_rect = NULL;
coarseRect = NULL;

}it

如圖: 車牌斷裂情形 車牌斷裂情形 執行區域融合效果 執行區域融合效果,圖中黑色圓點爲矩形的重心點 最終造成的連通域 最終造成的連通域io

此處須要說明的是,函數裏面的參數,如分佈的比率以及 最小面積 等 須要調試後再肯定,不一樣的需求可能參數值不一樣
相關文章
相關標籤/搜索