【OpenCV】8邻域种子填充法剔除短连通域的高效算法
生活随笔
收集整理的這篇文章主要介紹了
【OpenCV】8邻域种子填充法剔除短连通域的高效算法
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
//本文檔參考種子填充算法描述及C++代碼實現(xiàn)(https://www.bbsmax.com/A/amd0AVWzge/)講解的原理,實現(xiàn)快速種子填充算法,運(yùn)行效果高。
//具體功能如下:依次掃描每個像素,檢測8領(lǐng)域,尋找連通域,刪掉面積小于閾值的。
#include <opencv2/opencv.hpp>
#include <cv.h>using namespace cv;
using namespace std;#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 720
int position_offset[POSITION_OFFSET_SIZE] = {-INIMG_WIDTH, -INIMG_WIDTH-1,-1, INIMG_WIDTH-1, INIMG_WIDTH, INIMG_WIDTH+1, 1, -INIMG_WIDTH+1};int init_stk[MAX_STK_BIRD_SIZE];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像素寬度范圍內(nèi)像素置為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像素寬度范圍內(nèi)的像素置為0}bdata_tmp += INIMG_WIDTH; }cdata = outImg.data; memset(cdata, 0, sizeof(uchar)*INIMG_HEIGHT*INIMG_WIDTH);//需要為stk分配空間!stk = init_stk; //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鄰域聯(lián)通總數(shù)小于設(shè)置的最小面積閾值,不保留。for (k = stkN - 1; k >= 0; k--) {p = stk[k]; cdata[p] = 1; }}
}//把只有0/1取值的二值圖轉(zhuǎn)為0/255取值的二值圖
static void binary2To255(Mat &img)
{for (int i=0;i<img.rows;i++) {for (int j=0;j<img.cols;j++) {if (img.data[i*img.cols + j] > 0) img.data[i*img.cols + j] = 255;}}
}int main()
{Mat srcImg = imread("G:\\binaryImg\\image1.bmp", 0);imshow("in", srcImg);Mat dstImg(srcImg.rows, srcImg.cols, CV_8UC1, Scalar(0));;SeedFillAlgorithm(srcImg, dstImg);binary2To255(dstImg);imshow("out", dstImg);waitKey(0);return 0;
}
處理結(jié)果如下:?
?
?
總結(jié)
以上是生活随笔為你收集整理的【OpenCV】8邻域种子填充法剔除短连通域的高效算法的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【机器学习】LBP+SVM实现特征检测
- 下一篇: 基于OpenCV的findContour