⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 于八方向链码的边界跟踪代码.txt

📁 于八方向链码的边界跟踪代码
💻 TXT
字号:
于八方向链码的边界跟踪代码,其中nVerct数组存储的是边界点的矢量方向,Coordinate存储的是边界点的坐标。
//函数 OnProcessTrace()
void CSkagonView::OnProcessTrace() 
{
    if(DibObject.pDib==NULL) 
    {
        MessageBox("请先载入一幅位图","Error",MB_ICONERROR | MB_OK);
        return;
    }
    if(DibObject.GetNumberOfColors() != 256)
    {
        MessageBox("您处理的图片不是256色图","Error",MB_ICONERROR | MB_OK);
        return;
    }


    struct EdgePoint
    {
        BYTE nCurrenVerct;        //当前矢量,即在轮廓跟踪中的前一个搜索方向
        CPoint CurrenPoint;        //当前点的坐标
    };

    //CArray <EdgePoint,EdgePoint&> TraceArray;

    //获取位图的宽,高,以及每行字节数
    int nWidth=DibObject.GetWidth();
    int nByteWidth=DibObject.GetByteWidth();
    int nHeight=DibObject.GetHeight();

    //循环变量
    int i,j;

    //开辟一块新的空间
    BYTE *pData=new BYTE[nByteWidth*nHeight];
    memset(pData,255,nByteWidth*nHeight);

    //像素值
    unsigned char pixel;

    //是否找到起始点及回到起始点
    bool bFindStartPoint;

    //是否扫描到一个边界点
    bool bFindPoint;

    typedef struct 
    {
        int Width;
        int Height;
    }Position;

    //起始边界点与当前边界点
    Position StartPoint,CurrentPoint;

    //八个方向和起始扫描方向,依次是左上方、上方、右上方、右方、右下方、下方、左下方和左方。
    int Direction[8][2]={ {-1,1},{0,1},{1,1},{1,0},{1,-1},{0,-1},{-1,-1},{-1,0} };
    int BeginDirect;


    //先找到最左下方的边界点
    bFindStartPoint = false;
    for (j = 1;j < nHeight-1 && !bFindStartPoint;j++)
    {
        for(i = 1;i < nWidth-1 && !bFindStartPoint;i++)
        {
            //取得当前指针处的像素值
            pixel = PointOld(i,j);
            
            if(pixel == 0)
            {
                bFindStartPoint = true;
                StartPoint.Height = j;
                StartPoint.Width = i;

                // 指向目标图像倒数第j行,第i个象素的指针            
                Point(i,j) = 0;
            }        
        }
    }

    //由于起始点是在左下方,故起始扫描沿左上方向
    BeginDirect = 0;
    //跟踪边界
    bFindStartPoint = false;
            
    CurrentPoint.Height = StartPoint.Height;
    CurrentPoint.Width = StartPoint.Width;

    int index=0;
    memset(nVerct,0,9999);

    
    while(!bFindStartPoint)
    {
        //从起始点一直找边界,直到再次找到起始点为止
        bFindPoint = false;
        while(!bFindPoint)
        {
            //沿扫描方向,这里是左上方向获取一个像素
            pixel = PointOld( CurrentPoint.Width + Direction[BeginDirect][0], 
                                CurrentPoint.Height + Direction[BeginDirect][1] );
            if(pixel == 0)
            {
                bFindPoint = true;

                //存储边界点的矢量方向
                nVerct[index] = (BYTE)BeginDirect;
                //存储边界点的坐标
                Coordinate[index][0] = CurrentPoint.Width;
                Coordinate[index][1] = CurrentPoint.Height;
                index++;


                CurrentPoint.Width = CurrentPoint.Width + Direction[BeginDirect][0];
                CurrentPoint.Height = CurrentPoint.Height + Direction[BeginDirect][1];

                //如果一圈以后找到了起始点,那么边界寻找完成
                if(CurrentPoint.Height == StartPoint.Height && 
CurrentPoint.Width == StartPoint.Width)
                {
                    bFindStartPoint = true;
                }
                //将轮廓在新的位图中标示出来
                Point(CurrentPoint.Width,CurrentPoint.Height) = 0;
                //扫描的方向逆时针旋转两格
                //为什么?因为逆时针旋转三格的象素绝对不是边界,不然当前点就不会是边界。
                BeginDirect--;
                if(BeginDirect == -1)
                    BeginDirect = 7;
                BeginDirect--;
                if(BeginDirect == -1)
                    BeginDirect = 7;
            }
            else
            {
                //扫描方向顺时针旋转一格
                BeginDirect++;
                if(BeginDirect == 8)
                    BeginDirect = 0;
            }

        }
    }    

    //边界跟踪时,边界点数
    m_nNumNode =index;

    memcpy(DibObject.m_pData,pData,nByteWidth*nHeight);
    delete pData;
    FileIndex++;
    Invalidate();    //重绘
    
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -