Xem mẫu
- PHỤ LỤC - XỬ LÝ ẢNH
Phụ lục gồm listing chương trình trình bày một cách chi tiết các định dạng
ảnh: BMP, PCX, TIFF, GIF,... và các môđul chương trình thực hiện các công đoạn
của quá trình xử lý ảnh. Chương trình được viết trên C và Visual C và có thể coi như
một công cụ đơn giản minh hoạ các bước của xử lý ảnh. Các ảnh minh hoạ trong
cuốn sách này lấy từ kết quả thực hiện chương trình trên.
1. Nhóm chương trình nạp và lưu ảnh
Việc nạp ảnh từ tệp vào mảng số và lưu ảnh từ mảng lên tệp là cần thiết
cho mọi chức năng xử lý. Chính vì thế, phần chương trình có tổ chức 2 moduls riêng:
- BMP.H: Thực hiện việc mở và đọc ảnh số từ “tệp *.BMP” vào “mảng” 2
chiều.
- PCX.H: Thực hiện việc mở và đọc ảnh số từ “tệp *.PCX” vào “mảng” 2
chiều.
ề BMP.H
// Chứa các khai báo về file ảnh BMP & các thủ tục mở file. //
typedef unsigned int WORD;
typedef unsigned long DWORD;
typedef unsigned char BYTE;
typedef struct tagBITMAPFILEHEADER
{
WORD bfType;
DWORD bfSize;
WORD bfReserved1;
WORD bfReserved2;
DWORD bfoffBits;
} BITMAPFILEHEADER;
typedef struct tagBITMAPINFOHEADER
{
DWORD biSize;
long biWidth;
long biHeight;
WORD biPlanes;
WORD biBitCount;
DWORD biCompression;
NhËp m«n xö lý ¶nh sè §HBK Hµ néi
11
- PHỤ LỤC - XỬ LÝ ẢNH
DWORD biSizeImage;
long biXPelsPerMeter;
long biYPelsPerMeter;
DWORD biClrUsed;
DWORD biClrImportant;
} BITMAPINFOHEADER;
typedef struct tagRGBQUAD
{
BYTE rgbBlue;
BYTE rgbGreen;
BYTE rgbRed;
BYTE rgbReserved;
} RGBQUAD;
BYTE huge *InImage;
unsigned long p,chieucao,chieurong;
int OpenBitmapFile(char *fname,int *fh,
BITMAPFILEHEADER *bmfhd,
BITMAPINFOHEADER *bmihd);
int ReadBitmapPalette(int fh, int numcl, RGBQUAD *bmpals);
int GetScanLine(int fh, int BytePerLine, BITMAPINFOHEADER
*bih, int x, int y);
void SetRGBPalette(int index,int red ,int green,int blue);
void SetRGBPalettes(int index, int red, int green, int blue);
int GetBitmapToArray(char *fname);
extern void Error(unsigned OrderError);
//***************************************** //
//Mở file bitmap //
int OpenBitmapFile(char *fname,int *fh,BITMAPFILEHEADER
*bmfhd, BITMAPINFOHEADER *bmihd)
{int tmp;
*fh = _open(fname,O_RDONLY);
if(*fh == -1) return -1; // không mở được file
tmp = _read(*fh,bmfhd,sizeof(BITMAPFILEHEADER));
if (tmp == -1)
{ close(*fh); return -1;// lỗi đọc file
}
if(bmfhd->bfType != 0x4D42)
NhËp m«n xö lý ¶nh sè §HBK Hµ néi
12
- PHỤ LỤC - XỬ LÝ ẢNH
{
close(*fh);
return -2 ;// không phải dạng BMP
}
tmp = _read(*fh,bmihd,sizeof(BITMAPINFOHEADER));
if(tmp != sizeof(BITMAPINFOHEADER))
{
close(*fh);
return -2 ;//không phải dạng BMP
}
if (bmihd->biCompression == 0)
{
bmihd->biSizeImage = (bmfhd->bfSize-bmfhd-
>bfoffBits);
}
return 0;
} //end of function
//******************************************************** //
//Đọc bảng màu file bitmap //
int ReadBitmapPalette(int fh,int numcl,RGBQUAD *bmpals)
{
int numbyte,tmp;
numbyte=numcl*sizeof(RGBQUAD);
lseek(fh,sizeof(BITMAPFILEHEADER)
+sizeof(BITMAPINFOHEADER), SEEK_SET);
tmp=_read(fh,(void*)bmpals,numbyte);
if (tmp == -1)
{ close(fh);return -1;
}
if(tmp!=numbyte)
{close(fh);return -2;
}
return 0;
} // end of function
//******************************************//
int GetScanLine(int fh,int BytePerLine,BITMAPINFOHEADER *bih)
//Đọc dòng ảnh vào mảng //
NhËp m«n xö lý ¶nh sè §HBK Hµ néi
13
- PHỤ LỤC - XỬ LÝ ẢNH
{
BYTE *buff;
int tmp,ppb,mask,i,j,cx,nb,cl;
buff=(BYTE *)malloc(BytePerLine+1);
if(buff==NULL)
{return -3; //Không đủ bộ nhớ
}
tmp=_read(fh,buff,BytePerLine);
if(tmp != BytePerLine)
{return -1;
}
ppb=8/bih->biBitCount;
mask=(1 biBitCount)-1;
for(i=0,cx=0;i (bih->biBitCount * (ppb-1-j));
cl=cl & mask;
InImage[p++]= cl;
if(cx == bih->biWidth) break;
}
if(cx >= bih->biWidth) break;
}
free(buff); return 0;
}
//****************************************//
void SetRGBPalette(int index,int red ,int green,int blue)
{
int r,g,b,cl;
red >>= 6; r=(red & 1) = 6; g= (green & 1) >= 6; b= (blue & 1) > 1;
cl=r+g+b;
_AX=0x1000;
_BL=index;
_BH=cl;
geninterrupt(0x10);
NhËp m«n xö lý ¶nh sè §HBK Hµ néi
14
- PHỤ LỤC - XỬ LÝ ẢNH
}
//***************************************** //
void SetRGBPalettes(RGBQUAD *pals,int numcl)
{
int i;
for(i=0;irgbRed,(pals+i) ->rgbGreen,
(pals+i) - >rgbBlue);
}
}
//********************************************* //
// Đọc File BMP vào mảng bộ nhớ //
int GetBitmapToArray(char *fname)
{
int i,j,tmp,numcolor,BytePerLine,bmfilehand;
BITMAPINFOHEADER bminfohdr;
BITMAPFILEHEADER bmfilehdr;
RGBQUAD *bmpalettes;
tmp=OpenBitmapFile(fname,&bmfilehand,&bmfilehdr,
&bminfohdr);
chieucao= bminfohdr.biHeight;
chieurong= bminfohdr.biWidth;
switch(tmp)
{case -1: return(1); //break; //không mở được file
case -2: return(2); //break; //lỗi file
}
numcolor=1
- PHỤ LỤC - XỬ LÝ ẢNH
if((InImage =(BYTE huge *)
farcalloc(bminfohdr.biHeight*bminfohdr.biWidth,
sizeof(BYTE)))==NULL)
return(3);
p= 0;
for(i=0;i
- PHỤ LỤC - XỬ LÝ ẢNH
#define ECorrupt -5
#define EWrtFileHdr -6
#define EWrtOutFile -7
#define EWrtScanLine -8
#define EPCCFile -9
#define PCXHdrTag 0x0A
#define MaxRepCount 0x3F
#define PCX256ColorTag 0x0C
typedef struct
{
BYTE Red;
BYTE Green;
BYTE Blue;
}ColorRegister;
struct PCXFileHeader
{
BYTE Header;
BYTE Version;
BYTE Encode;
BYTE BitPerPix;
unsigned X1;
unsigned Y1;
unsigned X2;
unsigned Y2;
unsigned Hres;
unsigned Vres;
};
struct PCXInfo
{
BYTE Vmode;
BYTE NumOfPlanes;
unsigned BytesPerLine;
BYTE unused[60];
};
struct ExtendedPalette
{
BYTE ExtendedPalette;
NhËp m«n xö lý ¶nh sè §HBK Hµ néi
17
- PHỤ LỤC - XỬ LÝ ẢNH
ColorRegister Palette[MAX256PALETTECOLORS];
};
struct PCX_File
{
struct PCXFileHeader PCXHeader;
ColorRegister Palette[MAXPALETTECOLORS];
struct PCXInfo Info;
} PCX_FileType;
int looping;
struct PCX_File PCXData;
unsigned ImageWidth,ImageHeight;
FILE *PCXFile;
BYTE ScanLine[MAXBYTESPERSCAN];
BYTE PixelColorNum[MAXSCREENWIDTH];
struct ExtendedPalette Color256Palette;
unsigned ImageWidth,ImageHeight,NumOfPlanes;
unsigned Is256ColorFile=FALSE;
struct PCX_File PCXData;
int ReadPCXFileHdr(char *Filename,int Verbose);
static int ExpandScanLine(FILE *InFile);
unsigned InstallPCXFilePalette(void);
void DisplayPCXFile(char *FileName,int Verbose);
void Set256ColorMode(void);
void interrupt (*oldkb)();
void interrupt newkb();
int Gwrite(int x,int y,char *gtext,int inc)
{
WriteXYB(x,y,gtext,1,1,15,0,0,0);
return (x+inc+textwidth(gtext));
}
int GwriteDel(int x,int y,char *gtext,int inc)
{
WriteXYB(x,y,gtext,1,1,0,0,0,0);
return (x+inc+textwidth(gtext));
}
int Gwriteln(int x,int y,char *gtext)
{
NhËp m«n xö lý ¶nh sè §HBK Hµ néi
18
- PHỤ LỤC - XỬ LÝ ẢNH
WriteXYB(x,y,gtext,1,1,15,0,0,0);
return (y+10+textheight(gtext));
}
char *Gread(int x,int y)
{
char *gtext,text[2];
char ch;
gtext[0]=0x0;
do
{
ch=getch();
if (ch!=Enter)
{
if (ch!=BackSpace)
{
text[0]=ch;text[1]='\0';
x=Gwrite(x,y,text,0);
strcat(gtext,text);
}
else
if (strcmp(gtext,""))
{
text[0]=gtext[strlen(gtext)-1];text[1]='\0';
x=x-textwidth(text);
x=GwriteDel(x,y,"Û",0);
x=x-textwidth(text);
gtext[strlen(gtext)-1]='\0';
}
}
} while (ch!=Enter);
return gtext;
}
void interrupt newkb()
{
if(inportb(0x60)==1) looping=0;
oldkb();
}
NhËp m«n xö lý ¶nh sè §HBK Hµ néi
19
- PHỤ LỤC - XỬ LÝ ẢNH
void Set256ColorMode(void)
{
union REGS regs;
regs.h.ah=0;
regs.h.al=0x13;
int86(VIDEO,®s,®s);
}
int ReadPCXFileHdr(char *Filename,int Verbose)
{
unsigned Index,i;
int row=100,col=100;
for(i=0;i
- PHỤ LỤC - XỬ LÝ ẢNH
printf("\tY1: %d\n",PCXData.PCXHeader.Y1);
printf("\tX2: %d\n",PCXData.PCXHeader.X2);
printf("\tY2: %d\n",PCXData.PCXHeader.Y2);
printf("\tHoriz Resolution: %d\n",PCXData.PCXHeader.Hres);
printf("\tVert Resolution: %d\n",PCXData.PCXHeader.Vres);
printf("\tVmode: %d\n",PCXData.Info.Vmode);
printf("\tNumber of Planes: %d\n",PCXData.Info.NumOfPlanes);
printf("\tByte per Scan Line of Plane :%d\n"
,PCXData.Info.BytesPerLine);
printf("\n\tHit any key to proceed");
getch();
clrscr();
if
((PCXData.PCXHeader.Hres==320)&&(PCXData.PCXHeader.Vres==
200)&&
(PCXData.Info.NumOfPlanes==1))
Is256ColorFile=TRUE;
printf("\n\tColor Register Value of PCX file: %s\n\n",Filename);
if (Is256ColorFile)
for(Index=0;Index
- PHỤ LỤC - XỬ LÝ ẢNH
printf("\tPalette[ %X ] : R=%6X G=%6X B=%6X
\n",Index,PCXData.Palette[Index].Red,
PCXData.Palette[Index].Green,PCXData.Palette[Index].Blue);
}
printf("\n\tHit any key to continue");
getch();
}
return(NoError);
}
static int ExpandScanLine(FILE *InFile)
{
register short BitNum;
register unsigned ByteNum;
register short CharRead;
unsigned InPtr,RepCount,PixelsData;
unsigned BytesToRead,PlaneNum;
unsigned ByteOffset,BitOffset;
BytesToRead=PCXData.Info.NumOfPlanes*PCXData.Info.BytesPerLi
ne;
InPtr=0;
do
{
CharRead=getc(InFile);
if(CharRead==EOF) return(FALSE);
if((CharRead & 0xC0)==0xC0)
{
RepCount=CharRead & ~0xC0;
CharRead=getc(InFile);
if(CharRead==EOF) return(FALSE);
while (RepCount--) ScanLine[InPtr++] = CharRead;
}
else
ScanLine[InPtr++]=CharRead;
} while (InPtr < BytesToRead);
return(TRUE);
}
NhËp m«n xö lý ¶nh sè §HBK Hµ néi
22
- PHỤ LỤC - XỬ LÝ ẢNH
unsigned InstallPCXFilePalette(void)
{
struct palettetype palette;
union REGS regs;
unsigned Index;
if(PCXData.PCXHeader.Version!=3)
{
if(Is256ColorFile)
{
for (Index=0;Index>=2;
Color256Palette.Palette[Index].Green>>=2;
Color256Palette.Palette[Index].Blue>>=2;
}
regs.h.ah=0x10;
regs.h.al=0x12;
regs.x.bx=0;
regs.x.cx=MAX256PALETTECOLORS;
_ES=FP_SEG(&Color256Palette.Palette);
regs.x.dx=FP_OFF(&Color256Palette.Palette);
int86(VIDEO,®s,®s);
return(TRUE);
}
else
{
palette.size=MAXPALETTECOLORS;
for (Index=0;Index>=2;
PCXData.Palette[Index].Green>>=2;
PCXData.Palette[Index].Blue>>=2;
}
regs.h.ah=0x10;
regs.h.al=0x12;
regs.x.bx=0;
NhËp m«n xö lý ¶nh sè §HBK Hµ néi
23
- PHỤ LỤC - XỬ LÝ ẢNH
regs.x.cx=MAXPALETTECOLORS;
_ES=FP_SEG(&PCXData.Palette);
int86(VIDEO,®s,®s);
setallpalette(&palette);
return(TRUE);
}
}
else return(FALSE);
}
void DisplayPCXFile(char *FileName,int Verbose)
{
int i;
BYTE far *PtrScreen;
register unsigned ScanNum;
register unsigned ColNum;
unsigned OffsetDisplay,BytePerLine;
int PCXError,color,Plane;
long CurrentPos;
if((PCXError=ReadPCXFileHdr(FileName,Verbose))!
=NoError)exit(PCXError);
if((PCXData.PCXHeader.X1!=0) || (PCXData.PCXHeader.Y1!=0))
{
printf("\nError PCC file not PCX file\n");
exit(EPCCFile);
}
if(PCXData.PCXHeader.X2==319)
{
Set256ColorMode();
ImageWidth = 320;
ImageHeight= 200;
}
else
{
ImageWidth=640;
switch(PCXData.PCXHeader.Y2)
{
NhËp m«n xö lý ¶nh sè §HBK Hµ néi
24
- PHỤ LỤC - XỬ LÝ ẢNH
case 479: setgraphmode(VGAHI);
ImageHeight=480;break;
case 349: setgraphmode(VGAMED);
ImageHeight=350;break;
case 199: setgraphmode(VGALO);
ImageHeight=200;break;
}
}
CurrentPos=ftell(PCXFile);
fseek(PCXFile,-769,SEEK_END);
if(fread(&Color256Palette.ExtendedPalette,
sizeof(struct ExtendedPalette) ,1,PCXFile)==TRUE)
if(Color256Palette.ExtendedPalette==PCX256ColorTag)
Is256ColorFile=TRUE;
InstallPCXFilePalette();
fseek(PCXFile,CurrentPos,SEEK_SET);
for(ScanNum=0;ScanNum
- PHỤ LỤC - XỬ LÝ ẢNH
outp(0x3C5,1
- PHỤ LỤC - XỬ LÝ ẢNH
//* ************************* //
void WriteText(int *x,int *y,char *s)
{ settextjustify(1,1);
outtextxy(*x,*y,s);
settextjustify(0,2);
*x+=textwidth(s); }
//------------------------------------------------//
void ReadText(int *x,int *y,char *s)
{int i=0;char ch[2];
ch[1]=0;
while(1)
{ch[0]=getch();
if((ch[0]==ENTER)||(ch[0]==ESCAPE)) break;
settextjustify(1,1);
WriteText(x,y,ch);
settextjustify(0,2);
s[i]=ch[0];++i;
} s[i]=0;}
//------------------------------------------------//
void Message(char *st,char *st1,int thongtin)
{ int x,y,y1= 190;
void far *q; unsigned kt;
int trai= (getmaxx()/2)-(textwidth(st)/2)-10;
int cao= 100; int phai= (getmaxx()/2)+(textwidth(st)/2)+10;
kt= imagesize(trai,y1,phai,y1+cao);
if((q=(unsigned far*)farmalloc(kt))== NULL)
{outtextxy(70,465,"Không còn vùng nhớ cho cất màn hình !");
exit(1);
}
getimage(trai,y1,phai,y1+cao,q);
button("",0,trai,y1,phai,y1+cao,2,15,15,0,7);
rectangle(trai+1,y1+1,phai-1,y1+cao-1);
rectangle(trai+3,y1+3,phai-3,y1+cao-3);
y= y1+18;x= getmaxx()/2;
WriteText(&x,&y,st1);
y= y+textheight(st1)+19;x= getmaxx()/2;
WriteText(&x,&y,st);line(trai+3,y-13,phai-3,y-13);
NhËp m«n xö lý ¶nh sè §HBK Hµ néi
27
- PHỤ LỤC - XỬ LÝ ẢNH
if(thongtin==1)
{ y= y+textheight(st)+15; x= getmaxx()/2-30;
ReadText(&x,&y,fname);
}
getch();
putimage(trai,y1,q,COPY_PUT);
farfree((unsigned far*)q);
}
//------------------------------------------------------------//
void Warning(void)
{ int x,y,y1= 190;
char *st,*st1;
st=" *** Process Running - Please wait ! ***";
st1="WARNING !!!";
int trai= (getmaxx()/2)-(textwidth(st)/2)-10;
int cao= 80; int phai= (getmaxx()/2)+(textwidth(st)/2)+10;
button("",0,trai,y1,phai,y1+cao,2,15,15,0,7);
rectangle(trai+1,y1+1,phai-1,y1+cao-1);
rectangle(trai+3,y1+3,phai-3,y1+cao-3);
y= y1+22;x= getmaxx()/2;
WriteText(&x,&y,st1);
y= y+textheight(st1)+25;x= getmaxx()/2;
WriteText(&x,&y,st);line(trai+3,y-17,phai-3,y-17);
}
PROCESS.H
// Chứa các thao tác chính : Hiện ảnh, Lọc TB, Trung bình KG, Lọc
Trung vị,
//Lọc Sobel, Lọc Homomorphie
int Averaging(BYTE huge *Image,unsigned cotbd,unsigned
hangbd,unsigned rong, unsigned cao,unsigned avecol,
unsigned averow,double *matran);
void DipslayImageInBuf(BYTE huge *Image,unsigned hang,
unsigned cot);
void DipslayPCXInBuf(BYTE huge *Image,unsigned hang,
unsigned cot);
BYTE ReadPixel(BYTE huge *Image,unsigned cot,unsigned hang);
NhËp m«n xö lý ¶nh sè §HBK Hµ néi
28
- PHỤ LỤC - XỬ LÝ ẢNH
void WritePixel(BYTE huge *Image,unsigned hang,unsigned
cot,unsigned color);
void MedianFilter(BYTE huge *Image,unsigned hangbd,unsigned
cotbd, unsigned rong,unsigned cao);
int Averaging(BYTE huge *Image,unsigned cotbd,unsigned hangbd,
unsigned rong, unsigned cao,unsigned avecol, unsigned averow,
double *matran);
int SpatialConvolution(BYTE huge *Image,unsigned cotbd,
unsigned hangbd, unsigned rong,unsigned cao, unsigned KernelCol,
unsigned KernelRow, short *Kernel);
extern void Error(unsigned OrderError);
extern void Message(char *st,char *st1,int thongtin);
void Threshold(BYTE huge *Image,unsigned col,unsigned row,
unsigned rong,unsigned cao);
//**************************************************//
//Hiển thị ảnh BMP //
void DipslayImageInBuf(BYTE huge *Image,unsigned hang,unsigned
cot)
{ int i,j;
unsigned long p;
p= 0;
for(i= cot;i>0;i--)
for(j=0;j< hang;j++)
{
putpixel(j,i,Image[p++]);
}
}
//******************************************************//
//Đọc 1 pixel từ buffer
BYTE ReadPixel(BYTE huge *Image,unsigned cot,unsigned hang)
{unsigned long p;
p= hang;
p*= chieurong;
p+= cot;
return(Image[p]);}
//Ghi 1 pixel vào buffer
NhËp m«n xö lý ¶nh sè §HBK Hµ néi
29
- PHỤ LỤC - XỬ LÝ ẢNH
void WritePixel(BYTE huge *Image,unsigned hang,unsigned
cot,unsigned color)
{ unsigned long p;
if ((cot
nguon tai.lieu . vn