209 lines
6.1 KiB
C++
209 lines
6.1 KiB
C++
#ifndef LAZY_IMAGE_C
|
|
#define LAZY_IMAGE_C
|
|
|
|
#include <QtGlobal>
|
|
#include <QMainWindow>
|
|
#include <QColor>
|
|
|
|
#include <iostream>
|
|
|
|
#include <math.h>
|
|
|
|
class LazyImage {
|
|
|
|
private:
|
|
QImage* img; //Not managed by us, just used.
|
|
QImage* histogramm_normal_image;
|
|
QImage* histogramm_cumulative_image;
|
|
double histogramm_relative_intensity[256];
|
|
double histogramm_relative_cumulative_intensity[256];
|
|
int histogramm_absolute_intensity[256];
|
|
int histogramm_absolute_cumulative_intensity[256];
|
|
int intensity_average;
|
|
int intensity_variance;
|
|
|
|
void gatherHistogrammData(void) {
|
|
// Zero existing histogramm data first
|
|
for(int i=0; i<256; i++) {
|
|
histogramm_relative_intensity[i] = 0;
|
|
histogramm_absolute_intensity[i] = 0;
|
|
histogramm_absolute_cumulative_intensity[i] = 0;
|
|
}
|
|
// Count all the brightness values
|
|
for(int x=0; x<this->img->width(); x++) {
|
|
for(int y=0; y<this->img->height(); y++) {
|
|
int r,g,b;
|
|
QColor color = QColor::fromRgb(this->img->pixel(x, y));
|
|
color.getRgb(&r,&g,&b);
|
|
int intensity = this->calcIntensity(r, g, b);
|
|
histogramm_absolute_intensity[intensity] += 1;
|
|
}
|
|
}
|
|
|
|
// Calculate relative histogramm and absolute cumulative histogramm
|
|
int pixels = this->img->width()*this->img->height();
|
|
int sum = 0;
|
|
double relative_sum = 0.0;
|
|
for(int i=0; i<256; i++) {
|
|
histogramm_relative_intensity[i] = (((double) histogramm_absolute_intensity[i])/((double) pixels));
|
|
sum += histogramm_absolute_intensity[i];
|
|
relative_sum += histogramm_relative_intensity[i];
|
|
histogramm_absolute_cumulative_intensity[i] = sum;
|
|
histogramm_relative_cumulative_intensity[i] = relative_sum;
|
|
}
|
|
};
|
|
|
|
void calcIntensityAverage(void) {
|
|
double sum = 0;
|
|
for(int i=0; i<256;i++) {
|
|
sum += (i*histogramm_relative_intensity[i]);
|
|
}
|
|
this->intensity_average = (int) qRound(sum);
|
|
};
|
|
|
|
void calcIntensityVariance(void) {
|
|
int intensity_average = this->intensity_average;
|
|
int sum_difference = 0;
|
|
for(int x=0; x<this->img->width(); x++) {
|
|
for(int y=0; y<this->img->height(); y++) {
|
|
QColor color = QColor::fromRgb(this->img->pixel(x, y));
|
|
int r,g,b;
|
|
color.getRgb(&r,&g,&b);
|
|
sum_difference += std::abs(this->calcIntensity(r, g, b) - intensity_average);;
|
|
}
|
|
}
|
|
this->intensity_variance = (int) qRound(sum_difference/(this->img->width()*this->img->height()));
|
|
};
|
|
|
|
void generateNormalHistogrammImage(void) {
|
|
if(this->histogramm_normal_image != NULL) {
|
|
delete this->histogramm_normal_image;
|
|
this->histogramm_normal_image = NULL;
|
|
}
|
|
//Find biggest value in histogramm data
|
|
double max = 0;
|
|
for(int i=0; i<256; i++) {
|
|
if(histogramm_relative_intensity[i] > max) max = histogramm_relative_intensity[i];
|
|
}
|
|
this->histogramm_normal_image = new QImage(256, 100, QImage::Format_RGB32);
|
|
this->histogramm_normal_image->fill(QColor::fromRgb(200,200,200));
|
|
int black = QColor::fromRgb(0,0,0).rgb();
|
|
for(int x=0; x<256; x++) {
|
|
int k_max = (int) qRound((100*histogramm_relative_intensity[x])/max);
|
|
for(int y=0; y<k_max; y++) {
|
|
this->histogramm_normal_image->setPixel(x, (100-y)-1, black);
|
|
}
|
|
}
|
|
};
|
|
|
|
void generateCumulativeHistogrammImage(void) {
|
|
if(this->histogramm_cumulative_image != NULL) {
|
|
delete this->histogramm_cumulative_image;
|
|
this->histogramm_cumulative_image = NULL;
|
|
}
|
|
this->histogramm_cumulative_image = new QImage(256, 100, QImage::Format_RGB32);
|
|
this->histogramm_cumulative_image->fill(QColor::fromRgb(200,200,200));
|
|
int black = QColor::fromRgb(0,0,0).rgb();
|
|
double total = 0.0;
|
|
for(int x=0; x<256; x++) {
|
|
total += histogramm_relative_intensity[x];
|
|
int k_max = (int) qRound(100*total);
|
|
for(int y=0; y<k_max; y++) {
|
|
this->histogramm_cumulative_image->setPixel(x, (100-y)-1, black);
|
|
}
|
|
}
|
|
};
|
|
|
|
|
|
public:
|
|
LazyImage(QImage* img) {
|
|
this->histogramm_normal_image = NULL;
|
|
this->histogramm_cumulative_image = NULL;
|
|
this->setImage(img);
|
|
};
|
|
|
|
~LazyImage() {
|
|
if(img != NULL) {
|
|
img = NULL;
|
|
}
|
|
};
|
|
|
|
void setImage(QImage* img) {
|
|
if(img != NULL) {
|
|
this->img = img;
|
|
this->updateStatistics();
|
|
}
|
|
};
|
|
|
|
QImage* getImage(void) {
|
|
return this->img;
|
|
};
|
|
|
|
void updateStatistics(void) {
|
|
this->gatherHistogrammData();
|
|
this->calcIntensityAverage();
|
|
this->calcIntensityVariance();
|
|
this->generateNormalHistogrammImage();
|
|
this->generateCumulativeHistogrammImage();
|
|
};
|
|
|
|
QImage* getHistogrammNormalImage(void) {
|
|
return this->histogramm_normal_image;
|
|
};
|
|
|
|
QImage* getHistogrammCumulativeImage(void) {
|
|
return this->histogramm_cumulative_image;
|
|
};
|
|
|
|
/**
|
|
* Uses simple weights to calculate intensity of a pixel.
|
|
* Using qRound() to reduce the error of the int cast.
|
|
*
|
|
* @brief LazyImage::calcIntensity
|
|
*/
|
|
int calcIntensity(int r, int g, int b) {
|
|
return (int) qRound(0.299*r + 0.587*g + 0.114*b);
|
|
};
|
|
|
|
int getIntensityAverage(void) {
|
|
return this->intensity_average;
|
|
}
|
|
|
|
int getIntensityVariance(void) {
|
|
return this->intensity_variance;
|
|
};
|
|
|
|
int* getAbsoluteIntensityHistogramm(void) {
|
|
return this->histogramm_absolute_intensity;
|
|
};
|
|
|
|
int* getAbsoluteCumulativeIntensityHistogramm(void) {
|
|
return this->histogramm_absolute_cumulative_intensity;
|
|
};
|
|
|
|
double* getRelativeIntensityHistogramm(void) {
|
|
return this->histogramm_relative_intensity;
|
|
};
|
|
|
|
double* getRelativeCumulativeIntensityHistogramm(void) {
|
|
return this->histogramm_relative_cumulative_intensity;
|
|
};
|
|
|
|
void convertToMonochrome(void) {
|
|
for(int x=0; x<this->img->width(); x++) {
|
|
for(int y=0; y<this->img->height(); y++) {
|
|
int r,g,b;
|
|
QColor color = QColor::fromRgb(this->img->pixel(x, y));
|
|
color.getRgb(&r,&g,&b);
|
|
int intensity = this->calcIntensity(r, g, b);
|
|
color = QColor::fromRgb(intensity, intensity, intensity);
|
|
this->img->setPixel(x, y, color.rgb());
|
|
}
|
|
}
|
|
};
|
|
|
|
};
|
|
|
|
|
|
#endif
|