数字图像处理 实验四 邻域平均法滤波处理和差分法求图像边缘

邻域平均法

使用下面的模板进行邻域平均法滤波处理
1 9 [ 1 1 1 1 1 ∗ 1 1 1 1 ] \frac19 \begin{bmatrix} 1 & 1 & 1 \\ 1 & 1* & 1 \\ 1 & 1 & 1 \end{bmatrix} 91111111111

  • 上面这个模板的意思就是说,把这一圈算上中间一共九个点像素值加一块取个平均值再放回到中间,作为中间像素值,就这样把整个图片弄一遍,输出新图,所谓邻域平均法,就这么简单

差分法求图像边缘

  • 差分概念应该很清楚了,就是比如一个数组 a a a,那么它的差分数组可以是 b [ i ] = a [ i + 1 ] − a [ i ] b[i]=a[i+1]-a[i] b[i]=a[i+1]a[i]或者 b [ i ] = a [ i ] − a [ i − 1 ] b[i]=a[i]-a[i-1] b[i]=a[i]a[i1],一个前向差分,一个后向差分,那么这里公式已经给出 G [ f ( x , y ) ] = ∣ f ( i , j ) − f ( i + 1 , j ) ∣ + ∣ f ( i , j ) − f ( i , j + 1 ) ∣ G[f(x, y)]=| f(i, j) - f(i+1, j) | + |f(i, j )- f(i, j+1) | Gf(x,y)=f(i,j)f(i+1,j)+f(i,j)f(i,j+1),显然就是横向和纵向求两个前向差分绝对值加一起替代原像素点就好了

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;	
}


bmphdr.c

#include <stdio.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;
} header;

int main(int argc, char *argv[])
{
	FILE *fp;
	
	if (argc != 2) {
		printf("Usage: %s <filename>\n", argv[0]);
		exit(1);
	}
	
	fp = fopen(argv[1], "r");
	if (!fp) {
		printf("File open error or such file does not exist!\n");
		exit(1);	
	}
	
	fread(header.signature, 2, 1, fp);
	if (header.signature[0] != 'B' || header.signature[1] != 'M') {
		printf("Not a bmp file!\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);//图像信息头大小,识别不同版本bmp文件
	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(&header.compress_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", header.compress_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");
	return 0;	
}


邻域平均

#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};
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] = "testzf.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{
                int ans = bitmap[i * hdr->width + j];
                for(k=0;k<8;k++){
                    ii = i + di[k];
                    jj = j + dj[k];
                    ans += bitmap[ii * hdr->width + jj];
                }
                to[i * hdr->width + j] = ans * 1.0 / 9;
            }
        }
    }
    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;
}


差分求图像边缘

#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};
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] = "test.bmp";
    argv[2] = "testzf2.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{
                to[i * hdr->width + j] = abs(bitmap[i * hdr->width + j + 1] - bitmap[i *hdr->width + j]) +abs(bitmap[(i + 1) * hdr->width + j] - bitmap[i * hdr->width + j]);
            }
        }
    }
    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;
}


原图

在这里插入图片描述

加入椒盐噪声

在这里插入图片描述

邻域平均法去椒盐(脉冲)噪声

在这里插入图片描述

图像边缘

在这里插入图片描述

  • 之前做过中值滤波法去椒盐噪声的实验,邻域平均法相对于中值滤波法去椒盐噪声效果不好,原因很简单,从方法上考虑,一个取平均值,另一个取中位数,显然取中位数彻底抛弃了噪声,所以效果好是很自然的,但是高斯噪声就不行了
  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Clarence Liu

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

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

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

打赏作者

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

抵扣说明:

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

余额充值