1.基本原理
相互连通且颜色相近的像素集合可以被看成图像的区域,而区域填充就是将每一块图像区域用指定颜色填充,填充的算法有很多种,但今天的猪脚是种子算法。在使用种子算法的时候,我们要注意两点,第一点:连通像素的搜索分为四方向和八方向,根据应用自己选择就行;第二点:边界判断,如果填充过程遇到某点的像素值和基准像素值差距太大,就可以视该点位边界像素。
种子算法的实现过程:
1)选取一个起始种子点,获取基准颜色,将种子点压入栈
2)从栈中取一个像素,依次对该像素的左右连通像素进行填充,并在填充过程中判断每个填充位置的上下两行中的相邻像素是否需要填充,将需要填充的相邻像素压入栈
3)对栈中的像素进行检查,去除已被填充的像素
4)重复第2、3步,直到栈为空。
2.代码实现(代码是我以前自学图像处理时写的,代码很粗糙没做任何优化,但很好理解)
//种子算法
QImage* MainWindow::FillArea(QImage* image,int* pos, int color,int delta)
{
int stack[9999];
int sk = 0;
int stk = 0;
int x =pos[0];
int y =pos[1];
int x1,y1;
unsigned char flagBuf[image->width()][image->height()];
memset(flagBuf,0,sizeof(unsigned char)*image->width()*image->height());
QImage* newImage = new QImage(image->height(),image->width(),QImage::Format_ARGB32);
QColor color1;
QColor color2;
color1 = QColor(image->pixel(x,y));
unsigned nowColor[3];
nowColor[0] = color1.red();
nowColor[1] = color1.green();
nowColor[2] = color1.blue();
stack[sk] = x;
stack[sk + 1] = y;
sk+=2;
while(sk > 0)
{
sk-=2;
int *tempStack = new int [9999];
int*pos = new int[2];
pos[0] = stack[sk];
pos[1] = stack[sk+1];
x1 = pos[0];
y1 = pos[1];
stk = 0;
newImage->setPixel(x1,y1,qRgb(color,color,color));
flagBuf[x1][y1] = 1;
for(int step = -1; step<=1; step+=2)
{
x1 = pos[0] + step;
y1 = pos[1];
while(x1>=0 && x1 < image->width())
{
color2 = QColor(image->pixel(x1,y1));
if(abs(color2.red() - nowColor[0])<delta && abs(color2.green() - nowColor[1])<delta && abs(color2.blue() - nowColor[2])<delta)
{
image->setPixel(x1,y1,qRgb(color,color,color));
flagBuf[x1][y1] = 1;
color2 = QColor(image->pixel(x1,y1-1));
if(y1>0 && flagBuf[x1][y1 -1] == 0 && abs(color2.red() - nowColor[0])<delta && abs(color2.green() - nowColor[1])<delta && abs(color2.blue() - nowColor[2])<delta)
{
tempStack[stk]=x1;
tempStack[stk +1] = y1-1;
stk +=2;
}
color2 = QColor(image->pixel(x1,y1+1));
if(y1<image->height() - 1 && flagBuf[x1][y1+1] == 0 && abs(color2.red() - nowColor[0])<delta && abs(color2.green() - nowColor[1])<delta && abs(color2.blue() - nowColor[2])<delta)
{
tempStack[stk]=x1;
tempStack[stk +1] = y1+1;
stk +=2;
}
x1+=step;
}
else
break;
}
}
tempStack[stk]=-1;
int k =0;
for(int i = 0;i<sk;i+=2)
{
x = stack[i];
y= stack[i+1];
if(flagBuf[x][y] == 0)
{
stack[k] = stack[i];
stack[k+1] = stack[i+1];
k+=2;
}
}
sk = k;
int i = 0;
while(tempStack[i]!=-1)
{
stack[sk]=tempStack[i];
stack[sk+1]=tempStack[i+1];
sk+=2;
i+=2;
}
}
return image;
}
3.项目源码下载:
整套算法系列:
https://blog.csdn.net/u013289254/category_12811658.html?spm=1001.2014.3001.5482https://blog.csdn.net/u013289254/category_12811658.html?spm=1001.2014.3001.5482项目源码下载地址:关注WX【AI街潜水的八角】,回复【qt图像算法】即可下载
整套项目源码内容包含
标签:int,image,调包,像素,算法,图像,y1,x1 From: https://blog.csdn.net/u013289254/article/details/143090575[1].根据算法原理,编写纯c++源码,不调用外源库opencv 等;
[2].包括各种图像处理的基本算法,包含腐蚀膨胀,缩放,转置,镜像,平移,均衡变化,灰度拉升,灰度阈值,灰度非线性,转灰度,灰度线性,旋转,简单平滑,高斯平滑,轮廓跟踪,种子算法,hough直线检测,拉普拉斯,带方向边缘检测,常规边缘检测(梯度算子、Roberts算子和Sobel算子),中值滤波,反色操作等;
[3].程序中有完整的注释,便于大家很好理解代码。