diff --git a/Makefile b/Makefile index c8271bc..f6a5168 100644 --- a/Makefile +++ b/Makefile @@ -4,7 +4,7 @@ LDIR = /opt/local/lib/ LIBS = -lc -lpng16 CFLAGS = -Wall -march=native -Ofast -Wa,-q OUT_DIR = build -LABS = lab1_1 lab1_2 lab1_3 lab1_4 lab1_5 lab1_6 lab1_7 lab1_8 lab2_1 lab2_2 lab3 lab4_1 lab4_2 lab5 lab6 lab7 +LABS = lab1_1 lab1_2 lab1_3 lab1_4 lab1_5 lab1_6 lab1_7 lab1_8 lab2_1 lab2_2 lab3 lab4_1 lab4_2 lab4_3 lab5 lab6 lab7 BINS = $(addprefix $(OUT_DIR)/,${LABS}) OBJS = $(addsuffix .o,${BINS}) diff --git a/README.md b/README.md index da83641..b98f819 100644 --- a/README.md +++ b/README.md @@ -18,6 +18,7 @@ Here are the programs that I wrote during the Digital Image Processing class in 4. Intensity transformations 1. [Gamma correction](#gamma-correction-lab4_1c) 2. [Linear contrast stretching](#linear-contrast-stretching-lab4_2c) + 3. [Histogram equalization](#histogram-equalization-lab4_3c) 5. [Convolution](#convolution-lab5c) 6. [Median filter](#median-filter-lab6c) 7. [Segmentation](#segmentation-lab7c) @@ -111,6 +112,13 @@ Here are the programs that I wrote during the Digital Image Processing class in | ![Input](images/Auto.png) | ![Output](lab4_2/Auto_out_1000.png) | | ![Input](lab4_2/Auto_in_hist.png) | ![Output](lab4_2/Auto_out_1000_hist.png) | +--- +## Histogram equalization ([lab4_3.c](lab4_3/lab4_3.c)) +| Input | Output | +| ----- | ------ | +| ![Input](images/Goldhill.png) | ![Output](lab4_3/Goldhill_out.png) | +| ![Input](lab4_3/Goldhill_in_hist.png) | ![Output](lab4_3/Goldhill_out_hist.png) | + --- ## Convolution ([lab5.c](lab5/lab5.c)) | Input | Output ([11x11 blur](kernels/Blur_11.txt) kernel) | diff --git a/lab4_3/Goldhill_in_hist.png b/lab4_3/Goldhill_in_hist.png new file mode 100644 index 0000000..f5e0686 Binary files /dev/null and b/lab4_3/Goldhill_in_hist.png differ diff --git a/lab4_3/Goldhill_out.png b/lab4_3/Goldhill_out.png new file mode 100644 index 0000000..b3554ef Binary files /dev/null and b/lab4_3/Goldhill_out.png differ diff --git a/lab4_3/Goldhill_out_hist.png b/lab4_3/Goldhill_out_hist.png new file mode 100644 index 0000000..8400dc9 Binary files /dev/null and b/lab4_3/Goldhill_out_hist.png differ diff --git a/lab4_3/lab4_3.c b/lab4_3/lab4_3.c new file mode 100644 index 0000000..cbc6cfd --- /dev/null +++ b/lab4_3/lab4_3.c @@ -0,0 +1,60 @@ +#include +#include "png_wrapper.h" +#include "histogram.h" + +static void process_image(struct Image img) +{ + unsigned hist[MAX_COLOR + 1] = { }; + for (size_t y = 0; y < img.height; y++) + for (size_t x = 0; x < img.width; x++) + hist[img.pixels[y][x]]++; + + double cdf[MAX_COLOR + 1]; // Cumulative distributive function + unsigned total_pixels = img.height * img.width; + cdf[0] = hist[0] / (double) total_pixels; + + for (size_t i = 1; i <= MAX_COLOR; i++) + cdf[i] = cdf[i - 1] + hist[i] / (double) total_pixels; + + unsigned char lut[MAX_COLOR + 1]; + for (size_t i = 0; i <= MAX_COLOR; i++) + { + int new = cdf[i] * MAX_COLOR; + lut[i] = new <= 255 ? new : 255; + } + + for (size_t y = 0; y < img.height; y++) + for (size_t x = 0; x < img.width; x++) + img.pixels[y][x] = lut[img.pixels[y][x]]; +} + +int main(int argc, char * const argv[]) +{ + if (argc != 5) + error("usage: %s " + "", argv[0]); + + char *input_filename = argv[1]; + char *output_filename = argv[2]; + char *hist1_filename = argv[3]; + char *hist2_filename = argv[4]; + + struct Image img = read_grayscale_png(input_filename); + printf("Input file \"%s\" opened (width = %u, height = %u)\n", + input_filename, img.width, img.height); + + struct Image hist = { HIST_WIDTH, HIST_HEIGHT }; + alloc_pixels(&hist); + histogram(img, hist); + write_grayscale_png(hist, hist1_filename); + + process_image(img); + write_grayscale_png(img, output_filename); + + histogram(img, hist); + free_pixels(img); + write_grayscale_png(hist, hist2_filename); + free_pixels(hist); + + return 0; +}