From 96129bc8ab78265908c436bdcf19fe69d206d5d4 Mon Sep 17 00:00:00 2001 From: Damian Kowalski Date: Sun, 7 Apr 2024 13:14:32 +0200 Subject: [PATCH] histogram equalization --- .../histogram_equalization.cpp | 91 +++++++++++++------ 1 file changed, 62 insertions(+), 29 deletions(-) diff --git a/src/core/transformations/histogram_equalization.cpp b/src/core/transformations/histogram_equalization.cpp index 9425e2c..81fcbc5 100644 --- a/src/core/transformations/histogram_equalization.cpp +++ b/src/core/transformations/histogram_equalization.cpp @@ -1,6 +1,6 @@ #include "histogram_equalization.h" + #include "../histogram.h" -#include // Dla funkcji round HistogramEqualization::HistogramEqualization(PNM* img) : Transformation(img) @@ -14,44 +14,77 @@ HistogramEqualization::HistogramEqualization(PNM* img, ImageViewer* iv) : PNM* HistogramEqualization::transform() { - int width = image->width(); - int height = image->height(); + float width = image->width(); + float height = image->height(); - // Tworzymy nowy obiekt PNM do przechowywania przetworzonego obrazu PNM* newImage = new PNM(width, height, image->format()); + Histogram* histogram = image->getHistogram(); - // Tworzymy histogram dla obecnego obrazu - Histogram* hist = image->getHistogram(); // Nie przekazujemy argumentów + QHash* R = histogram->get(Histogram::RChannel); + QHash* G = histogram->get(Histogram::GChannel); + QHash* B = histogram->get(Histogram::BChannel); + QHash* L = histogram->get(Histogram::LChannel); - // Pobieramy łączną liczbę pikseli na obrazie - int totalPixels = width * height; + // Probability tables + float redProb[255]; + float greenProb[255]; + float blueProb[255]; + float greyProb[255]; - // Tworzymy dystrybuantę - QVector cdf(256, 0.0); // Inicjalizujemy wszystkie wartości na 0.0 - double sum = 0.0; - for (int i = 0; i < 256; ++i) { - sum += hist->get(Histogram::LChannel)->value(i) / static_cast(totalPixels); // Używamy kanału luminancji - cdf[i] = sum; + float pixelSum = width * height; + for (int i = 0; i < 256; i++) + { + redProb[i] = (R->value(i)) / (pixelSum); + greenProb[i] = (G->value(i)) / (pixelSum); + blueProb[i] = (B->value(i)) / (pixelSum); + greyProb[i] = (L->value(i)) / (pixelSum); } - // Normalizujemy dystrybuantę do przedziału [0, 255] - QVector lookupTable(256, 0); - for (int i = 0; i < 256; ++i) { - lookupTable[i] = round(cdf[i] * 255); + // D look-up + float redD[255]; + float greenD[255]; + float blueD[255]; + float greyD[255]; + + // Create template values + float sumRed = 0; + float sumGreen = 0; + float sumBlue = 0; + float sumGrey = 0; + + for(int i = 0; i < 255; i++) + { + sumRed = redProb[i] + sumRed; + redD[i] = sumRed; + + sumGreen = greenProb[i] + sumGreen; + greenD[i] = sumGreen; + + sumBlue = blueProb[i] + sumBlue; + blueD[i] = sumBlue; + + sumGrey= greyProb[i] + sumGrey; + greyD[i] = sumGrey; } - // Przeprowadzamy wyrównywanie histogramu - for (int y = 0; y < height; ++y) { - for (int x = 0; x < width; ++x) { + for (int x = 0; x < image->width(); x++) + { + for (int y = 0; y < image->height(); y++) + { QRgb pixel = image->pixel(x, y); - int grayValue = qGray(pixel); // Pobieramy wartość odcienia szarości - - // Używamy wartości z lookupTable jako nowej wartości odcienia szarości - int newGrayValue = lookupTable[grayValue]; - QRgb newPixel = qRgb(newGrayValue, newGrayValue, newGrayValue); // Ustawiamy nową wartość dla każdego kanału RGB - - // Ustawiamy nowy piksel na obrazie docelowym - newImage->setPixel(x, y, newPixel); + if (image->format() == QImage::Format_RGB32) { + newImage->setPixel( + x, + y, + QColor( + redD[qRed(pixel)] * 255, + greenD[qGreen(pixel)] * 255, + blueD[qBlue(pixel)] * 255 + ).rgb()); + } + else { + newImage->setPixel(x, y, greyD[qGray(pixel)] * 255); + } } }