C语言实现BMP图像B分量直方图均衡化
使用C语言实现BMP图像B分量直方图均衡化
本文将介绍如何使用C语言编写代码,对大小为256×256的24位真彩BMP格式图像进行B分量直方图均衡化。
首先,我们需要定义BMP文件头和图像数据的结构体,并编写读取和写入BMP文件的函数。
#include <stdio.h>
#include <stdlib.h>
typedef struct tagBITMAPFILEHEADER {
unsigned short bfType;
unsigned int bfSize;
unsigned short bfReserved1;
unsigned short bfReserved2;
unsigned int bfOffBits;
} BITMAPFILEHEADER;
typedef struct tagBITMAPINFOHEADER {
unsigned int biSize;
int biWidth;
int biHeight;
unsigned short biPlanes;
unsigned short biBitCount;
unsigned int biCompression;
unsigned int biSizeImage;
int biXPelsPerMeter;
int biYPelsPerMeter;
unsigned int biClrUsed;
unsigned int biClrImportant;
} BITMAPINFOHEADER;
void read_bmp(char *filename, unsigned char *image_data, BITMAPFILEHEADER *file_header, BITMAPINFOHEADER *info_header) {
FILE *fp = fopen(filename, "rb");
if (fp == NULL) {
printf("Error: cannot open file %s\n", filename);
return;
}
fread(file_header, sizeof(BITMAPFILEHEADER), 1, fp);
fread(info_header, sizeof(BITMAPINFOHEADER), 1, fp);
int width = info_header->biWidth;
int height = info_header->biHeight;
int row_size = (width * 3 + 3) / 4 * 4;
unsigned char *temp_data = (unsigned char *)malloc(row_size);
for (int i = 0; i < height; i++) {
fread(temp_data, row_size, 1, fp);
for (int j = 0; j < width; j++) {
image_data[(i * width + j) * 3] = temp_data[j * 3 + 2];
image_data[(i * width + j) * 3 + 1] = temp_data[j * 3 + 1];
image_data[(i * width + j) * 3 + 2] = temp_data[j * 3];
}
}
free(temp_data);
fclose(fp);
}
void write_bmp(char *filename, unsigned char *image_data, BITMAPFILEHEADER *file_header, BITMAPINFOHEADER *info_header) {
FILE *fp = fopen(filename, "wb");
if (fp == NULL) {
printf("Error: cannot create file %s\n", filename);
return;
}
fwrite(file_header, sizeof(BITMAPFILEHEADER), 1, fp);
fwrite(info_header, sizeof(BITMAPINFOHEADER), 1, fp);
int width = info_header->biWidth;
int height = info_header->biHeight;
int row_size = (width * 3 + 3) / 4 * 4;
unsigned char *temp_data = (unsigned char *)malloc(row_size);
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
temp_data[j * 3 + 2] = image_data[(i * width + j) * 3];
temp_data[j * 3 + 1] = image_data[(i * width + j) * 3 + 1];
temp_data[j * 3] = image_data[(i * width + j) * 3 + 2];
}
fwrite(temp_data, row_size, 1, fp);
}
free(temp_data);
fclose(fp);
}
接下来,我们开始进行B分量直方图均衡化。
- 计算B分量的直方图
int hist[256] = {0};
for (int i = 0; i < width * height; i++) {
hist[image_data[i * 3]]++;
}
- 计算B分量的累积直方图
int cum_hist[256] = {0};
for (int i = 0; i < 256; i++) {
cum_hist[i] = (i == 0) ? hist[i] : cum_hist[i - 1] + hist[i];
}
- 计算B分量的直方图均衡化映射表
int map[256] = {0};
for (int i = 0; i < 256; i++) {
map[i] = (int)(255.0 * cum_hist[i] / (width * height) + 0.5);
}
- 根据映射表对B分量进行直方图均衡化
for (int i = 0; i < width * height; i++) {
image_data[i * 3] = map[image_data[i * 3]];
}
完整的代码如下:
#include <stdio.h>
#include <stdlib.h>
typedef struct tagBITMAPFILEHEADER {
unsigned short bfType;
unsigned int bfSize;
unsigned short bfReserved1;
unsigned short bfReserved2;
unsigned int bfOffBits;
} BITMAPFILEHEADER;
typedef struct tagBITMAPINFOHEADER {
unsigned int biSize;
int biWidth;
int biHeight;
unsigned short biPlanes;
unsigned short biBitCount;
unsigned int biCompression;
unsigned int biSizeImage;
int biXPelsPerMeter;
int biYPelsPerMeter;
unsigned int biClrUsed;
unsigned int biClrImportant;
} BITMAPINFOHEADER;
void read_bmp(char *filename, unsigned char *image_data, BITMAPFILEHEADER *file_header, BITMAPINFOHEADER *info_header) {
FILE *fp = fopen(filename, "rb");
if (fp == NULL) {
printf("Error: cannot open file %s\n", filename);
return;
}
fread(file_header, sizeof(BITMAPFILEHEADER), 1, fp);
fread(info_header, sizeof(BITMAPINFOHEADER), 1, fp);
int width = info_header->biWidth;
int height = info_header->biHeight;
int row_size = (width * 3 + 3) / 4 * 4;
unsigned char *temp_data = (unsigned char *)malloc(row_size);
for (int i = 0; i < height; i++) {
fread(temp_data, row_size, 1, fp);
for (int j = 0; j < width; j++) {
image_data[(i * width + j) * 3] = temp_data[j * 3 + 2];
image_data[(i * width + j) * 3 + 1] = temp_data[j * 3 + 1];
image_data[(i * width + j) * 3 + 2] = temp_data[j * 3];
}
}
free(temp_data);
fclose(fp);
}
void write_bmp(char *filename, unsigned char *image_data, BITMAPFILEHEADER *file_header, BITMAPINFOHEADER *info_header) {
FILE *fp = fopen(filename, "wb");
if (fp == NULL) {
printf("Error: cannot create file %s\n", filename);
return;
}
fwrite(file_header, sizeof(BITMAPFILEHEADER), 1, fp);
fwrite(info_header, sizeof(BITMAPINFOHEADER), 1, fp);
int width = info_header->biWidth;
int height = info_header->biHeight;
int row_size = (width * 3 + 3) / 4 * 4;
unsigned char *temp_data = (unsigned char *)malloc(row_size);
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
temp_data[j * 3 + 2] = image_data[(i * width + j) * 3];
temp_data[j * 3 + 1] = image_data[(i * width + j) * 3 + 1];
temp_data[j * 3] = image_data[(i * width + j) * 3 + 2];
}
fwrite(temp_data, row_size, 1, fp);
}
free(temp_data);
fclose(fp);
}
int main() {
BITMAPFILEHEADER file_header;
BITMAPINFOHEADER info_header;
unsigned char image_data[256 * 256 * 3];
read_bmp("3.bmp", image_data, &file_header, &info_header);
int width = info_header.biWidth;
int height = info_header.biHeight;
int hist[256] = {0};
for (int i = 0; i < width * height; i++) {
hist[image_data[i * 3]]++;
}
int cum_hist[256] = {0};
for (int i = 0; i < 256; i++) {
cum_hist[i] = (i == 0) ? hist[i] : cum_hist[i - 1] + hist[i];
}
int map[256] = {0};
for (int i = 0; i < 256; i++) {
map[i] = (int)(255.0 * cum_hist[i] / (width * height) + 0.5);
}
for (int i = 0; i < width * height; i++) {
image_data[i * 3] = map[image_data[i * 3]];
}
write_bmp("6.bmp", image_data, &file_header, &info_header);
return 0;
}
本代码使用fread()和fwrite()函数进行文件读写,并通过对B分量的直方图均衡化,增强图像对比度,最终将均衡后的图像输出为6.bmp。
原文地址: https://www.cveoy.top/t/topic/jCZc 著作权归作者所有。请勿转载和采集!