📜  C中的直方图均衡图像处理

📅  最后修改于: 2021-05-28 04:15:56             🧑  作者: Mango

数字图像的直方图通过绘制条形图来表示强度分布,该条形图以X轴作为像素强度值,Y轴作为其出现频率。

直方图均衡化是一种调整对比度级别并扩展数字图像强度范围的技术。因此,它增强了图像,使信息提取和进一步的图像处理更加容易。

以下是用C语言进行直方图均衡化的算法。

  1. 将输入图像转换为灰度图像
  2. 查找每个像素值(即图像的直方图)的出现频率(对于任何灰度图像,值都在[0,255]范围内)
  3. 计算所有像素值的累积频率
  4. 用累积频率除以像素总数,然后将其乘以图像中的最大灰度计数(像素值)

例如,考虑具有总共25个像素和8个不同像素值的图像。所有步骤均已应用于原始图像的直方图。

图像说明直方图均衡化的步骤

上图中的最后一行显示了相乘后的结果,实际上是直方图等于原始灰度级的新灰度级映射。

下面是执行图像直方图均衡化的C程序。

// C program to perform histogram equalisation to adjust contrast levels
  
// All the needed library functions for this program
#include 
#include 
#include 
#include 
#include 
  
// Function to perform histogram equalisation on an image
// Function takes total rows, columns, input file name and output
// file name as parameters
void histogramEqualisation(int cols, int rows,
                           char* input_file_name, char* output_file_name)
{
    // creating image pointer
    unsigned char* image;
  
    // Declaring 2 arrays for storing histogram values (frequencies) and
    // new gray level values (newly mapped pixel values as per algorithm)
    int hist[256] = { 0 };
    int new_gray_level[256] = { 0 };
  
    // Declaring other important variables
    int input_file, output_file, col, row, total, curr, i;
  
    // allocating image array the size equivalent to number of columns
    // of the image to read one row of an image at a time
    image = (unsigned char*)calloc(cols, sizeof(unsigned char));
  
    // opening input file in Read Only Mode
    input_file = open(input_file_name, O_RDONLY);
    if (input_file < 0) {
        printf("Error opening input file\n");
        exit(1);
    }
  
    // creating output file that has write and read access
    output_file = creat(output_file_name, 0666);
    if (output_file < 0) {
        printf("Error creating output file\n");
        exit(1);
    }
  
    // Calculating frequency of occurrence for all pixel values
    for (row = 0; row < rows; row++) {
        // reading a row of image
        read(input_file, &image[0], cols * sizeof(unsigned char));
  
        // logic for calculating histogram
        for (col = 0; col < cols; col++)
            hist[(int)image[col]]++;
    }
  
    // calculating total number of pixels
    total = cols * rows;
  
    curr = 0;
  
    // calculating cumulative frequency and new gray levels
    for (i = 0; i < 256; i++) {
        // cumulative frequency
        curr += hist[i];
  
        // calculating new gray level after multiplying by
        // maximum gray count which is 255 and dividing by
        // total number of pixels
        new_gray_level[i] = round((((float)curr) * 255) / total);
    }
  
    // closing file
    close(input_file);
  
    // reopening file in Read Only Mode
    input_file = open(input_file_name, O_RDONLY);
  
    // performing histogram equalisation by mapping new gray levels
    for (row = 0; row < rows; row++) {
        // reading a row of image
        read(input_file, &image[0], cols * sizeof(unsigned char));
  
        // mapping to new gray level values
        for (col = 0; col < cols; col++)
            image[col] = (unsigned char)new_gray_level[image[col]];
  
        // reading new gray level mapped row of image
        write(output_file, &image[0], cols * sizeof(unsigned char));
    }
  
    // freeing dynamically allocated memory
    free(image);
  
    // closing input and output files
    close(input_file);
    close(output_file);
}
  
// driver code
int main()
{
    // declaring variables
    char* input_file_name;
    char* output_file_name;
    int cols, rows;
  
    // defining number of rows and columns in an image
    // here, image size is 512*512
    cols = 512;
    rows = 512;
  
    // defining input file name (input image name)
    // this boat_512_512 is a raw grayscale image
    input_file_name = "boat_512_512";
  
    // defining output file name (output image name)
    output_file_name = "boat_512_512_histogram_equalised";
  
    // calling function to do histogram equalisation
    histogramEqualisation(cols, rows, input_file_name, output_file_name);
  
    return 0;
}

结果:

直方图均衡化前后的船形图像(从左到右)
直方图均衡化之前和之后的船图像

均衡前后的直方图变换(从左到右)
应用均衡后直方图的变换

请注意,程序中使用的船图像是灰度原始图像。 ImageJ和GNUplot用于查看图像和绘制直方图。

想要从精选的最佳视频中学习和练习问题,请查看《基础知识到高级C的C基础课程》。