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