数字图像处理 实验二 直方图均衡化处理

  • 过程大概如下

1.读取test.bmp文件,获取位图文件相关信息
2.计算位图元素的个数
3.读取位图数据到bitmap中
4.计算每个灰度级上像素的个数,结果存入count数组中
5.计算灰度的累积分布
6.进行直方图的均衡化,定义新的灰度对应规则存入new_color数组中
7.对所有的像素灰度值按照均衡化得到的灰度对应规则进行转换,结果存入bitmap中
8.最后将均衡化之后的数据写入到testzf.bmp中,释放内存空间

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

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

主程序

#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include "hdr.h"

struct bmphdr *hdr;//定义结构指针
unsigned char *bitmap, new_color[256];// 定义用于直方图变量
int count[256], acum[256];//定义计算灰度分布,灰度累计分布的数组
int main(int argc, char *argv[]){
    int i, j, nr_pixels;//定义整数i,j用于函数循环
    //nr_pixels为图像中像素的个数
    FILE *fp, *fpnew;//定义两个文件指针分别用于提取原图像的数据和生成直方图均衡化之后的图像
    argc=3;
    argv[1] = "test.bmp";
    argv[2] = "testzf.bmp";
    if(argc != 3){//参数输入错误提示
            printf("please input the name of input and out bitmap files\n");
            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);
    //读取位图数据到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];
   //灰度直方图的均衡化(核心程序部分,请仔细分析)为了方便大家编程实现,这里直接给 出了源代码,本实验最核心的部分就在这里
   //定义新的灰度对应规则 new_color[i];
   for (i = 0; i < 256; i++) {
       j = acum[i] * 1.0 / acum[255] * 255 + 0.5;
       new_color[i] = j;
   }
   //对所有的像素灰度值按照均衡化得到的灰度对应规则进行转换,结果存入 bitmap[]中
   for (i = 0; i < nr_pixels; 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);
   return 0;
}

原图

test.bmp

在这里插入图片描述
均衡化之后

testzf.bmp

在这里插入图片描述

  • 1
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Clarence Liu

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

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

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

打赏作者

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

抵扣说明:

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

余额充值