//本文档参考种子填充算法描述及C++代码实现(https://www.bbsmax.com/A/amd0AVWzge/)讲解的原理,实现快速种子填充算法,运行效果高。
//具体功能如下:依次扫描每个像素,检测8领域,寻找连通域,删掉面积小于阈值的。
#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像素宽度范围内像素置为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);
//需要为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邻域联通总数小于设置的最小面积阈值,不保留。
for (k = stkN - 1; k >= 0; k--)
{
p = stk[k]; cdata[p] = 1;
}
}
}
//把只有0/1取值的二值图转为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;
}
处理结果如下: