Zadanie 3
This commit is contained in:
parent
9278aa08db
commit
5b18f63379
@ -1,3 +1,5 @@
|
||||
# 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''
|
||||
|
||||
|
136
03/do_sprawdzenia/histogram.cpp
Normal file
136
03/do_sprawdzenia/histogram.cpp
Normal 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;
|
||||
}
|
108
03/do_sprawdzenia/histogram_equalization.cpp
Normal file
108
03/do_sprawdzenia/histogram_equalization.cpp
Normal 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;
|
||||
}
|
88
03/do_sprawdzenia/histogram_stretching.cpp
Normal file
88
03/do_sprawdzenia/histogram_stretching.cpp
Normal 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;
|
||||
}
|
||||
|
||||
|
@ -24,15 +24,67 @@ Histogram::~Histogram()
|
||||
|
||||
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 */
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
|
@ -14,13 +14,95 @@ 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();
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -19,8 +19,69 @@ PNM* HistogramStretching::transform()
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user