区域生长算法:

来源:互联网 发布:js遍历数组删除元素 编辑:程序博客网 时间:2024/04/28 05:03

/*
iwdth=320,iheight=240;  后面有实例代码

 算法中的 239-endy 。。。是因为处理的灰度值是倒的。

*/

// 不采用递归算法, 栈空间不够。

void RegionGrow( unsigned char * pUnchInput, int nThreshold,int *pflag,int &b,int start_x,int start_y,int startx,int starty,int endx,int endy)
{

//8个领域进行处理
  int nDx[]={-1,0,1,1,1,0,-1,-1};
  int nDy[]={-1,-1,-1,0,1,1,1,0};

 
 int nStart ;
 int nEnd   ;
int nSeedX, nSeedY;

 // 设置种子点为图像的中心
 nSeedX = start_x;
 nSeedY = start_y;
 pflag[nSeedY*IWidth+nSeedX] = b;
 //初始化
 nStart = 0 ;
 nEnd   = 0 ;
int * pnGrowQueX ;
 int * pnGrowQueY ;
 
 // 分配空间
 pnGrowQueX = new int [IWidth*IHeight];
 pnGrowQueY = new int [IWidth*IHeight];


 pnGrowQueX[nEnd] = nSeedX;
 pnGrowQueY[nEnd] = nSeedY;

 int nCurrX ;
 int nCurrY ;


 int k ;

 
 int xx;
 int yy;

 while (nStart<=nEnd)
 {
  // 当前种子点的坐标
  nCurrX = pnGrowQueX[nStart];
  nCurrY = pnGrowQueY[nStart]; 
 
 
  // 对当前点的8邻域进行遍历
  for (k=0; k<8; k++)
  {
  
   xx = nCurrX+nDx[k];
   yy = nCurrY+nDy[k];
  
   if ( (xx < endx) && (xx>=startx) && (yy<endy) && (yy>=starty)
        && (pflag[yy*IWidth+xx]==0)  && abs(pUnchInput[yy*IWidth+xx] - pUnchInput[nCurrY*IWidth+nCurrX])<nThreshold )
   {
    // 堆栈的尾部指针后移一位
    nEnd++;

    // 象素(xx,yy) 压入栈
    pnGrowQueX[nEnd] = xx;
    pnGrowQueY[nEnd] = yy;

   
    pflag[yy*IWidth+xx] = b ;
   }
  }

  nStart++;
 }

b++;
 // 释放内存
 delete []pnGrowQueX;
 delete []pnGrowQueY;
    pnGrowQueX = NULL ;
 pnGrowQueY = NULL ;
}
extern "C"  _declspec(dllexport)  void _stdcall Oppe_Radiate_grayEx5(BYTE *bits,int startx,int starty,int endx,int endy)

{
   
 int *flag=new int [IWidth*IHeight];
volatile  int i,j;
 
  int m=1;
 for(i=0;i<IWidth*IHeight;i++)
    flag[i]=0;
 for(j=(239-endy);j<239-starty;j++)
  for(i=startx;i<endx;i++)
{

 if(flag[j*IWidth+i]==0)
     RegionGrow(bits,10,flag,m,i,j,startx,starty,endx,endy);

}

/*

这里是对相同标计的灰度值进行求平均处理。

*/
long *sum=new long [m-1];
int  *count=new int [m-1];

for(i=0;i<m-1;i++)
{
 sum[i]=0;
 count[i]=0;
}
for(j=(239-endy);j<239-starty;j++)
  for(i=startx;i<endx;i++)
  {
   count[flag[j*IWidth+i]-1]++;
  }
for(j=(239-endy);j<239-starty;j++)
  for(i=startx;i<endx;i++)
  {
   sum[flag[j*IWidth+i]-1]+=bits[j*IWidth+i];
  }
for(i=0;i<m-1;i++)
{
 sum[i]=sum[i]/count[i];
}
for(j=(239-endy);j<239-starty;j++)
  for(i=startx;i<endx;i++)
  {
   bits[j*IWidth+i]=sum[flag[j*IWidth+i]-1];
  }
  delete []count;
delete []sum;

 delete []flag;

将一下代码放入程序中:执行   就容易理解了

#include <iostream.h>
#include <windows.h>
#define IWidth 8
#define IHeight 8

void RegionGrow( unsigned char * pUnchInput, int nThreshold,int *pflag,int &b,int start_x,int start_y,int startx,int starty,int endx,int endy)
{
  int nDx[]={-1,0,1,1,1,0,-1,-1};
  int nDy[]={-1,-1,-1,0,1,1,1,0};

 
 int nStart ;
 int nEnd   ;
int nSeedX, nSeedY;

 // 设置种子点为图像的中心
 nSeedX = start_x;
 nSeedY = start_y;
 pflag[nSeedY*IWidth+nSeedX] = b;
 //初始化
 nStart = 0 ;
 nEnd   = 0 ;
int * pnGrowQueX ;
 int * pnGrowQueY ;
 
 // 分配空间
 pnGrowQueX = new int [IWidth*IHeight];
 pnGrowQueY = new int [IWidth*IHeight];


 pnGrowQueX[nEnd] = nSeedX;
 pnGrowQueY[nEnd] = nSeedY;

 int nCurrX ;
 int nCurrY ;


 int k ;

 
 int xx;
 int yy;

 while (nStart<=nEnd)
 {
  // 当前种子点的坐标
  nCurrX = pnGrowQueX[nStart];
  nCurrY = pnGrowQueY[nStart]; 
 
 
  // 对当前点的8邻域进行遍历
  for (k=0; k<8; k++)
  {
  
   xx = nCurrX+nDx[k];
   yy = nCurrY+nDy[k];
  
   if ( (xx < endx) && (xx>=startx) && (yy<endy) && (yy>=starty)
        && (pflag[yy*IWidth+xx]==0)  && abs(pUnchInput[yy*IWidth+xx] - pUnchInput[nCurrY*IWidth+nCurrX])<nThreshold )
   {
    // 堆栈的尾部指针后移一位
    nEnd++;

    // 象素(xx,yy) 压入栈
    pnGrowQueX[nEnd] = xx;
    pnGrowQueY[nEnd] = yy;

   
    pflag[yy*IWidth+xx] = b ;
   }
  }

  nStart++;
 }

b++;
 // 释放内存
 delete []pnGrowQueX;
 delete []pnGrowQueY;
    pnGrowQueX = NULL ;
 pnGrowQueY = NULL ;
}
 void  Oppe_Radiate_grayEx5(BYTE *bits,int startx,int starty,int endx,int endy)

{
   
 int *flag=new int [IWidth*IHeight];
volatile  int i,j;
 
  int m=1;
 for(i=0;i<IWidth*IHeight;i++)
    flag[i]=0;
 for(j=(starty);j<endy;j++)
  for(i=startx;i<endx;i++)
{

 if(flag[j*IWidth+i]==0)
     RegionGrow(bits,2,flag,m,i,j,startx,starty,endx,endy);

}
   for(j=0;j<IHeight;j++)
 {
  for(i=0;i<IWidth;i++)
  {
   cout<<flag[j*IWidth+i]<<" ";
  }
  cout<<endl;
 }
  
long *sum=new long [m-1];
int  *count=new int [m-1];

for(i=0;i<m-1;i++)
{
 sum[i]=0;
 count[i]=0;
}
for(j=(starty);j<endy;j++)
  for(i=startx;i<endx;i++)
  {
   count[flag[j*IWidth+i]-1]++;
  }
for(j=(starty);j<endy;j++)
  for(i=startx;i<endx;i++)
  {
   sum[flag[j*IWidth+i]-1]+=bits[j*IWidth+i];
  }
for(i=0;i<m-1;i++)
{
 sum[i]=sum[i]/count[i];
}
for(j=(starty);j<endy;j++)
  for(i=startx;i<endx;i++)
  {
   bits[j*IWidth+i]=sum[flag[j*IWidth+i]-1];
  }
  delete []count;
delete []sum;

 delete []flag;

}

 void main()
 {
  BYTE bit[64]={ 50,50,50,50,50,50,50,50,
              50, 2, 1, 1, 2, 1, 1,50,
              50, 1, 5, 4, 5, 5, 1,50,
     50, 2, 5, 8, 9, 6, 2,50,
     50, 1, 6, 9, 8, 6, 1,50,
     50, 1, 6, 8, 9, 8, 1,50,
     50, 1, 2, 1, 1, 2, 8,50,
     50,50,50,50,50,50,50,50
   };
     BYTE *bits=new BYTE[64];
   int index=0;
  int k=1;
  int i,j;
  for(index=0;index<64;index++)
   bits[index]=bit[index];
  int *flag=new int [64];
   for(i=0;i<64;i++)
    flag[i]=0;
Oppe_Radiate_grayEx5(bits,0,0,8,8);

 /*   for(j=0;j<IHeight;j++)
 {
  for(i=0;i<IWidth;i++)
  {
   cout<<(int)bits[j*IWidth+i]<<" ";
  }
  cout<<endl;
 }
 */
 }