区域生长算法

来源:互联网 发布:个体营业执照查询软件 编辑:程序博客网 时间:2024/05/17 02:41

区域生长算法一般有3个步骤

1、选择合适的生长点

2、确定相似性准则即生长准则

3、确定生长停止条件


matlab实现

function J = regionGrow(I)

% 区域生长,需要以交互方式设定初始种子点,具体方法为鼠标单击图像中一点后,按下回车键
%
% 输入:I - 原图像
% 输出:J - 输出图像


if isinteger(I)
    I=im2double(I);
end
figure,imshow(I),title('原始图像')
[M,N]=size(I);
[y,x]=getpts;             %获得区域生长起始点
x1=round(x);            %横坐标取整
y1=round(y);            %纵坐标取整
seed=I(x1,y1);           %将生长起始点灰度值存入seed中
J=zeros(M,N);          %作一个全零与原图像等大的图像矩阵J,作为输出图像矩阵
J(x1,y1)=1;             %将J中与所取点相对应位置的点设置为白
sum=seed;              %储存符合区域生长条件的点的灰度值的和
suit=1;                 %储存符合区域生长条件的点的个数
count=1;               %记录每次判断一点周围八点符合条件的新点的数目
threshold=0.15;         %阈值,注意需要和double类型存储的图像相符合
while count>0
    s=0;                   %记录判断一点周围八点时,符合条件的新点的灰度值之和
     count=0;
     for i=1:M
       for j=1:N
         if J(i,j)==1
          if (i-1)>0 & (i+1)<(M+1) & (j-1)>0 & (j+1)<(N+1)  %判断此点是否为图像边界上的点
           for u= -1:1                               %判断点周围八点是否符合阈值条件
            for v= -1:1
              if  J(i+u,j+v)==0 & abs(I(i+u,j+v)-seed)<=threshold& 1/(1+1/15*abs(I(i+u,j+v)-seed))>0.8
                           J(i+u,j+v)=1;
                    %判断是否尚未标记,并且为符合阈值条件的点
                    %符合以上两条件即将其在J中与之位置对应的点设置为白
                 count=count+1;
                 s=s+I(i+u,j+v);                      %此点的灰度之加入s中
              end
            end
           end
          end
         end
       end
     end
    suit=suit+count;                                   %将n加入符合点数计数器中
    sum=sum+s;                                     %将s加入符合点的灰度值总合中
    seed=sum/suit;                                    %计算新的灰度平均值

end



vc实现

/**************************************************
BOOL CImgProcess::RegionGrow(CImgProcess * pTo , int nSeedX, int nSeedY, BYTE bThre)


功能:
区域生长算法


参数:
CImgProcess * pTo
指向输出图像的指针
int nSeedX, int nSeedY
种子点的坐标值
BYTE bThre
生长时使用的阈值
返回值:
布尔类型,true为成功,false为失败
***************************************************/


BOOL CImgProcess::RegionGrow(CImgProcess * pTo , int nSeedX, int nSeedY, BYTE bThre)
{
if (m_pBMIH->biBitCount!=8) return false;


if ((nSeedX<0)||(nSeedX>GetWidthPixel())) return false;
if ((nSeedY<0)||(nSeedY>GetHeight())) return false;


pTo->InitPixels(0);
pTo->SetPixel(nSeedX, nSeedY, RGB(255, 255, 255));


// 生长起始点灰度
BYTE bSeed = GetGray(nSeedX, nSeedY);
// 生长区域灰度值之和
long int lSum = bSeed;
// 生长区域的点总数和每次八邻域中符合条件点个数
int nSuit = 1, nCount = 1;

// 开始区域生长循环操作
while (nCount > 0)
{
nCount = 0;


for (int i=1; i<GetHeight()-1; i++)
{ // 纵向
for (int j=1; j<GetWidthPixel()-1; j++)
{ // 横向
if (pTo->GetGray(j, i)==255)
{ // 是种子点
// 开始8邻域扫描
for (int m=i-1; m<=i+1; m++)
{
for (int n=j-1; n<=j+1; n++)
{
// 判断是否符合阈值条件且未标记
if ((pTo->GetGray(n, m)==0)&&(abs(GetGray(n, m)-bSeed)<=bThre))
{
pTo->SetPixel(n, m, RGB(255, 255, 255));
nCount++;
lSum += GetGray(n, m);
}
}
}
}
}
}


nSuit += nCount;


// 计算新种子值(这里使用改进的种子值算法为已标记区域的平均灰度)
bSeed = lSum / nSuit;
}


return true;
}

0 0
原创粉丝点击