histogram equalization

This commit is contained in:
Damian Kowalski 2024-04-07 13:14:32 +02:00
parent 7e1be18f0d
commit 96129bc8ab

View File

@ -1,6 +1,6 @@
#include "histogram_equalization.h" #include "histogram_equalization.h"
#include "../histogram.h" #include "../histogram.h"
#include <cmath> // Dla funkcji round
HistogramEqualization::HistogramEqualization(PNM* img) : HistogramEqualization::HistogramEqualization(PNM* img) :
Transformation(img) Transformation(img)
@ -14,44 +14,77 @@ HistogramEqualization::HistogramEqualization(PNM* img, ImageViewer* iv) :
PNM* HistogramEqualization::transform() PNM* HistogramEqualization::transform()
{ {
int width = image->width(); float width = image->width();
int height = image->height(); float height = image->height();
// Tworzymy nowy obiekt PNM do przechowywania przetworzonego obrazu
PNM* newImage = new PNM(width, height, image->format()); PNM* newImage = new PNM(width, height, image->format());
Histogram* histogram = image->getHistogram();
// Tworzymy histogram dla obecnego obrazu QHash<int, int>* R = histogram->get(Histogram::RChannel);
Histogram* hist = image->getHistogram(); // Nie przekazujemy argumentów QHash<int, int>* G = histogram->get(Histogram::GChannel);
QHash<int, int>* B = histogram->get(Histogram::BChannel);
QHash<int, int>* L = histogram->get(Histogram::LChannel);
// Pobieramy łączną liczbę pikseli na obrazie // Probability tables
int totalPixels = width * height; float redProb[255];
float greenProb[255];
float blueProb[255];
float greyProb[255];
// Tworzymy dystrybuantę float pixelSum = width * height;
QVector<double> cdf(256, 0.0); // Inicjalizujemy wszystkie wartości na 0.0 for (int i = 0; i < 256; i++)
double sum = 0.0; {
for (int i = 0; i < 256; ++i) { redProb[i] = (R->value(i)) / (pixelSum);
sum += hist->get(Histogram::LChannel)->value(i) / static_cast<double>(totalPixels); // Używamy kanału luminancji greenProb[i] = (G->value(i)) / (pixelSum);
cdf[i] = sum; blueProb[i] = (B->value(i)) / (pixelSum);
greyProb[i] = (L->value(i)) / (pixelSum);
} }
// Normalizujemy dystrybuantę do przedziału [0, 255] // D look-up
QVector<int> lookupTable(256, 0); float redD[255];
for (int i = 0; i < 256; ++i) { float greenD[255];
lookupTable[i] = round(cdf[i] * 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 x = 0; x < image->width(); x++)
for (int y = 0; y < height; ++y) { {
for (int x = 0; x < width; ++x) { for (int y = 0; y < image->height(); y++)
{
QRgb pixel = image->pixel(x, y); QRgb pixel = image->pixel(x, y);
int grayValue = qGray(pixel); // Pobieramy wartość odcienia szarości if (image->format() == QImage::Format_RGB32) {
newImage->setPixel(
// Używamy wartości z lookupTable jako nowej wartości odcienia szarości x,
int newGrayValue = lookupTable[grayValue]; y,
QRgb newPixel = qRgb(newGrayValue, newGrayValue, newGrayValue); // Ustawiamy nową wartość dla każdego kanału RGB QColor(
redD[qRed(pixel)] * 255,
// Ustawiamy nowy piksel na obrazie docelowym greenD[qGreen(pixel)] * 255,
newImage->setPixel(x, y, newPixel); blueD[qBlue(pixel)] * 255
).rgb());
}
else {
newImage->setPixel(x, y, greyD[qGray(pixel)] * 255);
}
} }
} }