计算机图像处理实验汇编.docx
《计算机图像处理实验汇编.docx》由会员分享,可在线阅读,更多相关《计算机图像处理实验汇编.docx(25页珍藏版)》请在冰豆网上搜索。
![计算机图像处理实验汇编.docx](https://file1.bdocx.com/fileroot1/2023-7/17/b6987eec-bd87-42b4-9f5e-b138215283ad/b6987eec-bd87-42b4-9f5e-b138215283ad1.gif)
计算机图像处理实验汇编
位图文件信息的提取和二值化处理
实验步骤:
1.拷贝MinGW文件夹至C:
(路径为C:
\MinGW)
2.编辑setc.bat文件,然后运行此批处理以设置路径。
3.编辑hdr.h和hdr.c文件
4.编辑bmphdr.c文件,然后在当前文件路径下,使用DOS命令:
gcc-chdr.c//编译,生成hdr.o目标文件
gcc-cbmphdr.c//编译,生成bmphdr.o目标文件
gcc-obmphdr.exehdr.obmphdr.o//链接,生成bmphdr.exe执行文件
使用bmphdr.exe来提取某一个bmp文件的头信息,例如:
bmphdrtest.bmp
5.编辑ez.c文件(用于图像的二值化处理),然后
gcc-cez.c//编译,生成ez.o目标文件
gcc-oez.exehdr.oez.o//链接,生成ez.exe执行文件
使用ez.exe文件来对某一个bmp文件进行二值化处理。
例如:
eztest.bmpresult.bmp108(对test.bmp文件进行二值化处理,阈值为108,处理的结果为result.bmp文件)
hdr.h文件内容:
#ifndef__HDR_H__
#define__HDR_H__
structbmphdr{
charsignature[2];
intsize;
shortreserved[2];
intoffset;
inthdr_size;
intwidth;
intheight;
shortnr_planes;
shortbits_per_pixel;
intcompress_type;
intdata_size;
intresol_hori;
intresol_vert;
intnr_colors;
intimportant_color;
charinfo[1024];
};
structbmphdr*get_header(charfilename[]);
#endif
hdr.c文件内容:
#include
#include
#include"hdr.h"
structbmphdr*get_header(charfilename[])
{
FILE*fp;
structbmphdr*hdr;
fp=fopen(filename,"rb");
if(!
fp){
printf("Fileopenerrororsuchfiledoesnotexist!
\n");
returnNULL;
}
hdr=(structbmphdr*)malloc(sizeof(structbmphdr));
fread(hdr->signature,2,1,fp);
if(hdr->signature[0]!
='B'||hdr->signature[1]!
='M'){
printf("Notabmpfile!
\n");
returnNULL;
}
fread(&hdr->size,4,1,fp);
fread(hdr->reserved,4,1,fp);
fread(&hdr->offset,4,1,fp);
fread(&hdr->hdr_size,4,1,fp);
fread(&hdr->width,4,1,fp);
fread(&hdr->height,4,1,fp);
fread(&hdr->nr_planes,2,1,fp);
fread(&hdr->bits_per_pixel,2,1,fp);
fread(&hdr->compress_type,4,1,fp);
fread(&hdr->data_size,4,1,fp);
fread(&hdr->resol_hori,4,1,fp);
fread(&hdr->resol_vert,4,1,fp);
fread(&hdr->nr_colors,4,1,fp);
fread(&hdr->important_color,4,1,fp);
if(hdr->offset>54)
fread(&hdr->info,1024,1,fp);
fclose(fp);
returnhdr;
}
bmphdr.c文件内容:
#include
structbmphdr{
charsignature[2];
intsize;
shortreserved[2];
intoffset;
inthdr_size;
intwidth;
intheight;
shortnr_planes;
shortbits_per_pixel;
intcompress_type;
intdata_size;
intresol_hori;
intresol_vert;
intnr_colors;
intimportant_color;
}header;
intmain(intargc,char*argv[])
{
FILE*fp;
if(argc!
=2){
printf("Usage:
%s\n",argv[0]);
exit
(1);
}
fp=fopen(argv[1],"r");
if(!
fp){
printf("Fileopenerrororsuchfiledoesnotexist!
\n");
exit
(1);
}
fread(header.signature,2,1,fp);
if(header.signature[0]!
='B'||header.signature[1]!
='M'){
printf("Notabmpfile!
\n");
exit
(1);
}
fread(&header.size,4,1,fp);
fread(header.reserved,4,1,fp);
fread(&header.offset,4,1,fp);
fread(&header.hdr_size,4,1,fp);
fread(&header.width,4,1,fp);
fread(&header.height,4,1,fp);
fread(&header.nr_planes,2,1,fp);
fread(&header.bits_per_pixel,2,1,fp);
fread(&press_type,4,1,fp);
fread(&header.data_size,4,1,fp);
fread(&header.resol_hori,4,1,fp);
fread(&header.resol_vert,4,1,fp);
fread(&header.nr_colors,4,1,fp);
fread(&header.important_color,4,1,fp);
fclose(fp);
printf("signature%c%c\n",header.signature[0],header.signature[1]);
printf("size%d\n",header.size);
printf("offset%d\n",header.offset);
printf("hdr_size%d\n",header.hdr_size);
printf("width%d\n",header.width);
printf("height%d\n",header.height);
printf("nr_planes%d\n",header.nr_planes);
printf("bits_per_pixel%d\n",header.bits_per_pixel);
printf("compress_type%d\n",press_type);
printf("data_size%d\n",header.data_size);
printf("resol_hori%d\n",header.resol_hori);
printf("resol_vert%d\n",header.resol_vert);
printf("nr_colors%d\n",header.nr_colors);
printf("important_color%d\n",header.important_color);
printf("\n");
return0;
}
二值化程序ez.c文件内容:
#include
#include
#include
#include"hdr.h"
structbmphdr*hdr;
unsignedchar*bitmap,*to;
charbuf[2048];
intmain(intargc,char*argv[])
{
inti,j,k,nr_pixels;
FILE*fp,*fpnew;
unsignedg;
if(argc!
=4){
printf("Usage:
%s\n",argv[0]);
exit
(1);
}
hdr=get_header(argv[1]);
if(!
hdr)exit
(1);
fp=fopen(argv[1],"rb");
if(!
fp){
printf("Fileopenerror!
\n");
exit
(1);
}
fseek(fp,hdr->offset,SEEK_SET);
nr_pixels=hdr->width*hdr->height;
bitmap=malloc(nr_pixels);
fread(bitmap,nr_pixels,1,fp);
fclose(fp);
k=atoi(argv[3]);
to=malloc(nr_pixels);
memset(to,0,nr_pixels);
for(i=0;ito[i]=bitmap[i]>(unsignedchar)k?
255:
0;
fpnew=fopen(argv[2],"wb+");
if(!
fpnew){
printf("Filecreateerror!
\n");
exit
(1);
}
fwrite(hdr->signature,2,1,fpnew);
fwrite(&hdr->size,4,1,fpnew);
fwrite(hdr->reserved,4,1,fpnew);
fwrite(&hdr->offset,4,1,fpnew);
fwrite(&hdr->hdr_size,4,1,fpnew);
fwrite(&hdr->width,4,1,fpnew);
fwrite(&hdr->height,4,1,fpnew);
fwrite(&hdr->nr_planes,2,1,fpnew);
fwrite(&hdr->bits_per_pixel,2,1,fpnew);
fwrite(&hdr->compress_type,4,1,fpnew);
fwrite(&hdr->data_size,4,1,fpnew);
fwrite(&hdr->resol_hori,4,1,fpnew);
fwrite(&hdr->resol_vert,4,1,fpnew);
fwrite(&hdr->nr_colors,4,1,fpnew);
fwrite(&hdr->important_color,4,1,fpnew);
if(hdr->offset>54)
fwrite(hdr->info,hdr->offset-54,1,fpnew);
fwrite(to,nr_pixels,1,fpnew);
fclose(fpnew);
free(hdr);
free(bitmap);
return0;
}
直方图均衡化
直方图均衡化实质上是减少图象的灰度级以换取对比度的加大
例如:
假设原图的灰度分布级为126(最大为256,也就是从0到255的级上的灰度都有或多或少的出现),经过直方图均衡化后,灰度分布级别将会小于126。
编程的时候请按照直方图均衡化公式进行。
#include
#include
#include
#include"hdr.h"
structbmphdr*hdr;
//定义用于直方图变量
unsignedchar*bitmap,new_color[256];
//定义计算灰度分布,灰度累计分布的数组
intcount[256],acum[256];
intmain(intargc,char*argv[])
{
//定义整数i,j用于函数循环时的,nr_pixels为图像中像素的个数
inti,j,nr_pixels;
//定义两个文件指针分别用于提取原图像的数据和生成直方图均衡化后的图像
FILE*fp,*fpnew;
//定义主函数的参数包括:
输入的位图文件名和输出的位图文件名,此处内容可以不要,在DOS下执行命令的时候再临时输入也可,为了方便演示,我这里直接把函数的参数确定了。
argc=3;
argv[1]="test.bmp";
argv[2]="testzf.bmp";
//参数输入出错显示
if(argc!
=3){
printf("pleaseinputthenameofinputandoutbitmapfiles\n");
exit
(1);
}
//获取位图文件相关信息
hdr=get_header(argv[1]);
if(!
hdr)exit
(1);
//以二进制可读方式打开输入位图文件
fp=fopen(argv[1],"rb");
if(!
fp){
printf("Fileopenerror!
\n");
exit
(1);
}
//文件指针指向数据区域
fseek(fp,hdr->offset,SEEK_SET);
//计算位图像素的个数
nr_pixels=hdr->width*hdr->height;
bitmap=malloc(nr_pixels);
//读取位图数据到bitmap中
fread(bitmap,nr_pixels,1,fp);
fclose(fp);
memset(count,0,sizeof(count));
//计算每个灰度级上像素的个数结果存入count[]数组中
for(i=0;i<=nr_pixels;i++)
{
for(j=0;j<=256;j++)
if(bitmap[i]==j)
count[j]++;
}
memcpy(acum,count,sizeof(acum));
//计算灰度的累计分布
for(i=1;i<256;i++)
acum[i]+=acum[i-1];
//灰度直方图的均衡化(核心程序部分,请仔细分析)为了方便大家编程实现,这里直接给出了源代码,本实验最核心的部分就在这里
for(i=0;i<256;i++)
{
new_color[i]=acum[i]*255/acum[255];
}
//对所有的像素灰度值按照均衡化得到的灰度对应规则进行转换,结果存入bitmap[]中
for(i=0;i{
bitmap[i]=new_color[bitmap[i]];
}
//打开一个以输出文件名命名的文件,设为可写的二进制形式
fpnew=fopen(argv[2],"wb+");
//由于位图文件的头部信息并没有因直方图均衡化而改变,因此输出图像的头部信息从原位图文件中拷贝即可:
fwrite(hdr->signature,2,1,fpnew);
fwrite(&hdr->size,4,1,fpnew);
fwrite(hdr->reserved,4,1,fpnew);
fwrite(&hdr->offset,4,1,fpnew);
fwrite(&hdr->hdr_size,4,1,fpnew);
fwrite(&hdr->width,4,1,fpnew);
fwrite(&hdr->height,4,1,fpnew);
fwrite(&hdr->nr_planes,2,1,fpnew);
fwrite(&hdr->bits_per_pixel,2,1,fpnew);
fwrite(&hdr->compress_type,4,1,fpnew);
fwrite(&hdr->data_size,4,1,fpnew);
fwrite(&hdr->resol_hori,4,1,fpnew);
fwrite(&hdr->resol_vert,4,1,fpnew);
fwrite(&hdr->nr_colors,4,1,fpnew);
fwrite(&hdr->important_color,4,1,fpnew);
if(hdr->offset>54)
fwrite(hdr->info,(hdr->offset-54),1,fpnew);
//直方图均衡化的数据(bitmap)赋值
fwrite(bitmap,nr_pixels,1,fpnew);
//关闭
fclose(fpnew);
//释放内存(优化程序必需)
free(hdr);
free(bitmap);
return0;
}
邻域平均法(box模板)和中值滤波处理
设计程序,分别用邻域平均法,其模板为:
和中值滤波法对testnoise图像进行去噪处理(中值滤波的模板的大小也设为3×3)。
得出实验结果图像后,比较这两种方法去噪的效果好坏,并分析具体原因。
完成上述工作后,使用程序进行验证分析:
使用邻域平均法时,3×3和5×5模板大小对图像进行处理的效果有何差别?
并分析原因。
邻域平均法(3*3)
/*------利用第一次实验课提供的dhc.h和dhc.c文件以获取位图的高宽以及从文件头到实际的位图数据的偏移字节数,从而实现对位图实际数据的操作。
------*/
#include
#include
#include
#include"hdr.h"
/*------定义结构指针------*/
structbmphdr*hdr;
//定义用于直方图变量
unsignedchar*bitmap,*count,*new_color;
/*------main()函数编写------*/
intmain()
{
//定义整数i,j用于函数循环时的,nr_pixels为图像中像素的个数
inti,j,nr_pixels,nr_w,nr_h;
//定义两个文件指针分别用于提取原图像的数据和生成直方图均衡化后的图像
FILE*fp,*fpnew;
//定义主函数的参数包括:
输入的位图文件名和输出的位图文件名,此处内容可以不要,在DOS下执行命令的时候再临时输入也可,为了方便演示,我这里直接把函数的参数确定了。
//argc=3;
//argv[1]="test.bmp";
//argv[2]="testzf.bmp";
//参数输入出错显示
/*if(argc!
=3){
printf("pleaseinputthenameofinputandoutbitmapfiles\n");
exit
(1);
}*/
//获取位图文件相关信息
//hdr=get_header(argv[1]);
hdr=get_header("testnoise.bmp");
if(!
hdr)exit
(1);
//以二进制可读方式打开输入位图文件
fp=fopen("testnoise.bmp","rb");
if(!
fp){
printf("Fileopenerror!
\n");
exit
(1);
}
//文件指针指向数据区域
fseek(fp,hdr->offset,SEEK_SET);
//计算位图像素的个数
nr_pixels=hdr->width*hdr->height;
nr_w=hdr->width;
nr_h=hdr->height;
bitmap=malloc(nr_pixels);
new_color=malloc(nr_pixels);
count=malloc((nr_w+2)*(+nr_h+2));
//读取位图数据到bitmap中
fread(bitmap,nr_pixels,1,fp);
fclose(fp);
//因为图像边缘无法使用邻域平均,所以根据邻近颜色填补图像的周围一圈,存入count[]数组中
//中心图像存入count[]
for(i=nr_w+3;i<(nr_w+2)*(+nr_h+2)-nr_w-3;i++)
{
j=i/(nr_w+2)