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)