0
点赞
收藏
分享

微信扫一扫

直方图均衡化

倚然君 2022-04-23 阅读 58

 图片用的是冈萨雷斯的《数字图像处理》里面的花粉图片,方便和标准答案对照。直方图均衡化全是用C语言实现的,画直方图用到了easyX,用了一点C++。

原花粉图和其灰度直方图:

均衡化后的图像和灰度直方图:

代码如下:

#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <math.h>
#include <graphics.h>
#include <conio.h>

#define _CRT_SECURE_NO_WARNINGS
#define width 500
#define height 500

int main()
{
    BITMAPFILEHEADER bmpFileHeader;
    BITMAPINFOHEADER bmpInfoHeader;
    RGBQUAD bmpColorTable[256];
    BYTE bmpValue[width * height];
    FILE* fp;
    //打开图像文件
    fp = fopen("pollen.bmp", "rb");
    if (fp == NULL)
    {
        printf("打开失败!\n");
        return 0;
    }
    //读取图像信息
    fread(&bmpFileHeader, sizeof(BITMAPFILEHEADER), 1, fp);
    fread(&bmpInfoHeader, sizeof(BITMAPINFOHEADER), 1, fp);
    fread(bmpColorTable, sizeof(RGBQUAD), 256, fp);
    fread(bmpValue, 1, width * height, fp);
    //将图像灰度值存入数组中
    int grayValue[width * height] = { 0 };
    for (int i = 0; i < width * height; i++)
    {
        grayValue[i] = bmpColorTable[bmpValue[i]].rgbBlue;
    }
    fclose(fp);


    //统计直方图
    int grayCount[256] = { 0 };          //灰度数量
    double grayFrequency[256] = { 0.0 }; //灰度数量对应的频率
    double graySum[256] = { 0.0 };       //灰度数量累计分布
    int s[256] = { 0 };

    

    for (int i = 0; i <width*height; i++)
    {
        grayCount[grayValue[i]]++;
    }
    for (int i = 0; i < 256; i++)
    {
        if (grayCount[i])
        {
            grayFrequency[i] = grayCount[i] / (500.0 * 500.0);                   //每个像素的累计概率
        }
        graySum[0] =  grayFrequency[0];                           //各灰度级累积分布
        if (i != 0) 
        {
          graySum[i] = graySum[i - 1] + grayFrequency[i];                           
        }
        printf("灰度值%3d 频数为%6d 频率为%f 累计频率为%f\n", i, grayCount[i], grayFrequency[i], graySum[i]);
    }
    //绘制原直方图,画布坐标与广义坐标是反的
    initgraph(256, 256);
    line(255, 0, 0, 0);   //x轴
    line(0, 255, 0, 0);   //y轴
    for (int i = 0; i < 256; i++)
    {
        line(i, 256 - grayCount[i] / 100, i,255 );      
    }
    getch();
    closegraph();

    //均衡化之后的值
    for (int i = 0; i < 256; i++)
    {
        s[i] = (int)(round((double)((256 - 1) * graySum[i])));
    }
    //映射
    for (int i = 0; i < width * height; i++)
    {
        grayValue[i] = s[grayValue[i]];
    }

    //写入新图像
    fp = fopen("output.bmp", "wb");
    if (fp == NULL)
    {
        return 0;
    }

    fwrite(&bmpFileHeader, sizeof(BITMAPFILEHEADER), 1, fp);
    fwrite(&bmpInfoHeader, sizeof(BITMAPINFOHEADER), 1, fp);
    fwrite(bmpColorTable, sizeof(RGBQUAD), 256, fp);
    for (int i = 0; i < width * height; i++)
    {
        fwrite(&grayValue[i], 1, 1, fp);
    }
    fclose(fp);

    //画新图像的直方图
    fp = fopen("output.bmp", "rb");
    fread(bmpColorTable, sizeof(RGBQUAD), 256, fp);
    fread(bmpValue, 1, width * height, fp);
    for (int i = 0; i < width * height; i++)
    {
        grayValue[i] = 0;
    }
    for (int i = 0; i < 256; i++)
    {
        grayCount[i] = 0;
    }
    for (int i = 0; i < width * height; i++)
    {
        grayValue[i] = bmpColorTable[bmpValue[i]].rgbBlue;
    }
    fclose(fp);
    for (int i = 0; i < width * height; i++)
    {
        grayCount[grayValue[i]]++;
    }

    initgraph(256, 256);
    line(255, 0, 0, 0);   //x轴
    line(0, 255, 0, 0);   //y轴
    for (int i = 0; i < 256; i++)
    {
        line(i, 256 - grayCount[i] / 100, i, 255);
    }
    getch();
    closegraph();

    return 0;
}

 

 

举报

相关推荐

0 条评论