提取骨架(细化)

来源:互联网 发布:淘宝神笔模板尺寸 编辑:程序博客网 时间:2024/04/27 16:17

BOOL IsContourP(int x,int y, IplImage *Src_Img)
{
 BOOL p[10] ={0};
 int LineBytes =Src_Img->widthStep;
 BYTE *lpPtr= (BYTE*)(Src_Img->imageData+LineBytes*y)+x;

 p[2]=*(lpPtr-LineBytes) ? true:false;
 p[3]=*(lpPtr-LineBytes+1) ? true:false;
 p[4]=*(lpPtr+1) ? true:false;
 p[5]=*(lpPtr+LineBytes+1) ? true:false;
 p[6]=*(lpPtr+LineBytes) ? true:false;
 p[7]=*(lpPtr+LineBytes-1) ? true:false;
 p[8]=*(lpPtr-1) ? true:false;
 p[9]=*(lpPtr-LineBytes-1) ? true:false;

 int Np=0;//邻域不为零节点总数
 int Tp=0;//邻域节点由0变成1的次数
 for (int i=2; i<10; i++)
 {
  Np += p[i];
  int k= (i<9) ? (i+1) : 2;
  if ( p[k] -p[i]>0)
  {
   Tp++;
  }
 }
 int p246= p[2] && p[4] && p[6];
 int p468= p[4] && p[6] && p[8];

 int p24= p[2] && !p[3] && p[4] && !p[5] && !p[6] && !p[7] && !p[8] && !p[9];
 int p46= !p[2] && !p[3] && p[4] && !p[5] && p[6] && !p[7] && !p[8] && !p[9];
 int p68= !p[2] && !p[3] && !p[4] && !p[5] && p[6] && !p[7] && p[8] && !p[9];
 int p82= p[2] && !p[3] && !p[4] && !p[5] && !p[6] && !p[7] && p[8] && !p[9];

 int p782= p[2] && !p[3] && !p[4] && !p[5] && !p[6] && p[7] && p[8] && !p[9];
 int p924= p[2] && !p[3] && p[4] && !p[5] && !p[6] && !p[7] && !p[8] && p[9];
 int p346= !p[2] && p[3] && p[4] && !p[5] && p[6] && !p[7] && !p[8] && !p[9];
 int p568= !p[2] && !p[3] && !p[4] && p[5] && p[6] && !p[7] && p[8] && !p[9];

 int p689= !p[2] && !p[3] && !p[4] && !p[5] && p[6] && !p[7] && p[8] && p[9];
 int p823= p[2] && p[3] && !p[4] && !p[5] && !p[6] && !p[7] && p[8] && !p[9];
 int p245= p[2] && !p[3] && p[4] && p[5] && !p[6] && !p[7] && !p[8] && !p[9];
 int p467= !p[2] && !p[3] && p[4] && !p[5] && p[6] && p[7] && !p[8] && !p[9];

 int p2468= p24 || p46 || p68 || p82;
 int p3333= p782 || p924 || p346 || p568 || p689 || p823 || p245 || p467;

 //判定条件第一个由数字图像处理上得到,由于结果不够满意,又加上两个条件
 return ( !p246 && !p468 && (Np<7) && (Np>1) && (Tp==1) ) || p2468 || p3333;
}


void thin( IplImage *Src_Img)//细化轮廓,得到单像素轮廓
{
 int i, j;
 CvSize img_size = cvGetSize(Src_Img);
 int Remove_Num=0;

 do //循环调用,直至没有可以去掉的点
 {
  Remove_Num=0;
  for (j = 1; j < img_size.height-1; j++)
  {
   for(i = 1; i < img_size.width-1; i++)
   {
    BYTE gray_value = ((BYTE*)(Src_Img->imageData + Src_Img->widthStep*j))[i];
    if ( gray_value && IsContourP( i, j, Src_Img))//符合条件,去掉
    {
     ((BYTE*)(Src_Img->imageData + Src_Img->widthStep*j))[i]=(UCHAR)0;
     Remove_Num++;
    }  //if
   }  //for
  }  //for
 } while( Remove_Num);
}