【OpenCV】8鄰域種子填充法剔除短連通域的高效演算法
阿新 • • 發佈:2018-12-21
//本文件參考種子填充演算法描述及C++程式碼實現(https://www.bbsmax.com/A/amd0AVWzge/)講解的原理,實現快速種子填充演算法,執行效果高。
//具體功能如下:依次掃描每個畫素,檢測8領域,尋找連通域,刪掉面積小於閾值的。
#define IMG_MARGIN_GAP_SIZE 3 #define IMG_MINIMUM_ALGO_AREA 30 //保留連通域的面積下限 #define POSITION_OFFSET_SIZE 8 //8鄰域 #define MAX_STK_BIRD_SIZE 4000 #define INIMG_WIDTH 300 #define INIMG_HEIGHT 500 int position_offset[POSITION_OFFSET_SIZE] = {-INIMG_WIDTH, -INIMG_WIDTH-1,-1, INIMG_WIDTH-1, INIMG_WIDTH, INIMG_WIDTH+1, 1, -INIMG_WIDTH+1}; void SeedFillAlgorithm(Mat &inImg, Mat &outImg) { int i, j, k, p, pp; uchar *bdata, *bdata_tmp, *cdata; int *stk, stkN; bdata = inImg.data; bdata_tmp = inImg.data + INIMG_WIDTH * (INIMG_HEIGHT-IMG_MARGIN_GAP_SIZE); for (i = 0; i < IMG_MARGIN_GAP_SIZE; i++) { for (j = 0; j < INIMG_WIDTH; j++) { *bdata++ = *bdata_tmp++ = 0; //把影象上下邊界3畫素寬度範圍內畫素置為0 } } bdata_tmp = inImg.data + (INIMG_WIDTH -1)*IMG_MARGIN_GAP_SIZE; for (i = INIMG_HEIGHT-2*IMG_MARGIN_GAP_SIZE; i > 0; i--) { for (j = 0; j < (IMG_MARGIN_GAP_SIZE*2); j++) { bdata_tmp[j] = 0; //把影象左右邊界3畫素寬度範圍內的畫素置為0 } bdata_tmp += INIMG_WIDTH; } cdata = outImg.data; memset(cdata, 0, sizeof(uchar)*INIMG_HEIGHT*INIMG_WIDTH); memset(stk, 0, sizeof(int)*MAX_STK_BIRD_SIZE); bdata = inImg.data; for (i = INIMG_WIDTH*IMG_MARGIN_GAP_SIZE; i < INIMG_WIDTH*(INIMG_HEIGHT-IMG_MARGIN_GAP_SIZE); i++) { if (bdata[i] == 0) continue; bdata[i] = 0; stk[0] = i; k = 0; stkN = 1; while (1) { p = stk[k++]; for (j = POSITION_OFFSET_SIZE-1; j >= 0; j--) { pp = p + position_offset[j]; if (bdata[pp] == 0) continue; bdata[pp] = 0; stk[stkN++] = pp; } if (k >= stkN) break; if (stkN >= (MAX_STK_BIRD_SIZE-POSITION_OFFSET_SIZE)) break; } if (stkN <= IMG_MINIMUM_ALGO_AREA) continue; //如果8鄰域聯通總數小於設定的最小面積閾值,不保留。 for (k = stkN - 1; k >= 0; k--) { p = stk[k]; cdata[p] = 1; } } }