//圖像預處理第4步:去離散雜點噪聲 void CChildView::OnImgprcRemoveNoise() { RemoveScatterNoise(m_hDIB); //在屏幕上顯示位圖 CDC* pDC=GetDC(); DisplayDIB(pDC,m_hDIB); }
/************************************************************ * * 函數名稱: * RemoveScatterNoise() * * 參數: * HDIB hDIB -原圖像的句柄 * * 返回值: * 無 * * 功能: * 經過對連續點長度的統計來去除離散雜點 * * 說明: * 只能對2值圖像進行處理 ****************************************************************/ void RemoveScatterNoise(HDIB hDIB) { // 指向DIB的指針 LPSTR lpDIB=(LPSTR) ::GlobalLock((HGLOBAL)hDIB); // 指向DIB象素指針 LPSTR lpDIBBits; // 找到DIB圖像象素數據區的起始位置 lpDIBBits = ::FindDIBBits(lpDIB); //得到圖像的長度 LONG lWidth=::DIBWidth ((char*)lpDIB); //得到圖像的高度 LONG lHeight=::DIBHeight ((char*)lpDIB); //設置斷定噪聲的長度閾值爲15 //即若是與考察點相鏈接的黑點的數目小於15則認爲考察點是噪聲點 int length=15; // 循環變量 m_lianXuShu=0; LONG i; LONG j; LONG k; // 圖像每行的字節數 LONG lLineBytes; // 計算圖像每行的字節數 lLineBytes = WIDTHBYTES(lWidth * 8); LPSTR lpSrc; //開闢一塊用來存放標誌的內存數組 LPBYTE lplab = new BYTE[lHeight * lWidth]; //開闢一塊用來保存離散斷定結果的內存數組 bool *lpTemp = new bool[lHeight * lWidth]; //初始化標誌數組 for (i=0;i<lHeight*lWidth;i++) { //將全部的標誌位設置爲非 lplab[i] = false; } //用來存放離散點的座標的數組 CPoint lab[21]; //爲循環變量賦初始值 k=0; //掃描整個圖像 //逐行掃描 for(i =0;i<lHeight;i++) { //逐行掃描 for(j=0;j<lWidth;j++) { //先把標誌位置false for(k=0;k<m_lianXuShu;k++) lplab[lab[k].y * lWidth + lab[k].x] = false; //連續數置0 m_lianXuShu =0; //進行離散性判斷 lpTemp[i*lWidth+j] = DeleteScaterJudge(lpDIBBits,(WORD)lLineBytes,lplab,lWidth,lHeight,j,i,lab,length); } } //掃描整個圖像,把離散點填充成白色 //逐行掃描 for(i = 0;i<lHeight;i++) { //逐列掃描 for(j=0;j<lWidth;j++) { //查看標誌位,若是爲非則將此點設爲白點 if(lpTemp[i*lWidth+j] == false) { //指向第i行第j個象素的指針 lpSrc=(char*)lpDIBBits + lLineBytes * i + j; //將此象素設爲白點 *lpSrc=BYTE(255); } } } //解除鎖定 ::GlobalUnlock ((HGLOBAL)hDIB); }
運行效果:數組