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

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,我可以为您提供一些关于BMP图像直方图均衡算法的基本思路和C语言实现直方图均衡是一种图像增强技术,它可以使图像的对比度增强,提高图像的质量。直方图均衡的基本思路是将图像的像素值进行重新分配,使得图像灰度级分布更加均匀。 下面是一种基于C语言实现BMP图像直方图均衡算法的伪代码: 1. 读取BMP图像的像素矩阵 2. 统计图像像素矩阵的灰度直方图 3. 计算直方图均衡映射表 4. 对原始像素矩阵进行直方图均衡 5. 将均衡后的像素矩阵写回BMP图像 下面是一份可以实现直方图均衡的C语言代码: ```c #include <stdio.h> #include <stdlib.h> #include <string.h> #pragma pack(1) //按字节对齐 typedef struct BMPFileHeader { char bfType[2]; int bfSize; short bfReserved1; short bfReserved2; int bfOffBits; } BMPFileHeader; typedef struct BMPInfoHeader { int biSize; int biWidth; int biHeight; short biPlanes; short biBitCount; int biCompression; int biSizeImage; int biXPelsPerMeter; int biYPelsPerMeter; int biClrUsed; int biClrImportant; } BMPInfoHeader; typedef struct RGB { unsigned char blue; unsigned char green; unsigned char red; } RGB; int main() { FILE* fp; BMPFileHeader bmpFileHeader; BMPInfoHeader bmpInfoHeader; RGB* image; RGB* image2; unsigned char* grayImage; unsigned char* grayImage2; int* hist; int* eqHist; int* map; int width, height, size, size2, i, j, k, max; char filename[100]; // 读取图像文件 printf("Enter the filename of the BMP image: "); scanf("%s", filename); fp = fopen(filename, "rb"); if (!fp) { printf("Error: Failed to open the file.\n"); return -1; } // 读取文件头 fread(&bmpFileHeader, sizeof(BMPFileHeader), 1, fp); if (bmpFileHeader.bfType[0] != 'B' || bmpFileHeader.bfType[1] != 'M') { printf("Error: Not a BMP file.\n"); return -1; } // 读取信息头 fread(&bmpInfoHeader, sizeof(BMPInfoHeader), 1, fp); if (bmpInfoHeader.biBitCount != 24) { printf("Error: Not a 24-bit BMP file.\n"); return -1; } // 计算图像大小 width = bmpInfoHeader.biWidth; height = bmpInfoHeader.biHeight; size = width * height; size2 = sizeof(unsigned char) * size; // 读取像素数据 image = (RGB*)malloc(sizeof(RGB) * size); fread(image, sizeof(RGB), size, fp); // 将RGB图像转换为灰度图像 grayImage = (unsigned char*)malloc(size2); for (i = 0; i < size; i++) { grayImage[i] = (unsigned char)(0.299 * image[i].red + 0.587 * image[i].green + 0.114 * image[i].blue); } // 计算灰度直方图 hist = (int*)malloc(sizeof(int) * 256); memset(hist, 0, sizeof(int) * 256); for (i = 0; i < size; i++) { hist[grayImage[i]]++; } // 计算直方图均衡映射表 eqHist = (int*)malloc(sizeof(int) * 256); map = (int*)malloc(sizeof(int) * 256); max = size / 256; for (i = 0; i < 256; i++) { eqHist[i] = 0; for (j = 0; j <= i; j++) { eqHist[i] += hist[j]; } map[i] = (int)(eqHist[i] * 255.0 / size + 0.5); if (eqHist[i] > max) { eqHist[i] = max; } } // 对灰度图像进行直方图均衡 grayImage2 = (unsigned char*)malloc(size2); for (i = 0; i < size; i++) { grayImage2[i] = (unsigned char)map[grayImage[i]]; } // 将灰度图像转换为RGB图像 image2 = (RGB*)malloc(sizeof(RGB) * size); for (i = 0; i < size; i++) { image2[i].red = grayImage2[i]; image2[i].green = grayImage2[i]; image2[i].blue = grayImage2[i]; } // 写回图像文件 fseek(fp, sizeof(BMPFileHeader) + sizeof(BMPInfoHeader), SEEK_SET); fwrite(image2, sizeof(RGB), size, fp); fclose(fp); free(image); free(image2); free(grayImage); free(grayImage2); free(hist); free(eqHist); free(map); printf("Done.\n"); return 0; } ``` 这份代码可以读取一个BMP图像文件,将其转换为灰度图像,进行直方图均衡,然后将均衡后的图像写回文件中。注意,这份代码只支持24位的BMP图像文件。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值