本文使用的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;
}