📄 分水岭算法源码.txt
字号:
//作者:纪荣嵘
//email:jirongrong1983@yahoo.com.cn
//哈尔滨工程大学
//请各位大虾多多指正
// 在视频分割中基于数学形态理论的分水岭(watershed)算法被广泛使用,//它又称水线算法,其基本过程是连续腐蚀二值图像,由图像简化、标记提取、//决策、后处理四个阶段构成。分水岭算法具有运算简单、性能优良,能够较好//提取运动对象轮廓、准确得到运动物体边缘的优点。但分割时需要梯度信息,//对噪声较敏感,且未利用帧间信息,通常会产生图像过度分割。
#define SIZE 10000
//定义一个队列
typedef struct
{
int q[SIZE];
int front;
int rear;
}queue;
//image_in:输入图像数据指针
//image_out:输出图像数据指针
//image_d:距离图像数据指针
//image_mask:标记图像指针
//图像分割中的分水岭算法
void Watershed(BYTE *image_in, int xsize, int ysize,BYTE* image_d ,BYTE *image_mask,BYTE* image_out)
{
const BYTE MASK = -2;
const BYTE WSHED = 0;
int Current_Dist = -1;
int Current_Label = 0;
queue* QU = new queue[1] ;
int i,j,k,l,m,n,p1,p2,x,y;
BYTE temp = 254;
for(i = 0;i<SIZE;i++)
QU->q[i] = 0;
QU->front = 0;
QU->rear = 0;
for(i = 0;i<xsize;i++)
for(j = 0;j<ysize;j++)
{
*(image_out+j*xsize+i) = *(image_in+j*xsize+i);
}
//置标记初始值为0
for(k = 0;k<xsize;k++)
for(l = 0;l<ysize;l++)
{
*(image_mask+l*xsize+k) = 0;
}
//置距离图像的初始值为0
for(i = 0;i<xsize;i++)
for(j = 0;j<ysize;j++)
{
*(image_d+j*xsize+i) = 0;
}
//像素前处理(没办法啊,只能牺牲局部保全整体了)
for(k = 0;k<xsize;k++)
for(l = 0;l<ysize;l++)
{
if(*(image_out+j*xsize+i) == 255)
*(image_out+j*xsize+i) = 254;
}
//根据像素的值,对输入图像进行升序排列
for(k = 0;k<xsize;k++)
for(l = 0;l<ysize;l++)
{
for(i = 0;i<xsize;i++)
for(j = 0;j<ysize;j++)
{
if(*(image_out+j*xsize+i)<=temp )
{
*(image_mask+l*xsize+k) = j*xsize+i;
temp = *(image_out+j*xsize+i);
}
}
*(image_out+*(image_mask+l*xsize+k)) = 255;
temp = 254;
}
//置输出图像的初始值为-1
for(i = 0;i<xsize;i++)
for(j = 0;j<ysize;j++)
{
*(image_out+j*xsize+i) = -1;
}
int h = 0;
for(k = 0;k<xsize;k++)
for(l = 0;l<ysize;l++)
{
if(*(image_in+*(image_mask+l*xsize+k)) == h)
{
label1: *(image_out+*(image_mask+l*xsize+k)) = MASK;
for(m = 1;m<xsize-1;m++)
for(n = 1;n<ysize-1;n++)
{
if(*(image_out+(n-1)*xsize+(m-1)) == MASK
||*(image_out+(n-1)*xsize+m) == MASK
||*(image_out+(n-1)*xsize+(m+1)) == MASK
||*(image_out+n*xsize+(m-1)) == MASK
||*(image_out+n*xsize+(m+1)) == MASK
||*(image_out+(n+1)*xsize+(m-1)) == MASK
||*(image_out+(n+1)*xsize+m) == MASK
||*(image_out+(n+1)*xsize+(m+1))==MASK)
{
//距离图像imd(p) = 1
*(image_d+n*xsize+m) = 1;
//将点p进入队列
{
QU->rear = (QU->rear+1)%SIZE;
QU->q[QU->rear] = *(image_mask+n*xsize+m);
}
}
}
//当前距离设置为1
Current_Dist = 1;
//将虚拟像素送入队列
const int VPIXEL = -100;
{
QU->rear = (QU->rear+1)%SIZE;
QU->q[QU->rear] = VPIXEL;
}
for(;;)
{
//队列中第一个点出队列给p
{
QU->front = (QU->front+1)%SIZE;
*(image_mask+l*xsize+k) = QU->q[QU->front];
}
if(*(image_mask+l*xsize+k) == VPIXEL)
{
//如果队列空,则退出循环
if(QU->front == QU->rear)
break;
//否则,将虚拟像素进队列,当前距离加1,并取出队列中第一个点
else
{
{
QU->rear = (QU->rear+1)%SIZE;
QU->q[QU->rear] = VPIXEL;
}
Current_Dist++;
{
QU->front = (QU->front+1)%SIZE;
p1 = QU->q[QU->front];
}
}
}
else
{
//对该点的八邻域处理如下
//左上点
if(*(image_d+*(image_mask+l*xsize+k)-xsize-1)<Current_Dist && (*(image_out+*(image_mask+l*xsize+k)-xsize-1)>0 || *(image_out+*(image_mask+l*xsize+k)-xsize-1) == WSHED))
{
if(*(image_out+*(image_mask+l*xsize+k)-xsize-1) >0)
{
if(*(image_out+*(image_mask+l*xsize+k)) == MASK || *(image_out+*(image_mask+l*xsize+k)) == WSHED)
*(image_out+*(image_mask+l*xsize+k)) = *(image_out+*(image_mask+l*xsize+k)-xsize-1);
else
{
if(*(image_out+*(image_mask+l*xsize+k)) != *(image_out+*(image_mask+l*xsize+k)-xsize-1))
*(image_out+*(image_mask+l*xsize+k)) = WSHED;
}
}
else
{
if(*(image_out+*(image_mask+l*xsize+k)) == -1)
{
*(image_out+*(image_mask+l*xsize+k)) = WSHED;
}
}
}
else
{
if(*(image_out+*(image_mask+l*xsize+k)-xsize-1) == MASK && *(image_d+*(image_mask+l*xsize+k)-xsize-1) == 0)
{
*(image_d+*(image_mask+l*xsize+k)-xsize-1) = Current_Dist+1;
{
QU->rear = (QU->rear+1)%SIZE;
QU->q[QU->rear] = *(image_mask+l*xsize+k)-xsize-1;
}
}
}
//左中点
if(*(image_d+*(image_mask+l*xsize+k)-xsize)<Current_Dist && (*(image_out+*(image_mask+l*xsize+k)-xsize)>0 || *(image_out+*(image_mask+l*xsize+k)-xsize) == WSHED))
{
if(*(image_out+*(image_mask+l*xsize+k)-xsize) >0)
{
if(*(image_out+*(image_mask+l*xsize+k)) == MASK || *(image_out+*(image_mask+l*xsize+k)) == WSHED)
*(image_out+*(image_mask+l*xsize+k)) = *(image_out+*(image_mask+l*xsize+k)-xsize);
else
{
if(*(image_out+*(image_mask+l*xsize+k)) != *(image_out+*(image_mask+l*xsize+k)-xsize))
*(image_out+*(image_mask+l*xsize+k)) = WSHED;
}
}
else
{
if(*(image_out+*(image_mask+l*xsize+k)) == -1)
{
*(image_out+*(image_mask+l*xsize+k)) = WSHED;
}
}
}
else
{
if(*(image_out+*(image_mask+l*xsize+k)-xsize) == MASK && *(image_d+*(image_mask+l*xsize+k)-xsize) == 0)
{
*(image_out+*(image_mask+l*xsize+k)-xsize) = Current_Dist+1;
{
QU->rear = (QU->rear+1)%SIZE;
QU->q[QU->rear] = *(image_mask+l*xsize+k)-xsize;
}
}
}
//左下点
if(*(image_d+*(image_mask+l*xsize+k)-xsize+1)<Current_Dist && (*(image_out+*(image_mask+l*xsize+k)-xsize+1)>0 || *(image_out+*(image_mask+l*xsize+k)-xsize+1) == WSHED))
{
if(*(image_out+*(image_mask+l*xsize+k)-xsize+1) >0)
{
if(*(image_out+*(image_mask+l*xsize+k)) == MASK || *(image_out+*(image_mask+l*xsize+k)) == WSHED)
*(image_out+*(image_mask+l*xsize+k)) = *(image_out+*(image_mask+l*xsize+k)-xsize+1);
else
{
if(*(image_out+*(image_mask+l*xsize+k)) != *(image_out+*(image_mask+l*xsize+k)-xsize+1))
*(image_out+*(image_mask+l*xsize+k)) = WSHED;
}
}
else
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -