From 722fcbfed28ab6dd5dbece5c35654ae5614ba734 Mon Sep 17 00:00:00 2001 From: Kamila Malanowicz Date: Tue, 14 Apr 2020 20:43:28 +0200 Subject: [PATCH] Zadanie 3 - Histogram --- lpo-projekt-v2/src/core/histogram.cpp | 54 ++++++++++- .../histogram_equalization.cpp | 86 ++++++++++++++++- .../transformations/histogram_stretching.cpp | 93 ++++++++++++++++++- 3 files changed, 228 insertions(+), 5 deletions(-) diff --git a/lpo-projekt-v2/src/core/histogram.cpp b/lpo-projekt-v2/src/core/histogram.cpp index 1287666..31fc8ce 100644 --- a/lpo-projekt-v2/src/core/histogram.cpp +++ b/lpo-projekt-v2/src/core/histogram.cpp @@ -24,15 +24,63 @@ Histogram::~Histogram() void Histogram::generate(QImage* image) { - qDebug() << Q_FUNC_INFO << "Not implemented yet!"; + qDebug() << Q_FUNC_INFO << "Histogram!"; + qDebug() << Q_FUNC_INFO << image->height(); + qDebug() << Q_FUNC_INFO << image->width(); + for ( int row = 0; row < image->height(); ++row ) { + for ( int col = 0; col < image->width(); ++col ) { + QColor clrCurrent( image->pixel( row, col ) ); + if (R->contains(clrCurrent.red())) { + R->insert(clrCurrent.red(), R->value(clrCurrent.red()) + 1); + } else { + R->insert(clrCurrent.red(), 1); + } + if (G->contains(clrCurrent.green())) { + G->insert(clrCurrent.green(), G->value(clrCurrent.green()) + 1); + } else { + G->insert(clrCurrent.green(), 1); + } + if (B->contains(clrCurrent.blue())) { + B->insert(clrCurrent.blue(), B->value(clrCurrent.blue()) + 1); + } else { + B->insert(clrCurrent.blue(), 1); + } + if (L->contains(clrCurrent.alpha())) { + L->insert(clrCurrent.alpha(), L->value(clrCurrent.alpha()) + 1); + } else { + L->insert(clrCurrent.alpha(), 1); + } + } + } } /** Returns the maximal value of the histogram in the given channel */ int Histogram::maximumValue(Channel selectedChannel = RGB) { - qDebug() << Q_FUNC_INFO << "Not implemented yet!"; + qDebug() << Q_FUNC_INFO << "Max value!"; + qDebug() << Q_FUNC_INFO << selectedChannel; + int max = 1; - return 0; + if (selectedChannel == RGB) { + qDebug() << Q_FUNC_INFO << "RGB"; + max = maximumValue(RChannel); + int maxG = maximumValue(GChannel); + if (maxG > max) { + max = maxG; + } + int maxB = maximumValue(BChannel); + if (maxB > max) { + max = maxB; + } + } else { + qDebug() << Q_FUNC_INFO << "selectedChannel"; + foreach(int value, get(selectedChannel)->values()) { + if (value > max) { + max = value; + } + } + } + return max; } diff --git a/lpo-projekt-v2/src/core/transformations/histogram_equalization.cpp b/lpo-projekt-v2/src/core/transformations/histogram_equalization.cpp index ab76cd3..1dc604d 100644 --- a/lpo-projekt-v2/src/core/transformations/histogram_equalization.cpp +++ b/lpo-projekt-v2/src/core/transformations/histogram_equalization.cpp @@ -19,7 +19,91 @@ PNM* HistogramEqualization::transform() PNM* newImage = new PNM(width, height, image->format()); - qDebug() << Q_FUNC_INFO << "Not implemented yet!"; + if (image->format() == QImage::Format_Indexed8) { + double prob[256] = { 0.0 }; + + Histogram::Channel channelL = Histogram::Channel::LChannel; + QHash* histL = image->getHistogram()->get(channelL); + + QHash::const_iterator i = histL->constBegin(); + while (i != histL->constEnd()) { + prob[i.key()] = (double)i.value() / (double)(width * height); + ++i; + } + + double distr[256] = { prob[0] }; + + for (int i = 1; i < 256; i++) { + distr[i] = distr[i - 1] + prob[i]; + } + + for (int i = 0; i < 256; i++) { + distr[i] = distr[i] * 255; + } + + for (int x = 0; x < width; x++) { + for (int y = 0; y < height; y++) { + newImage->setPixel(x, y, (int)distr[qGray(image->pixel(x, y))]); + } + } + + return newImage; + } + + double probR[256] = { 0.0 }; + double probG[256] = { 0.0 }; + double probB[256] = { 0.0 }; + + Histogram::Channel channelR = Histogram::Channel::RChannel; + Histogram::Channel channelG = Histogram::Channel::GChannel; + Histogram::Channel channelB = Histogram::Channel::BChannel; + QHash* histR = image->getHistogram()->get(channelR); + QHash* histG = image->getHistogram()->get(channelG); + QHash* histB = image->getHistogram()->get(channelB); + + QHash::const_iterator iR = histR->constBegin(); + while (iR != histR->constEnd()) { + probR[iR.key()] = (double)iR.value() / (double)(width * height); + ++iR; + } + + QHash::const_iterator iG = histG->constBegin(); + while (iG != histG->constEnd()) { + probG[iG.key()] = (double)iG.value() / (double)(width * height); + ++iG; + } + + QHash::const_iterator iB = histB->constBegin(); + while (iB != histB->constEnd()) { + probB[iB.key()] = (double)iB.value() / (double)(width * height); + ++iB; + } + + double distrR[256] = { probR[0] }; + double distrG[256] = { probG[0] }; + double distrB[256] = { probB[0] }; + + for (int i = 1; i < 256; i++) { + distrR[i] = distrR[i - 1] + probR[i]; + distrG[i] = distrG[i - 1] + probG[i]; + distrB[i] = distrB[i - 1] + probB[i]; + } + + for (int i = 0; i < 256; i++) { + distrR[i] = distrR[i] * 255; + distrG[i] = distrG[i] * 255; + distrB[i] = distrB[i] * 255; + } + + for (int i = 0; i < width; i++) { + for (int j = 0; j < height; j++) { + int r = (int) distrR[qRed( image->pixel(i,j))]; + int g = (int) distrG[qGreen(image->pixel(i,j))]; + int b = (int) distrB[qBlue(image->pixel(i,j))]; + + newImage->setPixel(i, j, QColor(r,g,b).rgb()); + } + } return newImage; } diff --git a/lpo-projekt-v2/src/core/transformations/histogram_stretching.cpp b/lpo-projekt-v2/src/core/transformations/histogram_stretching.cpp index 25440de..726ec20 100644 --- a/lpo-projekt-v2/src/core/transformations/histogram_stretching.cpp +++ b/lpo-projekt-v2/src/core/transformations/histogram_stretching.cpp @@ -17,9 +17,100 @@ PNM* HistogramStretching::transform() int width = image->width(); int height = image->height(); + int minR = INT_MAX; + int maxR = INT_MIN; + int minG = INT_MAX; + int maxG = INT_MIN; + int minB = INT_MAX; + int maxB = INT_MIN; + PNM* newImage = new PNM(width, height, image->format()); - qDebug() << Q_FUNC_INFO << "Not implemented yet!"; + if (image->format() == QImage::Format_Indexed8) { + Histogram::Channel channelL = Histogram::Channel::LChannel; + QHash* histL = image->getHistogram()->get(channelL); + int minL = INT_MAX; + int maxL = INT_MIN; + + QHash::const_iterator i = histL->constBegin(); + while (i != histL->constEnd()) { + if (i.key() < minL && i.value() > 0) { + minL = i.key(); + } + if (i.key() > maxL && i.value() > 0) { + maxL = i.key(); + } + ++i; + } + + for (int i = 0; i < width; i++) { + for (int j = 0; j < height; j++) { + int l = (255 * (qGray(image->pixel(i,j)) - minL)) /(maxL - minL); + newImage->setPixel(i,j,l); + } + } + + return newImage; + } + + Histogram::Channel channelR = Histogram::Channel::RChannel; + Histogram::Channel channelG = Histogram::Channel::GChannel; + Histogram::Channel channelB = Histogram::Channel::BChannel; + QHash* histR = image->getHistogram()->get(channelR); + QHash* histG = image->getHistogram()->get(channelG); + QHash* histB = image->getHistogram()->get(channelB); + + foreach(int i, histR->keys()) { + if (i < minR && histR->value(i) > 0) { + minR = i; + } + if (i > maxR && histR->value(i) > 0) { + maxR = i; + } + } + + QHash::const_iterator iR = histR->constBegin(); + while (iR != histR->constEnd()) { + if (iR.key() < minR && iR.value() > 0) { + minR = iR.key(); + } + if (iR.key() > maxR && iR.value() > 0) { + maxR = iR.key(); + } + ++iR; + } + + QHash::const_iterator iG = histG->constBegin(); + while (iG != histG->constEnd()) { + if (iG.key() < minG && iG.value() > 0) { + minG = iG.key(); + } + if (iG.key() > maxG && iG.value() > 0) { + maxG = iG.key(); + } + ++iG; + } + + QHash::const_iterator iB = histB->constBegin(); + while (iB != histB->constEnd()) { + if (iB.key() < minB && iB.value() > 0) { + minB = iB.key(); + } + if (iB.key() > maxB && iB.value() > 0) { + maxB = iB.key(); + } + ++iB; + } + + for (int i = 0; i < width; i++) { + for (int j = 0; j < height; j++) { + int r = (255 * (qRed(image->pixel(i,j)) - minR)) / (maxR - minR); + int g = (255 * (qGreen(image->pixel(i,j)) - minG)) / (maxG - minG); + int b = (255 * (qBlue(image->pixel(i,j)) - minB)) / (maxB - minB); + + newImage->setPixel(i,j,QColor(r,g,b).rgb()); + } + } return newImage; }