Zad6 #6

Merged
s452117 merged 3 commits from Zadanie_06_Dawid into master 2020-04-06 23:49:59 +02:00
7 changed files with 200 additions and 7 deletions
Showing only changes of commit 772b01c8fd - Show all commits

View File

@ -1 +1,18 @@
Plik z Dokumentacja do projektu 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

View File

@ -24,15 +24,101 @@ Histogram::~Histogram()
void Histogram::generate(QImage* image) 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) );
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);
}
}
} }
/** 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!"; 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<int, int> * channel ){
int max = -1;
QHash<int, int>::const_iterator iterator = channel->begin();
while (iterator != channel->end())
{
if(iterator.value() > max && iterator.value() != 0 ){
max = iterator.value();
}
++iterator;
}
return max;
}
int Histogram::getMaxKey( QHash<int, int> * channel ){
int max = -1;
QHash<int, int>::const_iterator iterator = channel->begin();
while (iterator != channel->end())
{
if(iterator.key() > max && iterator.value() != 0){
max = iterator.key();
}
++iterator;
}
return max;
}
int Histogram::getMinKey( QHash<int, int> * channel ){
int min = 256;
QHash<int, int>::const_iterator iterator = channel->begin();
while (iterator != channel->end())
{
if(iterator.key() < min && iterator.value() != 0){
min = iterator.key();
}
++iterator;
}
return min;
}
//Return min or 256 when qhash is empty
int Histogram::getMinFromQHashHelper( QHash<int, int> * channel ){
int min = 256;
QHash<int, int>::const_iterator iterator = channel->begin();
while (iterator != channel->end())
{
if(iterator.value() < min && iterator.value() != 0){
min = iterator.value();
}
++iterator;
}
return min;
} }

View File

@ -16,10 +16,15 @@ public:
QHash<int, int>* get(Histogram::Channel); QHash<int, int>* get(Histogram::Channel);
QImage getImage(Histogram::Channel, QBrush); QImage getImage(Histogram::Channel, QBrush);
int maximumValue(Channel); int maximumValue(Channel);
int getMaxFromQHashHelper( QHash<int, int> *);
int getMinFromQHashHelper( QHash<int, int> *);
int getMinKey( QHash<int, int> *);
int getMaxKey( QHash<int, int> *);
private: private:
void generate(QImage*); // iterates all parent image pixels and set the Hashes void generate(QImage*); // iterates all parent image pixels and set the Hashes
QHash<int, int>* R; QHash<int, int>* R;
QHash<int, int>* G; QHash<int, int>* G;
QHash<int, int>* B; QHash<int, int>* B;

View File

@ -16,11 +16,73 @@ PNM* HistogramEqualization::transform()
{ {
int width = image->width(); int width = image->width();
int height = image->height(); int height = image->height();
int pixelAmounts = width* height;
PNM* newImage = new PNM(width, height, image->format()); 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; 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;
}
}

View File

@ -8,8 +8,12 @@ class HistogramEqualization : public Transformation
public: public:
HistogramEqualization(PNM*); HistogramEqualization(PNM*);
HistogramEqualization(PNM*, ImageViewer*); HistogramEqualization(PNM*, ImageViewer*);
QHash<int, int> prepareDistrubuantPerChannel(QHash <int,int> * , int);
void prepareLUTperChannel(double *, double * );
void zeros(double *, double * , double * );
virtual PNM* transform(); virtual PNM* transform();
int min(QHash<int, int> *dist);
}; };

View File

@ -14,13 +14,31 @@ 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());
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));
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; return newImage;
} }

View File

@ -6,6 +6,7 @@
class HistogramStretching : public Transformation class HistogramStretching : public Transformation
{ {
public: public:
int const MAX_VALUE = 255;
HistogramStretching(PNM*); HistogramStretching(PNM*);
HistogramStretching(PNM*, ImageViewer* iv); HistogramStretching(PNM*, ImageViewer* iv);