Ecualización de histograma en C | Procesamiento de imágenes

Un histograma de una imagen digital representa la distribución de intensidad trazando un gráfico de barras con el eje X como valor de intensidad de píxel y el eje Y como la frecuencia de su aparición.

La ecualización de histogramas es una técnica para ajustar los niveles de contraste y expandir el rango de intensidad en una imagen digital. Por lo tanto, mejora la imagen, lo que facilita la extracción de información y el procesamiento posterior de la imagen.

A continuación se muestra el algoritmo para realizar la ecualización de histogramas en lenguaje C.

  1. Convierta la imagen de entrada en una imagen en escala de grises
  2. Encuentre la frecuencia de aparición de cada valor de píxel, es decir, el histograma de una imagen (los valores se encuentran en el rango [0, 255] para cualquier imagen en escala de grises)
  3. Calcular la frecuencia acumulada de todos los valores de píxeles
  4. Divida las frecuencias acumuladas por el número total de píxeles y multiplíquelas por el número máximo de grises (valor de píxel) en la imagen

Por ejemplo, considere una imagen que tiene un total de 25 píxeles con 8 valores de píxeles distintos. Todos los pasos se han aplicado al histograma de la imagen original.

Image explaining steps of Histogram Equalisation

La última fila en la imagen de arriba muestra el resultado después de la multiplicación, que en realidad es un histograma igualado con el nuevo mapeo de niveles de gris de los niveles de gris originales.

A continuación se muestra el programa C para realizar la ecualización de histograma de una imagen.

// C program to perform histogram equalisation to adjust contrast levels
  
// All the needed library functions for this program
#include <fcntl.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
  
// 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;
}

Resultados:

Imagen del barco antes y después de la ecualización del histograma (de izquierda a derecha)
Image of Boat before and after Histogram Equalisation

Transformación del histograma antes y después de la ecualización (de izquierda a derecha)
Transformation of Histogram after applying Equalisation

Tenga en cuenta que la imagen del barco utilizada en el programa es una imagen sin formato en escala de grises. ImageJ y GNUplot se utilizan para ver imágenes y trazar histogramas.

Publicación traducida automáticamente

Artículo escrito por meet97_patel y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *