From 845b6fe40c93cfa5dab26448181faf6525dff435 Mon Sep 17 00:00:00 2001 From: Dawid Kreft Date: Sun, 8 Mar 2020 13:01:03 +0100 Subject: [PATCH 1/4] =?UTF-8?q?Dodanie=20metody=20wyznaczaj=C4=85cej=20his?= =?UTF-8?q?togram?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/core/histogram.cpp | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/core/histogram.cpp b/src/core/histogram.cpp index 1287666..26e8ee6 100644 --- a/src/core/histogram.cpp +++ b/src/core/histogram.cpp @@ -24,6 +24,20 @@ Histogram::~Histogram() void Histogram::generate(QImage* image) { + + qDebug() << Q_FUNC_INFO << "Not implemented yet!"; + for(int i = 0 ; i < image->height(); i++){ + for(int j = 0 ; j < image->width() ; j++){ + QColor *clrCurrent = new QColor( image->pixel(i,j) ); + R->insert(clrCurrent->red(),R->value(clrCurrent->red())+1); + G->insert(clrCurrent->green(),R->value(clrCurrent->green())+1); + B->insert(clrCurrent->blue(),R->value(clrCurrent->blue())+1); + L->insert(clrCurrent->alpha(),R->value(clrCurrent->alpha())+1); + } + } + + + qDebug() << Q_FUNC_INFO << "Not implemented yet!"; } From c61895432329e43117204a3c31644c2d27ed9c1a Mon Sep 17 00:00:00 2001 From: Dawid_Kreft Date: Sun, 22 Mar 2020 19:09:14 +0100 Subject: [PATCH 2/4] Zadanie_03_ready --- src/core/histogram.cpp | 84 +++++++++++++++++-- src/core/histogram.h | 5 ++ .../transformations/histogram_stretching.cpp | 30 ++++++- .../histogram_stretching.cpp.autosave | 48 +++++++++++ .../transformations/histogram_stretching.h | 1 + 5 files changed, 160 insertions(+), 8 deletions(-) create mode 100644 src/core/transformations/histogram_stretching.cpp.autosave diff --git a/src/core/histogram.cpp b/src/core/histogram.cpp index 26e8ee6..00628f1 100644 --- a/src/core/histogram.cpp +++ b/src/core/histogram.cpp @@ -25,7 +25,7 @@ Histogram::~Histogram() void Histogram::generate(QImage* image) { - qDebug() << Q_FUNC_INFO << "Not implemented yet!"; + qDebug() << Q_FUNC_INFO << " Generating histogram !"; for(int i = 0 ; i < image->height(); i++){ for(int j = 0 ; j < image->width() ; j++){ QColor *clrCurrent = new QColor( image->pixel(i,j) ); @@ -35,18 +35,88 @@ void Histogram::generate(QImage* image) L->insert(clrCurrent->alpha(),R->value(clrCurrent->alpha())+1); } } - - - - qDebug() << Q_FUNC_INFO << "Not implemented yet!"; } /** Returns the maximal value of the histogram in the given channel */ int Histogram::maximumValue(Channel selectedChannel = RGB) { - qDebug() << Q_FUNC_INFO << "Not implemented yet!"; + int max = 0; + if(selectedChannel == LChannel){ + return getMaxFromQHashHelper(get(selectedChannel)); + } - return 0; + max = getMaxFromQHashHelper(R); + + if(getMaxFromQHashHelper(G) > max){ + max = getMaxFromQHashHelper(G); + } + + if(getMaxFromQHashHelper(B) > max){ + max = getMaxFromQHashHelper(B); + } + + return max; +} + +// Return max or -1 when QHash is empty +int Histogram::getMaxFromQHashHelper( QHash * channel ){ + int max = -1; + + QHash::const_iterator iterator = channel->begin(); + while (iterator != channel->end()) + { + if(iterator.value() > max){ + max = iterator.value(); + } + ++iterator; + + } + return max; +} + +int Histogram::getMaxKey( QHash * channel ){ + int max = -1; + + QHash::const_iterator iterator = channel->begin(); + while (iterator != channel->end()) + { + if(iterator.key() > max){ + max = iterator.key(); + } + ++iterator; + + } + return max; +} + +int Histogram::getMinKey( QHash * channel ){ + int min = 256; + + QHash::const_iterator iterator = channel->begin(); + while (iterator != channel->end()) + { + if(iterator.key() < min){ + min = iterator.key(); + } + ++iterator; + + } + return min; +} + +//Return min or 256 when qhash is empty +int Histogram::getMinFromQHashHelper( QHash * channel ){ + int min = 256; + + QHash::const_iterator iterator = channel->begin(); + while (iterator != channel->end()) + { + if(iterator.value() < min){ + min = iterator.value(); + } + ++iterator; + } + return min; } diff --git a/src/core/histogram.h b/src/core/histogram.h index dc5052c..4b62c26 100644 --- a/src/core/histogram.h +++ b/src/core/histogram.h @@ -16,10 +16,15 @@ public: QHash* get(Histogram::Channel); QImage getImage(Histogram::Channel, QBrush); int maximumValue(Channel); + int getMaxFromQHashHelper( QHash *); + int getMinFromQHashHelper( QHash *); + int getMinKey( QHash *); + int getMaxKey( QHash *); private: void generate(QImage*); // iterates all parent image pixels and set the Hashes + QHash* R; QHash* G; QHash* B; diff --git a/src/core/transformations/histogram_stretching.cpp b/src/core/transformations/histogram_stretching.cpp index 25440de..f1db580 100644 --- a/src/core/transformations/histogram_stretching.cpp +++ b/src/core/transformations/histogram_stretching.cpp @@ -14,13 +14,41 @@ HistogramStretching::HistogramStretching(PNM* img, ImageViewer* iv) : PNM* HistogramStretching::transform() { + qDebug() << Q_FUNC_INFO << "START"; int width = image->width(); int height = image->height(); PNM* newImage = new PNM(width, height, image->format()); + Histogram * histogram = image->getHistogram(); - qDebug() << Q_FUNC_INFO << "Not implemented yet!"; + int maxRed = histogram->getMaxKey(histogram->get(histogram->RChannel)); + int minRed = histogram->getMinKey(histogram->get(histogram->RChannel)); + int maxGreen = histogram->getMaxKey(histogram->get(histogram->GChannel)); + int minGreen = histogram->getMinKey(histogram->get(histogram->GChannel)); + + int maxBlue = histogram->getMaxKey(histogram->get(histogram->BChannel)); + int minBlue = histogram->getMinKey(histogram->get(histogram->BChannel)); + + int maxAlpha = histogram->getMaxKey(histogram->get(histogram->LChannel)); + int minAlpha = histogram->getMinKey(histogram->get(histogram->LChannel)); + + qDebug() << Q_FUNC_INFO << "LOOP"; + for(int x = 0 ; x < width; x++){ + for (int y = 0 ; y < height; y++) { + + QRgb pixel = image->pixel(x,y); + int g = (qGreen(pixel) - minGreen) * (MAX_VALUE/(maxGreen-minGreen)); + int r = (qRed(pixel) - minRed) * (MAX_VALUE/(maxRed-minRed)); + int b = (qBlue(pixel) - minBlue) * (MAX_VALUE/(maxBlue-minBlue)); + // int a = (qAlpha(pixel) - minAlpha) * (MAX_VALUE/(maxAlpha-minAlpha)); + + qDebug() << Q_FUNC_INFO << "1. Here is working !!"; + QRgb blee = QColor(r,g,b).rgba(); + qDebug() << Q_FUNC_INFO << "2. Here is workingt too !!"; + newImage->setPixel(x,y,QColor(r,g,b).rgba()); + } + } return newImage; } diff --git a/src/core/transformations/histogram_stretching.cpp.autosave b/src/core/transformations/histogram_stretching.cpp.autosave new file mode 100644 index 0000000..0e917e2 --- /dev/null +++ b/src/core/transformations/histogram_stretching.cpp.autosave @@ -0,0 +1,48 @@ +#include "histogram_stretching.h" + +#include "../histogram.h" + +HistogramStretching::HistogramStretching(PNM* img) : + Transformation(img) +{ +} + +HistogramStretching::HistogramStretching(PNM* img, ImageViewer* iv) : + Transformation(img, iv) +{ +} + +PNM* HistogramStretching::transform() +{ + qDebug() << Q_FUNC_INFO << "START"; + int width = image->width(); + int height = image->height(); + + PNM* newImage = new PNM(width, height, image->format()); + Histogram * histogram = image->getHistogram(); + + int maxRed = histogram->getMaxKey(histogram->get(histogram->RChannel)); + int minRed = histogram->getMinKey(histogram->get(histogram->RChannel)); + + int maxGreen = histogram->getMaxKey(histogram->get(histogram->GChannel)); + int minGreen = histogram->getMinKey(histogram->get(histogram->GChannel)); + + int maxBlue = histogram->getMaxKey(histogram->get(histogram->BChannel)); + int minBlue = histogram->getMinKey(histogram->get(histogram->BChannel)); + + + qDebug() << Q_FUNC_INFO << "LOOP"; + for(int x = 0 ; x < width; x++){ + for (int y = 0 ; y < height; y++) { + + QRgb pixel = image->pixel(x,y); + int g = (qGreen(pixel) - minGreen) * (MAX_VALUE/(maxGreen-minGreen)); + int r = (qRed(pixel) - minRed) * (MAX_VALUE/(maxRed-minRed)); + int b = (qBlue(pixel) - minBlue) * (MAX_VALUE/(maxBlue-minBlue)); + newImage->setPixel(x,y,QColor(r,g,b).rgba()); + } + } + return newImage; +} + + diff --git a/src/core/transformations/histogram_stretching.h b/src/core/transformations/histogram_stretching.h index 0f926db..8ce2757 100644 --- a/src/core/transformations/histogram_stretching.h +++ b/src/core/transformations/histogram_stretching.h @@ -6,6 +6,7 @@ class HistogramStretching : public Transformation { public: + int const MAX_VALUE = 255; HistogramStretching(PNM*); HistogramStretching(PNM*, ImageViewer* iv); From ebc28216cd72bd56b4f7c845c676e6e91eed5246 Mon Sep 17 00:00:00 2001 From: Dawid_Kreft Date: Sun, 22 Mar 2020 19:10:02 +0100 Subject: [PATCH 3/4] Zadanie 3 ready with all changes --- src/core/histogram.cpp | 20 +++--- .../histogram_equalization.cpp | 66 ++++++++++++++++++- .../transformations/histogram_equalization.h | 4 ++ .../transformations/histogram_stretching.cpp | 12 +--- .../histogram_stretching.cpp.autosave | 48 -------------- 5 files changed, 80 insertions(+), 70 deletions(-) delete mode 100644 src/core/transformations/histogram_stretching.cpp.autosave diff --git a/src/core/histogram.cpp b/src/core/histogram.cpp index 00628f1..2024b14 100644 --- a/src/core/histogram.cpp +++ b/src/core/histogram.cpp @@ -29,11 +29,13 @@ void Histogram::generate(QImage* image) for(int i = 0 ; i < image->height(); i++){ for(int j = 0 ; j < image->width() ; j++){ QColor *clrCurrent = new QColor( image->pixel(i,j) ); - R->insert(clrCurrent->red(),R->value(clrCurrent->red())+1); - G->insert(clrCurrent->green(),R->value(clrCurrent->green())+1); - B->insert(clrCurrent->blue(),R->value(clrCurrent->blue())+1); - L->insert(clrCurrent->alpha(),R->value(clrCurrent->alpha())+1); - } + + QRgb pixel = image->pixel(i,j); + R->insert(qRed(pixel),R->value(qRed(pixel))+1); + G->insert(qGreen(pixel),G->value(qGreen(pixel))+1); + B->insert(qBlue(pixel),B->value(qBlue(pixel))+1); + L->insert(qAlpha(pixel),L->value(qAlpha(pixel))+1); + } } } @@ -65,7 +67,7 @@ int Histogram::getMaxFromQHashHelper( QHash * channel ){ QHash::const_iterator iterator = channel->begin(); while (iterator != channel->end()) { - if(iterator.value() > max){ + if(iterator.value() > max && iterator.value() != 0 ){ max = iterator.value(); } ++iterator; @@ -80,7 +82,7 @@ int Histogram::getMaxKey( QHash * channel ){ QHash::const_iterator iterator = channel->begin(); while (iterator != channel->end()) { - if(iterator.key() > max){ + if(iterator.key() > max && iterator.value() != 0){ max = iterator.key(); } ++iterator; @@ -95,7 +97,7 @@ int Histogram::getMinKey( QHash * channel ){ QHash::const_iterator iterator = channel->begin(); while (iterator != channel->end()) { - if(iterator.key() < min){ + if(iterator.key() < min && iterator.value() != 0){ min = iterator.key(); } ++iterator; @@ -111,7 +113,7 @@ int Histogram::getMinFromQHashHelper( QHash * channel ){ QHash::const_iterator iterator = channel->begin(); while (iterator != channel->end()) { - if(iterator.value() < min){ + if(iterator.value() < min && iterator.value() != 0){ min = iterator.value(); } ++iterator; diff --git a/src/core/transformations/histogram_equalization.cpp b/src/core/transformations/histogram_equalization.cpp index ab76cd3..a9b43dc 100644 --- a/src/core/transformations/histogram_equalization.cpp +++ b/src/core/transformations/histogram_equalization.cpp @@ -16,11 +16,73 @@ PNM* HistogramEqualization::transform() { int width = image->width(); int height = image->height(); - + int pixelAmounts = width* height; PNM* newImage = new PNM(width, height, image->format()); + double LUTr[256], LUTg[256], LUTb[256], + redHist[256], greenHist[256], blueHist[256], + distRed[256], distGreen[256], distBlue[256]; - qDebug() << Q_FUNC_INFO << "Not implemented yet!"; + zeros(redHist,greenHist,blueHist); + zeros(distRed,distGreen,distBlue); + zeros(LUTr,LUTb,LUTg); + for (int x = 0; x < width; x++){ + for (int y = 0; y < height; y++) + { + QRgb pixel = image->pixel(x,y); + redHist[qRed(pixel)]++; + greenHist[qGreen(pixel)]++; + blueHist[qBlue(pixel)]++; + } + } + + double sumR = 0; + double sumG = 0; + double sumB = 0; + + for (int i=0; i<256; i++) + { + sumR += (redHist[i]/pixelAmounts); + sumG += (greenHist[i]/pixelAmounts); + sumB += (blueHist[i]/pixelAmounts); + distRed[i] += sumR; + distGreen[i] += sumG; + distBlue[i] += sumB; + } + + prepareLUTperChannel(distRed, LUTr); + prepareLUTperChannel(distGreen, LUTg ); + prepareLUTperChannel(distBlue, LUTb ); + for (int i = 0; i< width; i++){ + for (int j = 0; j< height; j++) + { + QRgb pixel = image->pixel(i,j); + newImage->setPixel(i,j, QColor( LUTr[qRed(pixel)], LUTg[qGreen(pixel)], LUTb[qBlue(pixel)]).rgba() ); + } + } return newImage; } +void HistogramEqualization::prepareLUTperChannel(double *D, double *LUT) +{ + double Dmin = 0; + for(int i = 0; i < 256 ; i++){ + if(D[i+1] > 0){ + Dmin = D[i+1]; + break; + } + } + + for (int i=0; i<256; i++){ + LUT[i] = ( 255* ((D[i] - Dmin) / (1 - Dmin))) ; + } +} + +void HistogramEqualization::zeros(double * r_tab, double * g_tab, double* b_tab){ + for (int i=0; i<256; i++) + { + r_tab[i] = 0; + g_tab[i] = 0; + b_tab[i] = 0; + } +} diff --git a/src/core/transformations/histogram_equalization.h b/src/core/transformations/histogram_equalization.h index 08057b4..afa3adf 100644 --- a/src/core/transformations/histogram_equalization.h +++ b/src/core/transformations/histogram_equalization.h @@ -8,8 +8,12 @@ class HistogramEqualization : public Transformation public: HistogramEqualization(PNM*); HistogramEqualization(PNM*, ImageViewer*); + QHash prepareDistrubuantPerChannel(QHash * , int); + void prepareLUTperChannel(double *, double * ); + void zeros(double *, double * , double * ); virtual PNM* transform(); + int min(QHash *dist); }; diff --git a/src/core/transformations/histogram_stretching.cpp b/src/core/transformations/histogram_stretching.cpp index f1db580..493b061 100644 --- a/src/core/transformations/histogram_stretching.cpp +++ b/src/core/transformations/histogram_stretching.cpp @@ -14,10 +14,9 @@ HistogramStretching::HistogramStretching(PNM* img, ImageViewer* iv) : PNM* HistogramStretching::transform() { - qDebug() << Q_FUNC_INFO << "START"; + int width = image->width(); int height = image->height(); - PNM* newImage = new PNM(width, height, image->format()); Histogram * histogram = image->getHistogram(); @@ -30,10 +29,6 @@ PNM* HistogramStretching::transform() int maxBlue = histogram->getMaxKey(histogram->get(histogram->BChannel)); int minBlue = histogram->getMinKey(histogram->get(histogram->BChannel)); - int maxAlpha = histogram->getMaxKey(histogram->get(histogram->LChannel)); - int minAlpha = histogram->getMinKey(histogram->get(histogram->LChannel)); - - qDebug() << Q_FUNC_INFO << "LOOP"; for(int x = 0 ; x < width; x++){ for (int y = 0 ; y < height; y++) { @@ -41,11 +36,6 @@ PNM* HistogramStretching::transform() int g = (qGreen(pixel) - minGreen) * (MAX_VALUE/(maxGreen-minGreen)); int r = (qRed(pixel) - minRed) * (MAX_VALUE/(maxRed-minRed)); int b = (qBlue(pixel) - minBlue) * (MAX_VALUE/(maxBlue-minBlue)); - // int a = (qAlpha(pixel) - minAlpha) * (MAX_VALUE/(maxAlpha-minAlpha)); - - qDebug() << Q_FUNC_INFO << "1. Here is working !!"; - QRgb blee = QColor(r,g,b).rgba(); - qDebug() << Q_FUNC_INFO << "2. Here is workingt too !!"; newImage->setPixel(x,y,QColor(r,g,b).rgba()); } } diff --git a/src/core/transformations/histogram_stretching.cpp.autosave b/src/core/transformations/histogram_stretching.cpp.autosave deleted file mode 100644 index 0e917e2..0000000 --- a/src/core/transformations/histogram_stretching.cpp.autosave +++ /dev/null @@ -1,48 +0,0 @@ -#include "histogram_stretching.h" - -#include "../histogram.h" - -HistogramStretching::HistogramStretching(PNM* img) : - Transformation(img) -{ -} - -HistogramStretching::HistogramStretching(PNM* img, ImageViewer* iv) : - Transformation(img, iv) -{ -} - -PNM* HistogramStretching::transform() -{ - qDebug() << Q_FUNC_INFO << "START"; - int width = image->width(); - int height = image->height(); - - PNM* newImage = new PNM(width, height, image->format()); - Histogram * histogram = image->getHistogram(); - - int maxRed = histogram->getMaxKey(histogram->get(histogram->RChannel)); - int minRed = histogram->getMinKey(histogram->get(histogram->RChannel)); - - int maxGreen = histogram->getMaxKey(histogram->get(histogram->GChannel)); - int minGreen = histogram->getMinKey(histogram->get(histogram->GChannel)); - - int maxBlue = histogram->getMaxKey(histogram->get(histogram->BChannel)); - int minBlue = histogram->getMinKey(histogram->get(histogram->BChannel)); - - - qDebug() << Q_FUNC_INFO << "LOOP"; - for(int x = 0 ; x < width; x++){ - for (int y = 0 ; y < height; y++) { - - QRgb pixel = image->pixel(x,y); - int g = (qGreen(pixel) - minGreen) * (MAX_VALUE/(maxGreen-minGreen)); - int r = (qRed(pixel) - minRed) * (MAX_VALUE/(maxRed-minRed)); - int b = (qBlue(pixel) - minBlue) * (MAX_VALUE/(maxBlue-minBlue)); - newImage->setPixel(x,y,QColor(r,g,b).rgba()); - } - } - return newImage; -} - - From 908b1fd1f28caf971244afb5f3b30a19153e34b6 Mon Sep 17 00:00:00 2001 From: Dawid_Kreft Date: Sun, 22 Mar 2020 19:17:16 +0100 Subject: [PATCH 4/4] Update doc --- specification.doc | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/specification.doc b/specification.doc index 195055c..e310874 100644 --- a/specification.doc +++ b/specification.doc @@ -1 +1,18 @@ Plik z Dokumentacja do projektu + + +Zadanie 3 +Histogram to wyliczenie ile razy wystepuje dana wartośc koloru w obrazie. +Dla każdego kanału : rgb liczona jest liczba wystąpień każdego odcienia od 0 do 255. + +Rozciągniecie histogramu : +najpierw szukamy lewej (min) i prawej (max) krawędzi histogramu, tzn. od jakiej wartości piksela (idąc od lewej i od prawej) zaczynają się pierwsze niezerowe wartości histogramu, +rozciągamy histogram, czyli każdemu pikselowi na obrazie dajemy nową wartość wg wzoru: + Pixel-new [x,y] = (255/ max-min) * pixel-old[x,y] - min + + Wyrównanie + To wyliczenie dystrybuanty czyli histogramu podzielonego przez sume. Mamy takzwane prawdopobienstwo wystapienia + a nastepnie wyliczenie na podstawie wzoru: + Lut[i] = ( ( D[i] - Dmin) / 1 - Dmin ) ) * k-1 , gdzie k to liczba poziomow odcienia czyli 256 + + \ No newline at end of file