一、实验目的
?图像变换是数字图像处理中的一种综合变换,如直方图变换、几何变换等。通过本实验,掌握中值滤波处理。
二、实验任务
设计程序,用中值滤波法(模板的大小为3×3)。进行去噪处理。
得出实验结果图像后,分析去噪的具体原因。并尝试使用1×3?? 1×11? 1×21模板去处理图像,并分析不同效果的原因。
三、实验环境
本实验在Windows平台上进行,对内存及cpu主频无特别要求,使用MINGW(gcc)编译器。
四、实验步骤
实验结果:
1.3*3模板
?
2.1*3模板
?
3.1*11模板
?
4.1*21模板
去噪的具体原因
去噪是指减少数字图像中噪声,椒盐噪声是一种在图像上出现很多白点或黑点的噪声,一般采用中值滤波器滤波可以得到较好的结果。中值滤波法是一种非线性平滑技术,中值滤波的基本原理是把数字图像或数字序列中一点的值用该点的一个邻域中各点值的中值代替,让周围的像素值接近真实值,从而消除孤立的噪声点,这样就可以去除图像上的白点,到达去噪的效果。
dhc.h 和 dhc.c 文件以获取位图的高、宽, 以及从文件头到实际的位图数据的偏移字节数,从而实现对位图实际数据的操作
?1.hdr.h?
#ifndef __HDR_H__
#define __HDR_H__
struct bmphdr
{
char signature[2]; //文件类型,字符串"BM"
int size; //文件大小
short reserved[2]; //保留字
int offset; //从文件到实际位图数据的偏移量
int hdr_size; //文件头的长度
int width; //图像的宽度,单位是像素
int height; //图像的高度,单位是像素
short nr_planes; //位平面数,值为1
short bits_per_pixel;//每个像素的位数
int compress_type; //指定压缩类型
int data_size; //位图数据大小
int resol_hori; //水平
int resol_vert; //垂直
int nr_colors; //使用的颜色数
int important_color; //图像中重要的颜色数
char info[1024];
};
struct bmphdr *get_header(char filename[]); //得到文件头信息
#endif
2.hdr.c?
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include "hdr.h"
struct bmphdr *get_header(char filename[])
{
FILE *fp;
struct bmphdr *hdr;
fp = fopen(filename, "rb");
//检查文件是否存在
if (!fp)
{
printf("File open error or such file does not exist!\n");
return NULL;
}
//为位图文件信息头分配内存空间
hdr = (struct bmphdr *)malloc(sizeof(struct bmphdr));
//fread(buf,size,count,fp)
//从图像中读取文件类型
fread(hdr->signature, 2, 1, fp);
//判断文件是否为BMP文件
if (hdr->signature[0] != 'B' || hdr->signature[1] != 'M')
{
printf("Not a bmp file!\n");
return NULL;
}
//读取位图文件头信息
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); //关闭文件
return hdr;
}
3.完整代码
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include "hdr.h"
struct bmphdr *hdr;
unsigned char *bitmap,*to;
char buf[2048];
//像素点的位置数组
int di[8] = {0,0,1,1,1,-1,-1,-1};
int dj[8] = {1,-1,0,1,-1,0,1,-1};
unsigned char tmp[9];
int cmp(const void *a,const void *b)
{
unsigned char *t1,*t2;
t1 = (unsigned char *)a;
t2 = (unsigned char *)b;
if(*t1<*t2)
return -1;
else if(*t1>*t2)
return 1;
else
return 0;
}
int main(int argc,char *argv[])
{
int i,j,k,nr_pixels;
FILE *fp,*fpnew; //原始图像文件、去噪后的图像文件
unsigned pj,px;
int ii,jj;
if(argc != 3){
printf("Usage:%s<file_form> <file_to>\n",argv[0]);
exit(1);
}
hdr = get_header(argv[1]); //获取文件头信息
if(!hdr) exit(1);
fp = fopen(argv[1],"rb"); //打开图像文件
if(!fp){
printf("File open error!\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);
to = malloc(nr_pixels);
for(i=0;i<hdr->height;i++)
for(j=0;j<hdr->width;j++) {
if(i==0 || i==hdr->height -1 || j==0 || j==hdr->width-1) {
to[i*hdr->width+j] = bitmap[i*hdr->width+j]; //边界值处理
} else {
for(k=0;k<8;k++){ //模板范围像素点位置
ii = i+di[k];
jj = j+dj[k];
tmp[k] = bitmap[ii*hdr->width+jj];
}
tmp[8] = bitmap[i*hdr->width+j];
qsort(tmp,9,1,cmp); //排序
to[i*hdr->width+j] = tmp[4]; //取中值
}
}
fpnew = fopen(argv[2],"wb+"); //打开结果文件
if(!fpnew) {
printf("File create error!\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);
return 0;
}
|