用C语言编写一段代码对大小为256×256大小 24 位真彩的bmp格式的图像进行相应操作并且读写要求用到fread 、fwrite 函数等将图像3bmp中的色彩R G B分量 中的R分量进行直方图均衡将对R分量进行直方图均衡并将均衡后的图像输出为名字为4bmp的图像
由于直方图均衡需要对每个像素点的R分量进行计算,因此需要先读取图像的像素点信息,然后对每个像素点的R分量进行处理,最后将处理后的像素点信息写回到新的图像文件中。
以下是实现该功能的代码:
#include <stdio.h>
#include <stdlib.h>
#pragma pack(2) // 设置结构体成员按2字节对齐
// BMP文件头结构体
typedef struct {
unsigned short bfType; // 文件类型,必须为0x4D42
unsigned int bfSize; // 文件大小,单位为字节
unsigned short bfReserved1; // 保留字段,必须为0
unsigned short bfReserved2; // 保留字段,必须为0
unsigned int bfOffBits; // 从文件头到像素数据的偏移量,单位为字节
} BMPFileHeader;
// BMP信息头结构体
typedef struct {
unsigned int biSize; // 信息头大小,必须为40
int biWidth; // 图像宽度,单位为像素
int biHeight; // 图像高度,单位为像素
unsigned short biPlanes; // 颜色平面数,必须为1
unsigned short biBitCount; // 每个像素的位数,必须为24
unsigned int biCompression; // 压缩方式,必须为0
unsigned int biSizeImage; // 像素数据大小,单位为字节
int biXPelsPerMeter; // 水平分辨率,单位为像素/米
int biYPelsPerMeter; // 垂直分辨率,单位为像素/米
unsigned int biClrUsed; // 颜色表中实际使用的颜色数,对于24位图像,该值为0
unsigned int biClrImportant; // 重要颜色数,对于24位图像,该值为0
} BMPInfoHeader;
// RGB三元组结构体
typedef struct {
unsigned char b; // 蓝色分量
unsigned char g; // 绿色分量
unsigned char r; // 红色分量
} RGBTriple;
// 直方图结构体
typedef struct {
int count[256]; // 每个灰度级出现的次数
float probability[256]; // 每个灰度级出现的概率
int mapping[256]; // 灰度级映射表
} Histogram;
int main() {
FILE *fpIn, *fpOut;
BMPFileHeader fileHeader;
BMPInfoHeader infoHeader;
RGBTriple **pixels;
Histogram histogram;
int i, j, k;
float sum = 0;
unsigned char r;
// 打开输入图像文件
fpIn = fopen("3.bmp", "rb");
if (fpIn == NULL) {
printf("无法打开输入图像文件\n");
return 0;
}
// 读取文件头信息
fread(&fileHeader, sizeof(BMPFileHeader), 1, fpIn);
fread(&infoHeader, sizeof(BMPInfoHeader), 1, fpIn);
// 分配像素点内存
pixels = (RGBTriple **)malloc(infoHeader.biHeight * sizeof(RGBTriple *));
for (i = 0; i < infoHeader.biHeight; i++) {
pixels[i] = (RGBTriple *)malloc(infoHeader.biWidth * sizeof(RGBTriple));
}
// 读取像素点信息
for (i = 0; i < infoHeader.biHeight; i++) {
for (j = 0; j < infoHeader.biWidth; j++) {
fread(&pixels[i][j], sizeof(RGBTriple), 1, fpIn);
}
}
// 关闭输入图像文件
fclose(fpIn);
// 初始化直方图
for (i = 0; i < 256; i++) {
histogram.count[i] = 0;
histogram.probability[i] = 0;
histogram.mapping[i] = 0;
}
// 统计R分量直方图
for (i = 0; i < infoHeader.biHeight; i++) {
for (j = 0; j < infoHeader.biWidth; j++) {
histogram.count[pixels[i][j].r]++;
}
}
// 计算R分量直方图概率
for (i = 0; i < 256; i++) {
histogram.probability[i] = (float)histogram.count[i] / (infoHeader.biWidth * infoHeader.biHeight);
}
// 计算R分量直方图累计概率
for (i = 0; i < 256; i++) {
sum += histogram.probability[i];
histogram.probability[i] = sum;
}
// 计算R分量直方图映射表
for (i = 0; i < 256; i++) {
histogram.mapping[i] = (int)(histogram.probability[i] * 255 + 0.5);
}
// 对R分量进行直方图均衡
for (i = 0; i < infoHeader.biHeight; i++) {
for (j = 0; j < infoHeader.biWidth; j++) {
r = pixels[i][j].r;
pixels[i][j].r = histogram.mapping[r];
}
}
// 打开输出图像文件
fpOut = fopen("4.bmp", "wb");
if (fpOut == NULL) {
printf("无法打开输出图像文件\n");
return 0;
}
// 写入文件头信息
fwrite(&fileHeader, sizeof(BMPFileHeader), 1, fpOut);
fwrite(&infoHeader, sizeof(BMPInfoHeader), 1, fpOut);
// 写入像素点信息
for (i = 0; i < infoHeader.biHeight; i++) {
for (j = 0; j < infoHeader.biWidth; j++) {
fwrite(&pixels[i][j], sizeof(RGBTriple), 1, fpOut);
}
}
// 关闭输出图像文件
fclose(fpOut);
// 释放像素点内存
for (i = 0; i < infoHeader.biHeight; i++) {
free(pixels[i]);
}
free(pixels);
return 0;
}
运行该程序后,会在当前目录下生成一个名为4.bmp的图像文件,其中R分量已经进行了直方图均衡处理。
原文地址: https://www.cveoy.top/t/topic/b3hT 著作权归作者所有。请勿转载和采集!