我对图像处理没有一点经验,谢谢各位大虾指点。对黑白位图,我想做一个灰度依次变化的膨胀,并且膨胀的大小能够参数化。
(这样表述可能不准确,赫赫)比如,对黑白位图,有字或图形的地方,设其象素值为0,没字的地方就是255,
那如何在字或图形的轮廓外加一个过渡(长度可设定,如1mm),使得灰度值从0逐渐变化到255。如能有相关代码,更不甚感谢!
[email protected]

解决方案 »

  1.   

    ///////BMP.H文件////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////
    #include "windows.h"
    #define IDM_LOADBMP   1
    #define IDM_EXIT      2 #define IDM_HDILATION                   40025
    #define IDM_VDILATION                   40026
    #define IDM_HEROSION                    40027
    #define IDM_VEROSION                    40028
    #define IDM_HOPEN                       40031
    #define IDM_VOPEN                       40032
    #define IDM_HCLOSE                      40033
    #define IDM_VCLOSE                      40034
    #define IDM_THINNING                    40035
    #define IDC_STATIC                      65535
    ////////////////////////////////////////////////////////////////////////////
    ///bmp.rc文件///////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////
    #include "bmp.h"
    /////////////////////////////////////////////////////////////////////////////
    //
    // Menu
    //BMPMENU MENU DISCARDABLE 
    BEGIN
        POPUP "File"
        BEGIN
            MENUITEM "Open",                        IDM_LOADBMP
            MENUITEM "Exit",                        IDM_EXIT
        END
        POPUP "Morph"
        BEGIN
            POPUP "Dilation"
            BEGIN
                MENUITEM "Horizontal",                  IDM_HDILATION
                MENUITEM "Vertical",                    IDM_VDILATION
            END
            POPUP "Erosion"
            BEGIN
                MENUITEM "Horizontal",                  IDM_HEROSION
                MENUITEM "Vertical",                    IDM_VEROSION
            END
            POPUP "Open"
            BEGIN
                MENUITEM "Horizontal",                  IDM_HOPEN
                MENUITEM "Vertical",                    IDM_VOPEN
            END
            POPUP "Close"
            BEGIN
                MENUITEM "Horizontal",                  IDM_HCLOSE
                MENUITEM "Vertical",                    IDM_VCLOSE
            END
            MENUITEM SEPARATOR
            MENUITEM "Thinning",                    IDM_THINNING
        END
    END
      

  2.   

    //////////////////////////////////////////////////////////////
    //Name:morph.c
    //Purpose: To perform morphological operation
    //Author: phoenix, CS, TshingHua, Beijing, P.R.C.
    //Email: [email protected] or [email protected]
    //Date:April 3, 1998//header file
    #include "bmp.h"
    #include "memory.h"
    #include "math.h"
    #include "stdio.h"
    //owner defined stack
    typedef struct{
      HGLOBAL hMem;
         POINT *lpMyStack;
      LONG  ElementsNum;
      LONG  ptr;
      }MYSTACK;
    //macro definition
    #define WIDTHBYTES(i)    ((i+31)/32*4)
    #define PI 3.1415926535
    #define RADIAN(angle) ((angle)*PI/180.0) //convert angle to radian//function declaration
    int PASCAL WinMain (HANDLE, HANDLE, LPSTR, int);
    LRESULT CALLBACK MainWndProc(HWND , UINT,WPARAM, LPARAM);
    BOOL LoadBmpFile (HWND hWnd,char *BmpFileName);
    BOOL Dilation(HWND hWnd,BOOL Hori);
    BOOL Erosion(HWND hWnd,BOOL Hori);
    BOOL MorphOpen(HWND hWnd,BOOL Hori);
    BOOL MorphClose(HWND hWnd,BOOL Hori);
    BOOL Thinning(HWND hWnd);
    //global variable declaration
    BITMAPFILEHEADER   bf;
    BITMAPINFOHEADER   bi;
    HPALETTE           hPalette=NULL;
    HBITMAP            hBitmap=NULL;
    HGLOBAL            hImgData=NULL;
    DWORD              NumColors;
    DWORD              LineBytes;
    HINSTANCE          ghInst;
    DWORD              ImgWidth=0 , ImgHeight=0;
    ///////////////////////////////////////////////////////////
    int PASCAL WinMain (HANDLE hInstance, HANDLE hPrevInstance,
        LPSTR lpszCmdLine, int nCmdShow)
    {
    MSG       msg;
    WNDCLASS  wndclass;
    HWND      hWnd; ghInst=hInstance;
    if ( ! hPrevInstance ){
    wndclass.style = CS_HREDRAW | CS_VREDRAW;
    wndclass.lpfnWndProc = MainWndProc;
    wndclass.cbClsExtra = 0;
    wndclass.cbWndExtra = 0;
    wndclass.hInstance = hInstance;
    wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION);
    wndclass.hCursor = LoadCursor (NULL, IDC_ARROW);
    wndclass.hbrBackground = GetStockObject (WHITE_BRUSH);
    wndclass.lpszMenuName =  "BMPMENU";
    wndclass.lpszClassName = "phoenix ip system";
        }    if ( ! RegisterClass (&wndclass) )
    return FALSE;
     
    hWnd = CreateWindow ("phoenix ip system","Morphological operation",
     WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,CW_USEDEFAULT,
     CW_USEDEFAULT, CW_USEDEFAULT, NULL,NULL,
     hInstance, NULL);
    if (!hWnd)
    return FALSE;
    ShowWindow (hWnd, SW_SHOWMAXIMIZED);
    UpdateWindow (hWnd);

    while ( GetMessage (&msg, NULL, 0, 0) ){
    TranslateMessage (&msg);
    DispatchMessage (&msg);
        } return msg.wParam;
    }
      

  3.   

    for(y=1;y<dibHeight-1;y++)
    {
    lpPtr=(char *)hImgData+sizeof(BITMAPFILEHEADER)+(BufSize-LineBytes-y*LineBytes)+1;
    lpTempPtr=(char *)hTempImgData+sizeof(BITMAPFILEHEADER)+(BufSize-LineBytes-y*LineBytes)+1;
    for(x=1;x<dibWidth-1;x++)
    {
    nTemp=(unsigned char)*lpPtr;
    if (nTemp==255)
    {
    *lpTempPtr=(unsigned char)255; num[0][0]=(unsigned char)*(lpPtr+(-1)*LineBytes-1);
    num[0][1]=(unsigned char)*(lpPtr+(-1)*LineBytes);
    num[0][2]=(unsigned char)*(lpPtr+(-1)*LineBytes+1);
    num[1][0]=(unsigned char)*(lpPtr-1);
    num[1][1]=(unsigned char)*(lpPtr);
    num[1][2]=(unsigned char)*(lpPtr+1);
    num[2][0]=(unsigned char)*(lpPtr+LineBytes-1);
    num[2][1]=(unsigned char)*(lpPtr+LineBytes);
    num[2][2]=(unsigned char)*(lpPtr+LineBytes+1); nTemp = (num[0][0]
    && num[0][1]
    && num[0][2]
    && num[1][0]
    && num[1][1]
    && num[1][2]
    && num[2][0]
    && num[2][1]
    && num[2][2]); if( nTemp == 0 )
    *lpTempPtr=(unsigned char)0; }
    else *lpTempPtr=(unsigned char)0;
    lpPtr++;
    lpTempPtr++;
    }
    }上面是一般膨胀的例子,其中num[][]是模板,只需如下改动就可以实现
    nTemp = (num[0][0]!=255)
       && (num[0][1]!=255)
       && (num[0][2]!=255)
       && (num[1][0]!=255)
       && (num[1][1]!=255)
       && (num[1][2]!=255)
       && (num[2][0]!=255)
       && (num[2][1]!=255)
       && (num[2][2]!=255));if( nTemp == 0 )
    *lpTempPtr=(unsigned char)k;//0<k<255为渐变效果的控制参数,膨胀完一次后k增加