Re: векторизация

From
Andrew Vlasov ()
To
Alexei Zaycev ()
Date
2003-01-22T15:53:51Z
Area
RU.ALGORITHMS
From: "Andrew Vlasov" <vlas@dicomp.ru>

    Считаем пихел квадратным(не точка), состояние обхода соотвественно пара
((x,y),dir),соображаем как двигаться по границам пихелов в области  -
получаеся простейший конечный автомат!

Вырезка из программы (as its)
Здесь:
интерфайс к Image:
    CSize Image::Size();
        размер картинки (в пихелах)
    CSize  Image::BSize();
         разность адресов соседних пихелов (в байтах) по X и по по Y
    int Image::BPix();
         размер пихела (в байтах)
    BYTE* PixA0();
        адрес пихелa (0,0)
    BYTE* PixA(const CSize& pt);
        адрес пихелa (x,y)

enum SC
{
 SC_LEFT=0,
 SC_DOWN=1,
 SC_RIGHT=2,
 SC_UP=3
};

inline int L(int iDir)
{
 //ASSERT_INRANGE(iDir,0,4);
 if(iDir==3)
  return 0;
 else
  return iDir+1;
}

inline int R(int iDir)
{
 //ASSERT_INRANGE(iDir,0,4);
 if(iDir==0)
  return 3;
 else
  return iDir-1;
}

inline CSize V(int iDir)
{
 //ASSERT_INRANGE(iDir,0,4);
 switch(iDir)
 {
  case SC_LEFT:
   return CSize(-1,0);
  case SC_DOWN:
   return CSize(0,1);
  case SC_RIGHT:
   return CSize(1,0);
  case SC_UP:
  default:
   return CSize(0,-1);
 }
}
inline int Ofs(const CSize& siB,int iDir)
{
 //ASSERT_INRANGE(iDir,0,4);
 switch(iDir)
 {
  case SC_LEFT:
   return -siB.cx;
  case SC_DOWN:
   return siB.cy;
  case SC_RIGHT:
   return siB.cx;
  case SC_UP:
  default:
   return -siB.cy;
 }
}

template<class Image,class Out>
CPoint ScanMaskBorder(Image& rIm,const CRect2& rcBnd,const CPoint& _pt,int
_iDir,Out& out,BYTE mask=1)
//ptStart - point on border
//siDir - is CCW direction at ptStart
{
 CSize si=rIm.Size();
 CSize siB=rIm.BSize();
 ASSERT(rIm.BPix()==4);

 CPoint ptS=_pt;
 BYTE* pS=rIm.PixA(ptS);
 int iDirS=_iDir;

 CPoint pt=ptS;
 BYTE* p=pS;
 int iDir=iDirS;

 CPoint ptInside(INT_MAX,INT_MAX);
 //int n=0;
 //TRACE("\n");
 //Out
 p[3]=mask;
 out<<pt;
 do
 {
  //TRACE("iDir=%d\n",iDir);

  //Dirs
  int lDir=L(iDir);
  int rDir=R(iDir);

  //Inside
  if((p+Ofs(siB,lDir))[3])
   ptInside=pt+V(lDir);
  //not valid - mask inside may be 0!

  //debug
  //ASSERT(rIm.PixA(pt)[3]);
  //ASSERT(!(p+Ofs(siB,rDir))[3]);
  //ASSERT(rIm.PixA(pt+V(rDir))==(rIm.PixA(pt)+Ofs(siB,rDir)));
  //p[2]=255;
  //p[1]=0;
  //p[0]=0;

  //next
  BYTE* p0=p+Ofs(siB,iDir);
  //ASSERT(rIm.PixA(pt+V(iDir))==p0);
  BYTE* p1=p0+Ofs(siB,rDir);
  //ASSERT(rIm.PixA(pt+V(iDir)+V(rDir))==p1);

  int iState=!!(p0[3])+((!!(p1[3]))<<1);
  switch(iState)
  {
   case 0:
   case 2:
    iDir=lDir;
    break;
   case 1:
    pt+=V(iDir);
    p=p0;
    //Out
    p[3]=mask;
    out<<pt;
    break;
   case 3:
    pt+=V(iDir)+V(rDir);
    p=p1;
    iDir=rDir;
    //Out
    p[3]=mask;
    out<<pt;
    break;
  }
  //ASSERT(rIm.PixA(pt)==p);
  //ASSERT(rcBnd.Include(pt));
  //if(p==pS)
  //{
  // TRACE("iDirS=%d,iDir=%d\n",iDirS,iDir);
  //}
 }
 while(!((p==pS)&&(iDirS==iDir)));
 //ASSERT(rcBnd.Include(ptInside));
 return ptInside;
}

"Alexei Zaycev" <azaycev@karelia.ru> wrote in message
news:b0j92j$pr1$1@atv.karelia.ru...
> Привет, All!
>
> Имеется растровая картинка, содержащая некоторый _непрерывный_ контур.
> Требуется перевести такую байду в ломаную, заданную в векторном виде.
> Какими методами пользуется All в таком случае?
>
> ЗЫ. Заранее thanx...
>
> С уважением, Алексей.
> email: azaycev@karelia.ru     ICQ:111705967
>


--- ifmail v.2.15dev5
 * Origin: Comcor (2:5020/400)