数字图像处理 实验三 中值滤波处理

该博客介绍了一个C语言实现的中值滤波器,用于去除图像噪声。程序首先读取BMP图像文件,然后对内部像素使用3x3模板进行中值滤波,最后将处理后的图像保存到新的BMP文件。通过修改滤波模板大小,如11x1,可以适应不同噪声消除需求。博客展示了不同模板尺寸下处理后的图像效果。
摘要由CSDN通过智能技术生成

实验目的
在这里插入图片描述
在这里插入图片描述

  • 中值滤波的处理过程是选择像素周围的一片模板大小的区域,计算这个区域的每个位置的像素,然后取这个区域的像素的中位数作为这个点的像素大小,然后输出,当然为了方便应该尽量选择奇数

3_3.c

#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];
inline 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;//定义整数i,j用于函数循环
    //nr_pixels为图像中像素的个数
    FILE *fp, *fpnew;
    unsigned pj, px;
    argc = 3;
    argv[1] = "testnoise.bmp";
    argv[2] = "3_3.bmp";
    int ii, jj;
    if(argc != 3){
        printf("Usage: %s <file_from> <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);
   //直方图均衡化的数据(bitmap)赋值
   fwrite(to, nr_pixels, 1, fpnew);
   fclose(fpnew);
   free(hdr);
   free(bitmap);
   return 0;
}

hdr.h

#ifndef __HDR_H__
#define __HDR_H__

struct bmphdr {
	char signature[2];//文件类型
	int size;//位图大小
	short reserved[2];//两个保留字
	int offset;//位图偏移位置
	int hdr_size;//头文件大小
	int width;//位图宽度
	int height;//位图高度
	short nr_planes;//位平面数
	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

hdr.c

#include <stdio.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(hdr->signature, 2, 1, fp);
	if (hdr->signature[0] != 'B' || hdr->signature[1] != 'M') {//如果打开文件的扩展名不是.bmp
		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)//获得位图有效信息,偏移量为54的时候读的才是位图第一个像素
		  fread(&hdr->info, 1024, 1, fp);	
  
  fclose(fp);//关闭文件
	return hdr;	
}

处理结果如下
在这里插入图片描述

  • 如果想把模板改成 1 × 11 1\times11 1×11,那么就是1行11列,所以只需要把方向改一下即可,像这样
int dj[11] = {-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5};

注意数组大小也都要改好,当然这是在列上进行的改变,行不动,很简单,这样处理之后得到图像如下
在这里插入图片描述
剩下 1 × 21 1\times21 1×21等等一个道理

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Clarence Liu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值