BMP灰度图像直方图均衡化(C语言实现)

        本文使用的BMP图像为24位的非压缩格式,24位分别记录了RGB值,想要得到这个格式的图像,可以通过画图来另存为。

        原始图像为一张彩色图像,所以第一步是要将其转变为灰度图。具体转变原理这里不详述,总之是要得到这一个像素的亮度a,再将a赋值给RGB。

for(i=0;i<info_header.height;++i){
	for(j=0;j<info_header.width;++j){
		    tmp = (unsigned char *)img;
			tmp1 = (float)tmp[2]*0.299 + (float)tmp[1]*0.587 + (float)tmp[0]*0.114;
			tmp1 = tmp1 > 254 ? 255 : tmp1;
			tmp[0] = tmp1;
			tmp[1] = tmp1;
			tmp[2] = tmp1;
			A[tmp1]++;
			img=img+3;
	}
}

这一步中,通过A矩阵统计灰度值,再进行均衡化

B[0]=A[0];
printf("%d\n",A[1]);
for(i=1;i<256;i++){
	B[i]=A[i]+B[i-1];
} 
for (i = 0; i < 256; i++) {
    C[i] = (int)(255.0 * B[i] / (info_header.width * info_header.height) + 0.5);
}

处理后原图,灰度图和直方图均衡的灰度图分别为

 

 

可以发现处理后的图像更加明亮,当然这与原图比较昏暗有关,总体代码如下:
 

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#pragma pack(push, 1)

typedef struct {
    unsigned short type;
    unsigned int size;
    unsigned short reserved1;
    unsigned short reserved2;
    unsigned int offset;
} BMPFileHeader;

typedef struct {
    unsigned int header_size;
    int width;
    int height;
    unsigned short planes;
    unsigned short bits_per_pixel;
    unsigned int compression;
    unsigned int image_size;
    int x_resolution;
    int y_resolution;
    unsigned int num_colors;
    unsigned int important_colors;
} BMPInfoHeader;

#pragma pack(pop)

int main() {
	int i,j;
	unsigned int tmp1;
	unsigned char* tmp;
	int A[256];
	unsigned int B[256];
	int C[256];
	for(i=0;i<256;i++){
		A[i]=0;
	}
    // Open the original BMP image
    FILE* original_file = fopen("xianxian.bmp", "rb");
    if (original_file == NULL) {
        printf("Error: Could not open original BMP file.\n");
        return 1;
    }

    // Read the file header
    BMPFileHeader file_header;
    fread(&file_header, sizeof(file_header), 1, original_file);

    // Read the info header
    BMPInfoHeader info_header;
    fread(&info_header, sizeof(info_header), 1, original_file);

    // Allocate memory for the image data
    unsigned char* image_data = (unsigned char*)malloc(info_header.image_size);
    if (image_data == NULL) {
        printf("Error: Could not allocate memory for image data.\n");
        return 1;
    }
                          
    // Read the image data
    fread(image_data, 1, info_header.image_size, original_file);
printf("%d %d %d\n",image_data[0],image_data[1],image_data[2]);

    // Close the original BMP image file
    fclose(original_file);

unsigned char*img=&image_data[0];
for(i=0;i<info_header.height;++i){
	for(j=0;j<info_header.width;++j){
		    tmp = (unsigned char *)img;
			tmp1 = (float)tmp[2]*0.299 + (float)tmp[1]*0.587 + (float)tmp[0]*0.114;
			tmp1 = tmp1 > 254 ? 255 : tmp1;
			tmp[0] = tmp1;
			tmp[1] = tmp1;
			tmp[2] = tmp1;
			A[tmp1]++;
			img=img+3;
	}
}
//直方图均衡化
B[0]=A[0];
printf("%d\n",A[1]);
for(i=1;i<256;i++){
	B[i]=A[i]+B[i-1];
} 
for (i = 0; i < 256; i++) {
    C[i] = (int)(255.0 * B[i] / (info_header.width * info_header.height) + 0.5);
}
    //输出灰度直方图到TXT 
FILE *rec;
rec = fopen("output.txt","w");
for(i=0;i<256;i++){
	fprintf(rec,"A[%d] = %d   B[%d] = %u   C[%d] = %d\n",i,A[i],i,B[i],i,C[i]);
}
fclose(rec);
//灰度图均衡化
img=&image_data[0];
for(i=0;i<info_header.height;++i){
	for(j=0;j<info_header.width;++j){
		    tmp = (unsigned char *)img;
			tmp1 = tmp[0];
			if(tmp1<256){
			    tmp[0] = C[tmp1];
			    tmp[1] = C[tmp1];
			    tmp[2] = C[tmp1];
			}else{
				tmp[0] = tmp1;
			    tmp[1] = tmp1;
			    tmp[2] = tmp1;
			}
			img=img+3;
	}
} 
    // Create a new BMP image file
    FILE* new_file = fopen("new.bmp", "wb");
    if (new_file == NULL) {
        printf("Error: Could not create new BMP file.\n");
        free(image_data);
        return 1;
    }

    // Write the file header to the new BMP image file
    fwrite(&file_header, sizeof(file_header), 1, new_file);

    // Write the info header to the new BMP image file
    fwrite(&info_header, sizeof(info_header), 1, new_file);

    // Write the image data to the new BMP image file
    fwrite(image_data, 1, info_header.image_size, new_file);

    // Close the new BMP image file
    fclose(new_file);

    // Free the memory
    free(image_data);

    printf("Success: Created a new BMP image file that is identical to the original.\n");

    return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值