输出数组oi[Row][Col]=输出图像(灰度图像)输入参数=变换前区间两端点输入参数=变换后区间两端点算法流程图如下:g(x,y)=zzba*(f(x, y)-a)+cf(x, y)>b?输出图像g(x, y)输入f(x,y)zzba=g(x, y)=d图像<a?(c-d) / (b-a)f(x, y)g (x, y)=c图3-3图像直方图的线性变换图像直方图3.灰度图像直方图的对数变换算法流程当灰度图像f的各象素点f(x,y)的值域在区间[a,b)(a<b)上时,可将它按自然对数变换到区间[c,d](c<d)上,从而求得输出图像g。因此算法的功能是把输入图像区间[a,b]对数变换到输出图像的灰度区间[c,d],灰度值为0时,用一个很小的数eps置换后再计算对数值。输入数组ii[Row][Col]=输入图像输出数组oi[Row][Co]]=输出图像输入参数=变换前区间两端点输入参数=变换后区间两端点算法流程图如下:求最大计算gg=(d-c)/(logb-logc)[logf(x,y)-loga]+c输入图像和最小f(x,y)和灰度值参数c,da,b输出图像g(x,y)=gg+0.5图3-4图像直方图对数变换图像直方图14
14 输出数组 oi[Row][Col]=输出图像(灰度图像) 输入参数=变换前区间两端点 输入参数=变换后区间两端点 算法流程图如下: 图 3-3 图像直方图的线性变换图像直方图 3.灰度图像直方图的对数变换算法流程 当灰度图像 f 的各象素点 f(x,y)的值域在区间[a,b](a<b)上时,可将它按自然对数 变换到区间[c,d](c<d)上,从而求得输出图像 g。因此算法的功能是把输入图像区间[a,b] 对数变换到输出图像的灰度区间[c,d],灰度值为 0 时,用一个很小的数 eps 置换后再计 算对数值。 输入数组 ii[Row][Col]=输入图像 输出数组 oi[Row][Col]=输出图像 输入参数=变换前区间两端点 输入参数=变换后区间两端点 算法流程图如下: 图 3-4 图像直方图对数变换图像直方图 输入 图像 f(x,y) zzba= (c-d)/(b-a) f(x,y) <a? f(x,y) >b? g(x,y)=c g(x,y)=d g(x,y)=zzba* (f(x,y)-a)+c 输出 图像 g(x,y) 输入图像 f(x,y) 和 参数 c,d 求 最 大 和 最 小 灰 度 值 a,b 计算 gg=(d-c)/(logb-logc)[logf(x,y)-loga]+c 输出图像 g(x,y)=gg+0.5
三、实验前准备1:预习本实验中关于图像直方图灰度变换的基本原理;2.了解本实验的目的和实验内容。四、实验内容1:根据图像直方图线性变换处理的方法和流程,利用C编写图像直方图线性变换处理的程序;2.给定一幅BMP图像,用所编程序对给定图像进行操作,对图像处理后另存为(*.bmp)文件;3.本实验完成灰度的线性变换处理,如有时间再做灰度图像直方图的对数变换。五、实验报告要求1:总结图像直方图变换处理的原理和方法:2.总结对图像直方图线性变换处理编程的过程:3.对实验结果进行分析。六、参考程序图像灰度线性变换参考程序/*参数值Width影像宽度Heighe影像高度Color图像数据本程序输入、输出都为无压缩8BitBMP文件,对图像文件的大小不限程序中min对应变换前的灰度a,max对应变换前的灰度b,zl对应变换后的灰度c,z2对应变换后的灰度d。使用方法:执行文件名输入文件名.bmp输出文件名.bmp其中输入文件和输出文件都放在与执行文件相同的目录下*(1)灰度线性变换原程序#include<stdio.h>15
15 三、实验前准备 1.预习本实验中关于图像直方图灰度变换的基本原理; 2.了解本实验的目的和实验内容。 四、实验内容 1.根据图像直方图线性变换处理的方法和流程,利用 C 编写图像直方图线性变换处理的 程序; 2.给定一幅 BMP 图像,用所编程序对给定图像进行操作,对图像处理后另存为(*.bmp) 文件; 3.本实验完成灰度的线性变换处理,如有时间再做灰度图像直方图的对数变换。 五、实验报告要求 1.总结图像直方图变换处理的原理和方法; 2.总结对图像直方图线性变换处理编程的过程; 3.对实验结果进行分析。 六、参考程序 图像灰度线性变换参考程序 /*参数值 Width 影像宽度 Heighe 影像高度 Color 图像数据 本程序输入、输出都为无压缩 8Bit BMP 文件,对图像文件的大小不限 程序中 min 对应变换前的灰度 a,max 对应变换前的灰度 b,z1 对应变换后的灰度 c, z2 对应变换后的灰度 d。 使用方法: 执行文件名 输入文件名.bmp 输出文件名.bmp 其中输入文件和输出文件都放在与执行文件相同的目录下*/ (1)灰度线性变换原程序 #include <stdio.h>
#include<conio.h>#include<stdlib.h>typedef structchar bfType[2];1longbfSize;int bfReservedl;int bfReserved2;long bfoffBits;BITMAPFILEHEADER;typedef structlong biSize,1long biWidth;long biHighth,int biPlanes;int biBitCount;longbiCompress;longbiSizelmage;long biXpelsPerMeter,long biYpelsPerMeter,long biClrUsed;long biClrlmportant;BITMAPINFOHEADER;typedef struct tagRGBQUADunsigned char rgbBlue;unsigned char rgbGreen;unsigned char rgbRed;unsigned char rgbReserved,IRGBQUAD,unsigned int width,depth,unsigned int d,w,i.j;unsigned char color,datal;main(int argc,char *argv[)4FILE*fp;16
16 #include <conio.h> #include <stdlib.h> typedef struct { char bfType[2]; long bfSize; int bfReserved1; int bfReserved2; long bfoffBits; }BITMAPFILEHEADER; typedef struct { long biSize; long biWidth; long biHighth; int biPlanes; int biBitCount; long biCompress; long biSizeImage; long biXpelsPerMeter; long biYpelsPerMeter; long biClrUsed; long biClrImportant; }BITMAPINFOHEADER; typedef struct tagRGBQUAD { unsigned char rgbBlue; unsigned char rgbGreen; unsigned char rgbRed; unsigned char rgbReserved; }RGBQUAD; unsigned int width,depth; unsigned int d,w,i,j; unsigned char color,data1; main(int argc,char *argv[]) { FILE *fp;
FILE*FL2:unsigned int G[255];float zzba,int max,min,dd.g1,g2,z1,z2BITMAPFILEHEADER FileHeader:BITMAPINFOHEADERInfoHeader,RGBQUADrgbquad;/*读取/写入表头信息*/if(argc/=3)1printf("Usage:bmpinputfile.bmpoutputile.bmpln");printf("Error inputformat");exit(0),-if(fp=fopen(argv[1],"rb"))--NULL)1printf("Cannot open the file1.bmpln");getchO);exit(1),if(fread((char*)&FileHeader,1,sizeof(BITMAPFILEHEADER),fp)I=sizeof(BITMAPFILEHEADER))tprintf("%s read error 256color.bmpln");getchO;exit(1);if(fread((char*)&InfoHeader,1,sizeof(BITMAPINFOHEADER),fp)!=sizeof(BITMAPINFOHEADER))1printf("%s read error 256color.bmpln");getchO;exit(1),17
17 FILE *FL2; unsigned int G[255]; float zzba; int max,min,dd,g1,g2,z1,z2; BITMAPFILEHEADER FileHeader; BITMAPINFOHEADER InfoHeader; RGBQUAD rgbquad; /*读取/写入表头信息*/ if(argc!=3) { printf("Usage:bmp inputfile.bmp outputfile.bmp\n"); printf("Error inputformat"); exit(0); } if((fp=fopen(argv[1],"rb"))==NULL) { printf("Cannot open the file1.bmp\n"); getch(); exit(1); } if(fread((char*)&FileHeader,1,sizeof(BITMAPFILEHEADER),fp) !=sizeof(BITMAPFILEHEADER)) { printf("%s read error 256color.bmp\n"); getch(); exit(1); } if(fread((char*)&InfoHeader,1,sizeof(BITMAPINFOHEADER),fp) !=sizeof(BITMAPINFOHEADER)) { printf("%s read error 256color.bmp\n"); getch(); exit(1); }
if(FileHeader.bfType!="BM")printf("Please input BMP fileln");getchO);exit(1);if(InfoHeader.biCompress!=0)1printf("Only supports non_compressed BMP fileln"),getchO;exit(1),1if(InfoHeader.biBitCount!=8)printf("%s id not a 256 BMP file 256color.bmpln");getch(O);exit(1);FL2=fopen(argv[2],"wb");fwrite((char*)&FileHeader,1,sizeof(BITMAPFILEHEADER),FL2);fwrite(char*)&InfoHeader,1,sizeof(BITMAPINFOHEADER),FL2);width-InfoHeader.biWidth;depth-InfoHeader.biHighth:nn=(width+3)/4*4;d=depth;/*读取/写入调色盘资料*/for(i=0;i<256;i++)tfread((char*)&rgbquad,1,sizeof(RGBQUAD),fp),fwrite(char*)&rgbquad,1,sizeof(RGBQUAD),FL2);/*读取/写入影像资料,并进行直方图统计*fseek(fp,FileHeader.bfoffBits,SEEKSET)fseek(FL2,FileHeader.bfoffBits,SEEK_SET),18
18 if(FileHeader.bfType!="BM") { printf("Please input BMP file\n"); getch(); exit(1); } if(InfoHeader.biCompress!=0) { printf("Only supports non_compressed BMP file\n"); getch(); exit(1); } if(InfoHeader.biBitCount!=8) { printf("%s id not a 256 BMP file 256color.bmp\n"); getch(); exit(1); } FL2=fopen(argv[2],"wb"); fwrite((char*)&FileHeader,1,sizeof(BITMAPFILEHEADER),FL2); fwrite((char*)&InfoHeader,1,sizeof(BITMAPINFOHEADER),FL2); width=InfoHeader.biWidth; depth=InfoHeader.biHighth; nn=(width+3)/4*4; d=depth; /*读取/写入调色盘资料*/ for(i=0;i<256;i++) { fread((char*)&rgbquad,1,sizeof(RGBQUAD),fp); fwrite((char*)&rgbquad,1,sizeof(RGBQUAD),FL2); } /*读取/写入影像资料,并进行直方图统计*/ fseek(fp,FileHeader.bfoffBits,SEEK_SET); fseek(FL2,FileHeader.bfoffBits,SEEK_SET);