2005年的博

搬家到 http://blog.csdn.net/persuper/

导航

二值图像跟踪曲线程序

稍后提交一个完整的测试程序

  1
  2BOOL WINAPI TraceDIB(LPSTR lpDIBBits,LONG lWidth,LONG lHeight,CArray<CPoint,CPoint>* pPoint,CArray<int,int>* pSlope)
  3{
  4// 指向源图像的指针
  5BYTE*lpSrc;
  6
  7// 指向缓存图像的指针
  8BYTE*lpDst;
  9
 10// 指向缓存DIB图像的指针
 11BYTE*lpNewDIBBits;
 12HLOCALhNewDIBBits;
 13
 14// 图像每行的字节数
 15LONG lLineBytes=WIDTHBYTES(lWidth * 8);
 16
 17long i,j;
 18DWORD ii=0;
 19
 20BYTE pixel;
 21bool bFindStartPoint;
 22
 23//是否扫描到一个边界点
 24bool bFindPoint;
 25
 26
 27//起始边界点与当前边界点
 28CPoint StartPoint,CurrentPoint;
 29    //顺时针方向
 30int Direction[8][2]={{1,0},{1,-1},{0,-1},{-1,-1},{-1,0},{-1,1},{0,1},{1,1}};
 31int BeginDirect;
 32
 33hNewDIBBits = LocalAlloc(LHND, lLineBytes * lHeight);
 34if (hNewDIBBits == NULL)
 35{
 36// 分配内存失败
 37return FALSE;
 38}

 39lpNewDIBBits = (BYTE* )LocalLock(hNewDIBBits);
 40// 初始化新分配的内存,设定初始值为255
 41lpDst = (BYTE*)lpNewDIBBits;
 42memset(lpDst, (BYTE)255, lLineBytes * lHeight);
 43
 44
 45//先找到最左下方的边界点
 46bFindStartPoint = false;
 47for (j = 0;j < lHeight && !bFindStartPoint;j++)
 48{
 49for(i = 0;i < lWidth && !bFindStartPoint;i++)
 50{
 51// 指向源图像倒数第j行,第i个象素的指针
 52lpSrc = (BYTE *)lpDIBBits + lLineBytes * j + i;
 53
 54pixel = (BYTE)*lpSrc;
 55
 56if(pixel == 0)
 57{
 58bFindStartPoint = true;
 59
 60StartPoint.y = j;
 61StartPoint.x = i;
 62
 63// 指向目标图像倒数第j行,第i个象素的指针
 64lpDst = (BYTE *)lpNewDIBBits + lLineBytes * j + i;
 65*lpDst = (BYTE)0;
 66}

 67}

 68}

 69
 70//由于起始点是在左下方,故起始扫描沿左上方向
 71BeginDirect = 5;
 72//跟踪边界
 73bFindStartPoint = false;
 74//从初始点开始扫描
 75CurrentPoint.y = StartPoint.y;
 76CurrentPoint.x = StartPoint.x;
 77pPoint->Add(CurrentPoint);
 78// 第一个点的斜率为2 
 79pSlope->Add(int(2));
 80ii++;
 81
 82while(!bFindStartPoint)
 83{
 84bFindPoint = false;
 85while(!bFindPoint)
 86{
 87//沿扫描方向查看一个像素
 88long offset = lLineBytes * ( CurrentPoint.y + Direction[BeginDirect][1])
 89+ (CurrentPoint.x + Direction[BeginDirect][0]);
 90lpSrc = (unsigned char *)lpDIBBits + offset;
 91lpDst = (unsigned char *)lpNewDIBBits + offset;
 92pixel = (unsigned char)*lpSrc;
 93
 94if(pixel == 0&&(unsigned char)*lpDst==255)
 95{
 96bFindPoint = true;
 97CurrentPoint.y = CurrentPoint.y + Direction[BeginDirect][1];
 98CurrentPoint.x = CurrentPoint.x + Direction[BeginDirect][0];
 99pPoint->Add(CurrentPoint);
100
101// s = BeginDirect%4;
102//if(s==3)
103//s = -1;
104                //左上方代表方向的5,以后按照
105pSlope->Add(BeginDirect);//s;
106ii++;
107*lpDst = (unsigned char)0;
108//扫描的方向逆时针旋转两格
109BeginDirect--;
110if(BeginDirect == -1)
111BeginDirect = 7;
112BeginDirect--;
113if(BeginDirect == -1)
114BeginDirect = 7;
115}

116else
117{
118if(pixel!=0)
119{
120//扫描方向顺时针旋转一格
121BeginDirect++;
122if(BeginDirect == 8)
123BeginDirect = 0;
124}

125else{
126// 扫描到以扫过的点
127bFindPoint = true;
128bFindStartPoint = true;
129}

130}

131
132}

133}

134
135ASSERT(pPoint->GetSize()==ii);
136
137// 复制腐蚀后的图像
138memcpy(lpDIBBits, lpNewDIBBits, lWidth * lHeight);
139
140// 释放内存
141LocalUnlock(hNewDIBBits);
142LocalFree(hNewDIBBits);
143
144// 返回
145return TRUE;
146}

147
148

posted on 2005-05-11 19:59  迷失天堂  阅读(1291)  评论(2编辑  收藏  举报