由于直方图均衡需要对每个像素点的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分量已经进行了直方图均衡处理。

用C语言编写一段代码对大小为256×256大小 24 位真彩的bmp格式的图像进行相应操作并且读写要求用到fread 、fwrite 函数等将图像3bmp中的色彩R G B分量 中的R分量进行直方图均衡将对R分量进行直方图均衡并将均衡后的图像输出为名字为4bmp的图像

原文地址: https://www.cveoy.top/t/topic/b3hT 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录