1
0

Zadanie 3

This commit is contained in:
Jarosław Wieczorek 2021-03-19 22:59:32 +01:00
parent 9278aa08db
commit 5b18f63379
7 changed files with 539 additions and 10 deletions

View File

@ -1,3 +1,5 @@
# Rozwiązania laboratoria 03 # Rozwiązania laboratoria 03
# Znajdują się w katalogu ./03/do_sprawdzenia/cpp/mysimplegimp Cały kod znajduje się w katalogu głównym ,,app/cpp/mysimplegimp''
Zmienieone pliki projektu dla zadania 3-ego znajdują się w katalogu ,,03/do_sprawdzenia''

View File

@ -0,0 +1,136 @@
#include "histogram.h"
#include <QDebug>
#include <QPainter>
#include <cmath>
Histogram::Histogram(QImage* image)
{
R = new QHash<int, int>;
G = new QHash<int, int>;
B = new QHash<int, int>;
L = new QHash<int, int>;
generate(image);
}
Histogram::~Histogram()
{
delete R;
delete G;
delete B;
delete L;
}
void Histogram::generate(QImage* image)
{
int width = image->width();
int height = image->height();
for (int x = 0; x < width; x++) {
for (int y = 0; y < height; y++) {
QRgb pixel = image->pixel(x,y);
// Get color values
int r = Histogram::R->value(qRed(pixel));
int g = Histogram::G->value(qGreen(pixel));
int b = Histogram::B->value(qBlue(pixel));
int l = Histogram::L->value(qGray(pixel));
// Insert color values
Histogram::R->insert(qRed(pixel), r+1);
Histogram::G->insert(qGreen(pixel), g+1);
Histogram::B->insert(qBlue(pixel), b+1);
Histogram::L->insert(qGray(pixel), l+1);
}
}
}
/** Returns the maximal value of the histogram in the given channel */
int Histogram::maximumValue(Channel selectedChannel = RGB)
{
// Create and set max value
int max = 0;
// Iterate over values
for(int i = 0; i < R->size(); i++)
{
if(R->value(i) > max)
{
max = R->value(i);
}
}
for(int i = 0; i < G->size(); i++)
{
if(G->value(i) > max)
{
max = G->value(i);
}
}
for(int i = 0; i < B->size(); i++)
{
if(B->value(i) > max)
{
max = B->value(i);
}
}
for(int i = 0; i < L->size(); i++)
{
if(L->value(i) > max)
{
max = L->value(i);
}
}
return max;
}
/** Returns a pointer to the given channel QHash<int, int> */
QHash<int, int>* Histogram::get(Channel channel = LChannel)
{
if (channel==LChannel) return L;
if (channel==RChannel) return R;
if (channel==GChannel) return G;
if (channel==BChannel) return B;
return 0;
}
/**
* Returns a 255 by 100 QImage containing a Histogram for the given channel.
* The background is transparent (Alpha 0, RGB=255) */
QImage Histogram::getImage(Channel channel = LChannel, QBrush pen = Qt::gray)
{
// Create blank QImage and fill it with transparent background:
QImage histImage(255, 100, QImage::Format_ARGB32);
histImage.fill(0);
QPainter painter(&histImage);
painter.setBrush(Qt::transparent);
painter.setPen(Qt::transparent);
painter.drawRect(0,0,255,100);
// Calculate the aspect ratio using the maximal value of the color histograms
int maximum = (channel == LChannel ? maximumValue(LChannel) : maximumValue(RGB));
float ratio = 100.0/float(maximum);
// Preparing the painter:
painter.setBrush(pen);
painter.setPen(pen.color());
int h;
// Draw histogram
QHash<int, int>* hist = get(channel);
QHash<int, int>::const_iterator cit = hist->begin();
while (cit != hist->end())
{
h = 100 - floor(ratio*cit.value());
painter.drawLine(cit.key(), h, cit.key(), 100);
++cit;
}
return histImage;
}

View File

@ -0,0 +1,108 @@
#include "histogram_equalization.h"
#include "../histogram.h"
HistogramEqualization::HistogramEqualization(PNM* img) :
Transformation(img)
{
}
HistogramEqualization::HistogramEqualization(PNM* img, ImageViewer* iv) :
Transformation(img, iv)
{
}
PNM* HistogramEqualization::transform()
{
float width = image->width();
float height = image->height();
PNM* newImage = new PNM(width, height, image->format());
// Create histogram
Histogram* histogram = image->getHistogram();
// Create pointers QHash<int, int>
QHash<int, int>* R = histogram->get(Histogram::RChannel);
QHash<int, int>* G = histogram->get(Histogram::GChannel);
QHash<int, int>* B = histogram->get(Histogram::BChannel);
QHash<int, int>* L = histogram->get(Histogram::LChannel);
// Setup Channel p
float Rp[255];
float Gp[255];
float Bp[255];
float Lp[255];
// Setup Channel D
float RD[255];
float GD[255];
float BD[255];
float LD[255];
// Get size
float size = width * height;
// Create template values
float tempSumR=0;
float tempSumG=0;
float tempSumB=0;
float tempSumL=0;
for (int i=0; i<256; i++)
{
// Set Xp[i] values
Rp[i] = (R->value(i))/(size);
Gp[i] = (G->value(i))/(size);
Bp[i] = (B->value(i))/(size);
Lp[i] = (L->value(i))/(size);
}
for(int i=0; i<255; i++)
{
// Red
tempSumR=Rp[i]+tempSumR;
RD[i]=tempSumR;
// Green
tempSumG=Gp[i]+tempSumG;
GD[i]=tempSumG;
// Blue
tempSumB=Bp[i]+tempSumB;
BD[i]=tempSumB;
// L
tempSumL=Lp[i]+tempSumL;
LD[i]=tempSumL;
}
// For each pixel
for (int x=0; x<width; x++)
{
for (int y=0; y<height; y++)
{
// Get pixel
QRgb pixel = image->pixel(x, y);
// Set new values
int r = RD[qRed(pixel)] * 255;
int g = GD[qGreen(pixel)] * 255;
int b = BD[qBlue(pixel)] * 255;
int l = LD[qGray(pixel)] * 255;
if (image->format() == QImage::Format_RGB32)
{
newImage->setPixel(x, y, QColor(r,g,b).rgb());
}
else
{
newImage->setPixel(x, y, l);
}
}
}
return newImage;
}

View File

@ -0,0 +1,88 @@
#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()
{
int width = image->width();
int height = image->height();
PNM* newImage = new PNM(width, height, image->format());
// Create min values
int minR = 0;
int minG = 0;
int minB = 0;
int minL = 0;
// Create max values
int maxR = 255;
int maxG = 255;
int maxB = 255;
int maxL = 255;
// Create histogram
Histogram* histogram = image->getHistogram();
// Create pointers QHash<int, int>
QHash<int, int>* R = histogram->get(histogram->RChannel);
QHash<int, int>* G = histogram->get(histogram->GChannel);
QHash<int, int>* B = histogram->get(histogram->BChannel);
QHash<int, int>* L = histogram->get(histogram->LChannel);
// Increment max values
for (int i=0; i<256; i++)
{
if (R->value(minR) == 0) minR++;
if (G->value(minG) == 0) minG++;
if (B->value(minB) == 0) minB++;
if (L->value(minL) == 0) minL++;
}
// Decrement max values
for (int i=256; i>0; i--)
{
if (R->value(maxR) == 0) maxR--;
if (G->value(maxG) == 0) maxG--;
if (B->value(maxB) == 0) maxB--;
if (L->value(maxL) == 0) maxL--;
}
// Iterate over pixels
for (int x=0; x<width; x++)
{
for (int y=0; y<height; y++)
{
QRgb pixel = image->pixel(x, y);
// Calculate new values
int r = (255/(maxR-minR))*(qRed(pixel)-minR);
int g = (255/(maxG-minG))*(qGreen(pixel)-minG);
int b = (255/(maxB-minB))*(qBlue(pixel)-minB);
int l = (255/(maxL-minL))*(qGray(pixel)-minL);
if (image->format() == QImage::Format_RGB32)
{
// Set pixel in RGB32 model
newImage->setPixel(x, y, QColor(r,g,b).rgb());
}
else
{
// Set pixel
newImage->setPixel(x, y, l);
}
}
}
return newImage;
}

View File

@ -24,15 +24,67 @@ Histogram::~Histogram()
void Histogram::generate(QImage* image) void Histogram::generate(QImage* image)
{ {
qDebug() << Q_FUNC_INFO << "Not implemented yet!"; int width = image->width();
int height = image->height();
for (int x = 0; x < width; x++) {
for (int y = 0; y < height; y++) {
QRgb pixel = image->pixel(x,y);
// Get color values
int r = Histogram::R->value(qRed(pixel));
int g = Histogram::G->value(qGreen(pixel));
int b = Histogram::B->value(qBlue(pixel));
int l = Histogram::L->value(qGray(pixel));
// Insert color values
Histogram::R->insert(qRed(pixel), r+1);
Histogram::G->insert(qGreen(pixel), g+1);
Histogram::B->insert(qBlue(pixel), b+1);
Histogram::L->insert(qGray(pixel), l+1);
}
}
} }
/** Returns the maximal value of the histogram in the given channel */ /** Returns the maximal value of the histogram in the given channel */
int Histogram::maximumValue(Channel selectedChannel = RGB) int Histogram::maximumValue(Channel selectedChannel = RGB)
{ {
qDebug() << Q_FUNC_INFO << "Not implemented yet!"; // Create and set max value
int max = 0;
return 0; // Iterate over values
for(int i = 0; i < R->size(); i++)
{
if(R->value(i) > max)
{
max = R->value(i);
}
}
for(int i = 0; i < G->size(); i++)
{
if(G->value(i) > max)
{
max = G->value(i);
}
}
for(int i = 0; i < B->size(); i++)
{
if(B->value(i) > max)
{
max = B->value(i);
}
}
for(int i = 0; i < L->size(); i++)
{
if(L->value(i) > max)
{
max = L->value(i);
}
}
return max;
} }

View File

@ -14,13 +14,95 @@ 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();
PNM* newImage = new PNM(width, height, image->format()); PNM* newImage = new PNM(width, height, image->format());
qDebug() << Q_FUNC_INFO << "Not implemented yet!"; // Create histogram
Histogram* histogram = image->getHistogram();
// Create pointers QHash<int, int>
QHash<int, int>* R = histogram->get(Histogram::RChannel);
QHash<int, int>* G = histogram->get(Histogram::GChannel);
QHash<int, int>* B = histogram->get(Histogram::BChannel);
QHash<int, int>* L = histogram->get(Histogram::LChannel);
// Setup Channel p
float Rp[255];
float Gp[255];
float Bp[255];
float Lp[255];
// Setup Channel D
float RD[255];
float GD[255];
float BD[255];
float LD[255];
// Get size
float size = width * height;
// Create template values
float tempSumR=0;
float tempSumG=0;
float tempSumB=0;
float tempSumL=0;
for (int i=0; i<256; i++)
{
// Set Xp[i] values
Rp[i] = (R->value(i))/(size);
Gp[i] = (G->value(i))/(size);
Bp[i] = (B->value(i))/(size);
Lp[i] = (L->value(i))/(size);
}
for(int i=0; i<255; i++)
{
// Red
tempSumR=Rp[i]+tempSumR;
RD[i]=tempSumR;
// Green
tempSumG=Gp[i]+tempSumG;
GD[i]=tempSumG;
// Blue
tempSumB=Bp[i]+tempSumB;
BD[i]=tempSumB;
// L
tempSumL=Lp[i]+tempSumL;
LD[i]=tempSumL;
}
// For each pixel
for (int x=0; x<width; x++)
{
for (int y=0; y<height; y++)
{
// Get pixel
QRgb pixel = image->pixel(x, y);
// Set new values
int r = RD[qRed(pixel)] * 255;
int g = GD[qGreen(pixel)] * 255;
int b = BD[qBlue(pixel)] * 255;
int l = LD[qGray(pixel)] * 255;
if (image->format() == QImage::Format_RGB32)
{
newImage->setPixel(x, y, QColor(r,g,b).rgb());
}
else
{
newImage->setPixel(x, y, l);
}
}
}
return newImage; return newImage;
} }

View File

@ -14,13 +14,74 @@ HistogramStretching::HistogramStretching(PNM* img, ImageViewer* iv) :
PNM* HistogramStretching::transform() PNM* HistogramStretching::transform()
{ {
int width = image->width(); int width = image->width();
int height = image->height(); int height = image->height();
PNM* newImage = new PNM(width, height, image->format()); PNM* newImage = new PNM(width, height, image->format());
qDebug() << Q_FUNC_INFO << "Not implemented yet!"; // Create min values
int minR = 0;
int minG = 0;
int minB = 0;
int minL = 0;
// Create max values
int maxR = 255;
int maxG = 255;
int maxB = 255;
int maxL = 255;
// Create histogram
Histogram* histogram = image->getHistogram();
// Create pointers QHash<int, int>
QHash<int, int>* R = histogram->get(histogram->RChannel);
QHash<int, int>* G = histogram->get(histogram->GChannel);
QHash<int, int>* B = histogram->get(histogram->BChannel);
QHash<int, int>* L = histogram->get(histogram->LChannel);
// Increment max values
for (int i=0; i<256; i++)
{
if (R->value(minR) == 0) minR++;
if (G->value(minG) == 0) minG++;
if (B->value(minB) == 0) minB++;
if (L->value(minL) == 0) minL++;
}
// Decrement max values
for (int i=256; i>0; i--)
{
if (R->value(maxR) == 0) maxR--;
if (G->value(maxG) == 0) maxG--;
if (B->value(maxB) == 0) maxB--;
if (L->value(maxL) == 0) maxL--;
}
// Iterate over pixels
for (int x=0; x<width; x++)
{
for (int y=0; y<height; y++)
{
QRgb pixel = image->pixel(x, y);
// Calculate new values
int r = (255/(maxR-minR))*(qRed(pixel)-minR);
int g = (255/(maxG-minG))*(qGreen(pixel)-minG);
int b = (255/(maxB-minB))*(qBlue(pixel)-minB);
int l = (255/(maxL-minL))*(qGray(pixel)-minL);
if (image->format() == QImage::Format_RGB32)
{
// Set pixel in RGB32 model
newImage->setPixel(x, y, QColor(r,g,b).rgb());
}
else
{
// Set pixel
newImage->setPixel(x, y, l);
}
}
}
return newImage; return newImage;
} }