最近一直在做位图矢量化的课题,经过大量的查阅资料和代码下载,自己也拼凑一部分代码基本上实现了:先灰度处理,在中值滤波,sobel边缘检测,二值化等,得到一个二值图片。下一步打算用传说中的八邻域法进行轮廓提取,但是小弟没有具体的算法,希望哪位大侠路过赏脸,给小弟一个比较好的算法,另外如果有一条直线的时候使用这种方法难免出现中间掏空的现象,而我只是要其中的直线,该怎么做?谢谢您的观贴!

解决方案 »

  1.   

    BOOL Outline(HWND hWnd)
    {
    DWORD                 BufSize;
        LPBITMAPINFOHEADER  lpImgData;
    LPSTR                   lpPtr;
    HLOCAL                hTempImgData;
    LPBITMAPINFOHEADER  lpTempImgData;
    LPSTR                   lpTempPtr;
    HDC                     hDc;
    HFILE                   hf;
    LONG                   x,y;
    int             num;
    int                   nw,n,ne,w,e,sw,s,se;
    //我们处理的实际上是256级灰度图,不过只用到了0
    和255两种颜色。
    if( NumColors!=256){ 
         MessageBox(hWnd,"Must be a mono bitmap with grayscale palette!",
    "Error Message",MB_OK|MB_ICONEXCLAMATION);
            return FALSE;
    }
    //原图缓冲区的大小
    BufSize=bf.bfSize-sizeof(BITMAPFILEHEADER);
    //为新图缓冲区分配内存
    if((hTempImgData=LocalAlloc(LHND,BufSize))==NULL)
        {
         MessageBox(hWnd,"Error alloc memory!","Error Message",MB_OK|
    MB_ICONEXCLAMATION);
            return FALSE;
        }
        lpImgData=(LPBITMAPINFOHEADER)GlobalLock(hImgData);    
    lpTempImgData=(LPBITMAPINFOHEADER)LocalLock(hTempImgData);
    //拷贝头信息和位图数据
    memcpy(lpTempImgData,lpImgData,BufSize);
    for (y=1;y<bi.biHeight-1;y++){ //注意y的范围是从1到高度-2
    //lpPtr指向原图数据,lpTempPtr指向新图数据
    lpPtr=(char *)lpImgData+(BufSize-LineBytes-y*LineBytes);
    lpTempPtr=(char *)lpTempImgData+(BufSize-LineBytes-y*LineBytes);
    for (x=1;x<bi.biWidth-1;x++){
    if(*(lpPtr+x)==0){ //是个黑点
    //查找八个相邻点
    nw=(unsigned char)*(lpPtr+x+LineBytes-1);
    n=(unsigned char)*(lpPtr+x+LineBytes);
    ne=(unsigned char)*(lpPtr+x+LineBytes+1);
    w=(unsigned char)*(lpPtr+x-1);
    e=(unsigned char)*(lpPtr+x+1);
    sw=(unsigned char)*(lpPtr+x-LineBytes-1);
    s=(unsigned char)*(lpPtr+x-LineBytes);
    se=(unsigned char)*(lpPtr+x-LineBytes+1);
    num=nw+n+ne+w+e+sw+s+se;
    if(num==0) //说明都是黑点
    *(lpTempPtr+x)=(unsigned char)255; //删除该黑点
    }
    }
    }
        if(hBitmap!=NULL)
        DeleteObject(hBitmap);
    hDc=GetDC(hWnd);
    //创立一个新的位图
    hBitmap=CreateDIBitmap(hDc, (LPBITMAPINFOHEADER)lpTempImgData, 
       (LONG)CBM_INIT,(LPSTR)lpTempImgData+sizeof(BITMAPINFOHEADER) +
       NumColors*sizeof(RGBQUAD),(LPBITMAPINFO)lpTempImgData, DIB_RGB_COLORS);
    hf=_lcreat("c:\\outline.bmp",0);
    _lwrite(hf,(LPSTR)&bf,sizeof(BITMAPFILEHEADER)); 
    _lwrite(hf,(LPSTR)lpTempImgData,BufSize);
    _lclose(hf);
    //释放内存和资源
      ReleaseDC(hWnd,hDc);
    LocalUnlock(hTempImgData);
    LocalFree(hTempImgData);
    GlobalUnlock(hImgData);
    return TRUE;
    }