[TASK] Move most basic logic into lazy_image.cpp.
This commit is contained in:
parent
ef298dc322
commit
884c8ee7ae
|
@ -45,9 +45,8 @@
|
||||||
* @brief ImageViewer::ImageViewer
|
* @brief ImageViewer::ImageViewer
|
||||||
*/
|
*/
|
||||||
ImageViewer::ImageViewer() {
|
ImageViewer::ImageViewer() {
|
||||||
original_image = NULL;
|
original = NULL;
|
||||||
image = NULL;
|
working_copy = NULL;
|
||||||
histogramm = NULL;
|
|
||||||
startLogging();
|
startLogging();
|
||||||
generateMainGui();
|
generateMainGui();
|
||||||
renewLogging();
|
renewLogging();
|
||||||
|
@ -66,44 +65,27 @@ ImageViewer::ImageViewer() {
|
||||||
* @brief ImageViewer::initializeImage
|
* @brief ImageViewer::initializeImage
|
||||||
*/
|
*/
|
||||||
void ImageViewer::initializeImage() {
|
void ImageViewer::initializeImage() {
|
||||||
if(image==NULL) {
|
if(original->getImage() == NULL) {
|
||||||
std::cout << "Error! No image provided!" << std::endl;
|
std::cout << "Error! No image provided!" << std::endl;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
analyzeImage();
|
analyzeImage();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Uses simple weights to calculate intensity of a pixel.
|
|
||||||
* Using qRound() to reduce the error of the int cast.
|
|
||||||
*
|
|
||||||
* @brief ImageViewer::calcIntensity
|
|
||||||
*/
|
|
||||||
int ImageViewer::calcIntensity(int r, int g, int b) {
|
|
||||||
return (int) qRound(0.299*r + 0.587*g + 0.114*b);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* In case it is needed, convert the loaded image into grayscale.
|
* In case it is needed, convert the loaded image into grayscale.
|
||||||
* This is one of the only methods modifying original_image!
|
* This is the only method modifying the original image!
|
||||||
*
|
*
|
||||||
* @brief ImageViewer::convertToMonochrome
|
* @brief ImageViewer::convertToMonochrome
|
||||||
*/
|
*/
|
||||||
void ImageViewer::convertToMonochrome() {
|
void ImageViewer::convertToMonochrome() {
|
||||||
if(image!=NULL) {
|
if(original->getImage() != NULL) {
|
||||||
logFile << "Converting image to monochrome...";
|
logFile << "Converting image to monochrome...";
|
||||||
renewLogging();
|
renewLogging();
|
||||||
for(int x=0; x<image->width(); x++) {
|
|
||||||
for(int y=0; y<image->height(); y++) {
|
original->convertToMonochrome();
|
||||||
int r,g,b;
|
working_copy->convertToMonochrome();
|
||||||
QColor color = QColor::fromRgb(image->pixel(x, y));
|
|
||||||
color.getRgb(&r,&g,&b);
|
|
||||||
int intensity = calcIntensity(r, g, b);
|
|
||||||
color = QColor::fromRgb(intensity, intensity, intensity);
|
|
||||||
image->setPixel(x, y, color.rgb());
|
|
||||||
original_image->setPixel(x, y, color.rgb());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
updateImageDisplay();
|
updateImageDisplay();
|
||||||
logFile << "done." << std::endl;
|
logFile << "done." << std::endl;
|
||||||
renewLogging();
|
renewLogging();
|
||||||
|
@ -115,9 +97,9 @@ void ImageViewer::convertToMonochrome() {
|
||||||
* @brief ImageViewer::drawBlackLine
|
* @brief ImageViewer::drawBlackLine
|
||||||
*/
|
*/
|
||||||
void ImageViewer::drawBlackLine() {
|
void ImageViewer::drawBlackLine() {
|
||||||
if(image!=NULL) {
|
if(original->getImage() != NULL) {
|
||||||
for(int i=0;i<std::min(image->width(),image->height());i++) {
|
for(int i=0;i<std::min(working_copy->getImage()->width(),working_copy->getImage()->height());i++) {
|
||||||
image->setPixel(i,i,0);
|
working_copy->getImage()->setPixel(i,i,0);
|
||||||
}
|
}
|
||||||
updateImageDisplay();
|
updateImageDisplay();
|
||||||
logFile << "Black line drawn." << std::endl;
|
logFile << "Black line drawn." << std::endl;
|
||||||
|
@ -130,13 +112,13 @@ void ImageViewer::drawBlackLine() {
|
||||||
* @brief ImageViewer::drawDiagonalCross
|
* @brief ImageViewer::drawDiagonalCross
|
||||||
*/
|
*/
|
||||||
void ImageViewer::drawDiagonalCross() {
|
void ImageViewer::drawDiagonalCross() {
|
||||||
if(image!=NULL) {
|
if(original->getImage() != NULL) {
|
||||||
int color = QColor::fromHsl(120,255,125).rgb();
|
int color = QColor::fromHsl(120,255,125).rgb();
|
||||||
int width = image->width();
|
int width = working_copy->getImage()->width();
|
||||||
int height = image->height();
|
int height = working_copy->getImage()->height();
|
||||||
for(int y=0; y<image->height(); y++) {
|
for(int y=0; y<working_copy->getImage()->height(); y++) {
|
||||||
image->setPixel((1.0*y/height)*width,y,color);
|
working_copy->getImage()->setPixel((1.0*y/height)*width,y,color);
|
||||||
image->setPixel((1.0-(1.0*y/height))*width,y,color);
|
working_copy->getImage()->setPixel((1.0-(1.0*y/height))*width,y,color);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
updateImageDisplay();
|
updateImageDisplay();
|
||||||
|
@ -160,17 +142,17 @@ void ImageViewer::drawRainbowCross() {
|
||||||
* @param initialHue
|
* @param initialHue
|
||||||
*/
|
*/
|
||||||
void ImageViewer::drawRainbowCross(int initialHue=0) {
|
void ImageViewer::drawRainbowCross(int initialHue=0) {
|
||||||
if(image!=NULL) {
|
if(original->getImage() != NULL) {
|
||||||
int h = initialHue;
|
int h = initialHue;
|
||||||
QColor myColor = QColor::fromHsl(h, 255, 125);
|
QColor myColor = QColor::fromHsl(h, 255, 125);
|
||||||
int image_width = image->width()-1;
|
int image_width = working_copy->getImage()->width()-1;
|
||||||
int range = line_slider->value();
|
int range = line_slider->value();
|
||||||
if(range > image->width()-2) range = image->width()-2;
|
if(range > working_copy->getImage()->width()-2) range = working_copy->getImage()->width()-2;
|
||||||
for(int i=0;i<std::min(image->width(),image->height());i++) {
|
for(int i=0;i<std::min(working_copy->getImage()->width(),working_copy->getImage()->height());i++) {
|
||||||
int color = myColor.rgb();
|
int color = myColor.rgb();
|
||||||
for(int r=0; r<range; r++) {
|
for(int r=0; r<range; r++) {
|
||||||
image->setPixel(i+r,i,color);
|
working_copy->getImage()->setPixel(i+r,i,color);
|
||||||
image->setPixel((image_width-i)-r,i,color);
|
working_copy->getImage()->setPixel((image_width-i)-r,i,color);
|
||||||
}
|
}
|
||||||
h++;
|
h++;
|
||||||
if(h > 359) h = 0;
|
if(h > 359) h = 0;
|
||||||
|
@ -201,107 +183,22 @@ void ImageViewer::acidTrippin() {
|
||||||
* Analyze the image, get average luminance
|
* Analyze the image, get average luminance
|
||||||
* Also fill grayscale_absolute_histogramm
|
* Also fill grayscale_absolute_histogramm
|
||||||
*
|
*
|
||||||
* TODO: Decouple this from the drawing of the histogramm
|
|
||||||
* (READ: Fuck, reanalyzing my image fucks up tools that work on histogramm data!)
|
|
||||||
*
|
|
||||||
* @brief ImageViewer::analyzeImage
|
* @brief ImageViewer::analyzeImage
|
||||||
*/
|
*/
|
||||||
void ImageViewer::analyzeImage() {
|
void ImageViewer::analyzeImage() {
|
||||||
if(image!=NULL) {
|
if(original->getImage() != NULL) {
|
||||||
//Zero existing histogramm data first
|
|
||||||
for(int i=0; i<256; i++) {
|
|
||||||
grayscale_absolute_histogramm[i] = 0;
|
|
||||||
grayscale_relative_histogramm[i] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
logFile << "Analyzing image ...";
|
logFile << "Analyzing image ...";
|
||||||
renewLogging();
|
renewLogging();
|
||||||
for(int x=0; x<image->width(); x++) {
|
original->updateStatistics();
|
||||||
for(int y=0; y<image->height(); y++) {
|
working_copy->updateStatistics();
|
||||||
int r,g,b;
|
|
||||||
QColor color = QColor::fromRgb(image->pixel(x, y));
|
|
||||||
color.getRgb(&r,&g,&b);
|
|
||||||
int intensity = calcIntensity(r, g, b);
|
|
||||||
grayscale_absolute_histogramm[intensity] += 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int pixels = image->width()*image->height();
|
|
||||||
for(int i=0; i<256; i++) {
|
|
||||||
grayscale_relative_histogramm[i] = (((double) grayscale_absolute_histogramm[i])/((double) pixels));
|
|
||||||
}
|
|
||||||
|
|
||||||
logFile << "done" << std::endl;
|
logFile << "done" << std::endl;
|
||||||
renewLogging();
|
renewLogging();
|
||||||
|
QString result = QString("Intensity: Average: %1, Variance: %2").arg(working_copy->getIntensityAverage()).arg(working_copy->getIntensityVariance());
|
||||||
QString result = QString("Intensity: Average: %1, Variance: %2").arg(getAverageIntensity()).arg(getIntensityVariance());
|
|
||||||
stats->setText(result);
|
stats->setText(result);
|
||||||
|
histogramm_label->setPixmap(QPixmap::fromImage(*(working_copy->getHistogrammImage())));
|
||||||
updateHistogramm();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Use histogramm to retrieve the average intensity.
|
|
||||||
* @brief ImageViewer::getAverageIntensity
|
|
||||||
*/
|
|
||||||
int ImageViewer::getAverageIntensity() {
|
|
||||||
double sumIntensity = 0;
|
|
||||||
for(int i=0; i<256;i++) {
|
|
||||||
sumIntensity += (i*grayscale_relative_histogramm[i]);
|
|
||||||
}
|
|
||||||
return (int) qRound(sumIntensity);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieve the intensity variance from the image.
|
|
||||||
* @brief ImageViewer::getVarianceIntensity
|
|
||||||
*/
|
|
||||||
int ImageViewer::getIntensityVariance() {
|
|
||||||
int average_intensity = getAverageIntensity();
|
|
||||||
int sumDifference = 0;
|
|
||||||
for(int x=0; x<image->width(); x++) {
|
|
||||||
for(int y=0; y<image->height(); y++) {
|
|
||||||
QColor color = QColor::fromRgb(image->pixel(x, y));
|
|
||||||
int r,g,b;
|
|
||||||
color.getRgb(&r,&g,&b);
|
|
||||||
int intensity = calcIntensity(r, g, b);
|
|
||||||
int diff = std::abs(intensity - average_intensity);
|
|
||||||
sumDifference += diff;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return (int) (sumDifference/(image->width()*image->height()));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Builds up the image for the histogramm.
|
|
||||||
* @brief ImageViewer::updateHistogramm
|
|
||||||
*/
|
|
||||||
void ImageViewer::updateHistogramm() {
|
|
||||||
if(histogramm != NULL) {
|
|
||||||
delete histogramm;
|
|
||||||
histogramm = NULL;
|
|
||||||
}
|
|
||||||
//Find biggest value in histogramm data
|
|
||||||
double max = 0;
|
|
||||||
for(int i=0; i<256; i++) {
|
|
||||||
if(grayscale_relative_histogramm[i] > max) max = grayscale_relative_histogramm[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
histogramm = new QImage(256, 100, QImage::Format_RGB32);
|
|
||||||
histogramm->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*grayscale_relative_histogramm[x])/max);
|
|
||||||
for(int y=0; y<k_max; y++) {
|
|
||||||
histogramm->setPixel(x, (100-y)-1, black);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
logFile << "Histogramm done." << std::endl;
|
|
||||||
renewLogging();
|
|
||||||
histogramm_label->setPixmap(QPixmap::fromImage(*histogramm));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fired by the brightness_slider, this one adjusts the brightness on image.
|
* Fired by the brightness_slider, this one adjusts the brightness on image.
|
||||||
* @brief ImageViewer::adjustBrightness
|
* @brief ImageViewer::adjustBrightness
|
||||||
|
@ -310,15 +207,15 @@ void ImageViewer::adjustBrightness(int b) {
|
||||||
int h, s, old_l;
|
int h, s, old_l;
|
||||||
int new_l = 0;
|
int new_l = 0;
|
||||||
int delta = b - 255;
|
int delta = b - 255;
|
||||||
for(int x=0; x<image->width(); x++) {
|
for(int x=0; x<working_copy->getImage()->width(); x++) {
|
||||||
for(int y=0; y<image->height(); y++) {
|
for(int y=0; y<working_copy->getImage()->height(); y++) {
|
||||||
QColor color = QColor::fromRgb(original_image->pixel(x, y));
|
QColor color = QColor::fromRgb(original->getImage()->pixel(x, y));
|
||||||
color.getHsl(&h, &s, &old_l);
|
color.getHsl(&h, &s, &old_l);
|
||||||
new_l = old_l + delta;
|
new_l = old_l + delta;
|
||||||
if(new_l > 255) new_l = 255;
|
if(new_l > 255) new_l = 255;
|
||||||
if(new_l < 0) new_l = 0;
|
if(new_l < 0) new_l = 0;
|
||||||
color.setHsl(h, s, new_l);
|
color.setHsl(h, s, new_l);
|
||||||
image->setPixel(x, y, color.rgb());
|
working_copy->getImage()->setPixel(x, y, color.rgb());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
updateImageDisplay();
|
updateImageDisplay();
|
||||||
|
@ -334,16 +231,16 @@ void ImageViewer::adjustContrast(int c) {
|
||||||
int h, s, old_l;
|
int h, s, old_l;
|
||||||
int new_l = 0;
|
int new_l = 0;
|
||||||
double alpha = c / 255.0;
|
double alpha = c / 255.0;
|
||||||
int average_intensity = getAverageIntensity();
|
int average_intensity = original->getIntensityAverage();
|
||||||
for(int x=0; x<image->width(); x++) {
|
for(int x=0; x<working_copy->getImage()->width(); x++) {
|
||||||
for(int y=0; y<image->height(); y++) {
|
for(int y=0; y<working_copy->getImage()->height(); y++) {
|
||||||
QColor color = QColor::fromRgb(original_image->pixel(x, y));
|
QColor color = QColor::fromRgb(original->getImage()->pixel(x, y));
|
||||||
color.getHsl(&h, &s, &old_l);
|
color.getHsl(&h, &s, &old_l);
|
||||||
new_l = average_intensity + ((int) round((old_l - average_intensity) * alpha));
|
new_l = average_intensity + ((int) round((old_l - average_intensity) * alpha));
|
||||||
if(new_l > 255) new_l = 255;
|
if(new_l > 255) new_l = 255;
|
||||||
if(new_l < 0) new_l = 0;
|
if(new_l < 0) new_l = 0;
|
||||||
color.setHsl(h, s, new_l);
|
color.setHsl(h, s, new_l);
|
||||||
image->setPixel(x, y, color.rgb());
|
working_copy->getImage()->setPixel(x, y, color.rgb());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
updateImageDisplay();
|
updateImageDisplay();
|
||||||
|
@ -366,6 +263,7 @@ void ImageViewer::robustAutomaticContrastAdaption(void) {
|
||||||
int upper_border = -1;
|
int upper_border = -1;
|
||||||
double limit = percentile / 100.0;
|
double limit = percentile / 100.0;
|
||||||
double cursor = 0.0;
|
double cursor = 0.0;
|
||||||
|
double* grayscale_relative_histogramm = original->getRelativeIntensityHistogramm();
|
||||||
for(int i=0; i<256; i++) {
|
for(int i=0; i<256; i++) {
|
||||||
cursor += grayscale_relative_histogramm[i];
|
cursor += grayscale_relative_histogramm[i];
|
||||||
if(cursor >= limit && lower_border == -1) {
|
if(cursor >= limit && lower_border == -1) {
|
||||||
|
@ -383,9 +281,9 @@ void ImageViewer::robustAutomaticContrastAdaption(void) {
|
||||||
renewLogging();
|
renewLogging();
|
||||||
|
|
||||||
int h, s, l;
|
int h, s, l;
|
||||||
for(int x=0; x<image->width(); x++) {
|
for(int x=0; x<working_copy->getImage()->width(); x++) {
|
||||||
for(int y=0; y<image->height(); y++) {
|
for(int y=0; y<working_copy->getImage()->height(); y++) {
|
||||||
QColor color = QColor::fromRgb(original_image->pixel(x, y));
|
QColor color = QColor::fromRgb(original->getImage()->pixel(x, y));
|
||||||
color.getHsl(&h, &s, &l);
|
color.getHsl(&h, &s, &l);
|
||||||
|
|
||||||
if(l < lower_border) {
|
if(l < lower_border) {
|
||||||
|
@ -397,7 +295,7 @@ void ImageViewer::robustAutomaticContrastAdaption(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
color.setHsl(h, s, l);
|
color.setHsl(h, s, l);
|
||||||
image->setPixel(x, y, color.rgb());
|
working_copy->getImage()->setPixel(x, y, color.rgb());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
updateImageDisplay();
|
updateImageDisplay();
|
||||||
|
@ -512,7 +410,6 @@ void ImageViewer::generateControlPanels() {
|
||||||
task_tab_widget3 = new QWidget();
|
task_tab_widget3 = new QWidget();
|
||||||
task_tab3 = new QVBoxLayout();
|
task_tab3 = new QVBoxLayout();
|
||||||
task_tab_widget3->setLayout(task_tab3);
|
task_tab_widget3->setLayout(task_tab3);
|
||||||
|
|
||||||
|
|
||||||
tabWidget->addTab(task_tab_widget3, "Task #3");
|
tabWidget->addTab(task_tab_widget3, "Task #3");
|
||||||
|
|
||||||
|
@ -551,7 +448,7 @@ void ImageViewer::renewLogging()
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImageViewer::updateImageDisplay() {
|
void ImageViewer::updateImageDisplay() {
|
||||||
imageLabel->setPixmap(QPixmap::fromImage(*image));
|
imageLabel->setPixmap(QPixmap::fromImage(*(working_copy->getImage())));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -611,19 +508,19 @@ void ImageViewer::print() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImageViewer::open() {
|
void ImageViewer::open() {
|
||||||
if(image != NULL) {
|
if(working_copy != NULL) {
|
||||||
delete image;
|
delete working_copy;
|
||||||
image = NULL;
|
working_copy = NULL;
|
||||||
}
|
}
|
||||||
if(original_image!=NULL) {
|
if(original != NULL) {
|
||||||
delete original_image;
|
delete original;
|
||||||
original_image = NULL;
|
original = NULL;
|
||||||
}
|
}
|
||||||
QString fileName = QFileDialog::getOpenFileName(this, tr("Open File"), QDir::currentPath());
|
QString fileName = QFileDialog::getOpenFileName(this, tr("Open File"), QDir::currentPath());
|
||||||
if(!fileName.isEmpty()) {
|
if(!fileName.isEmpty()) {
|
||||||
image = new QImage(fileName);
|
working_copy = new LazyImage(new QImage(fileName));
|
||||||
original_image = new QImage(fileName);
|
original = new LazyImage(new QImage(fileName));
|
||||||
if(image->isNull()) {
|
if(working_copy->getImage()->isNull()) {
|
||||||
QMessageBox::information(this, tr("Image Viewer"), tr("Cannot load %1.").arg(fileName));
|
QMessageBox::information(this, tr("Image Viewer"), tr("Cannot load %1.").arg(fileName));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,6 +54,8 @@
|
||||||
#include "fstream"
|
#include "fstream"
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
|
#include "lazy_image.cpp"
|
||||||
|
|
||||||
class QAction;
|
class QAction;
|
||||||
class QLabel;
|
class QLabel;
|
||||||
class QMenu;
|
class QMenu;
|
||||||
|
@ -101,10 +103,8 @@ class ImageViewer : public QMainWindow {
|
||||||
QVBoxLayout* task_tab3;
|
QVBoxLayout* task_tab3;
|
||||||
|
|
||||||
// "My" space for storing data/results
|
// "My" space for storing data/results
|
||||||
int grayscale_absolute_histogramm[256];
|
LazyImage* original;
|
||||||
double grayscale_relative_histogramm[256];
|
LazyImage* working_copy;
|
||||||
QImage* histogramm;
|
|
||||||
QImage* original_image;
|
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
// Custom slots
|
// Custom slots
|
||||||
|
@ -113,7 +113,6 @@ class ImageViewer : public QMainWindow {
|
||||||
void drawDiagonalCross();
|
void drawDiagonalCross();
|
||||||
void acidTrippin();
|
void acidTrippin();
|
||||||
void analyzeImage();
|
void analyzeImage();
|
||||||
void updateHistogramm();
|
|
||||||
void adjustBrightness(int b);
|
void adjustBrightness(int b);
|
||||||
void adjustContrast(int c);
|
void adjustContrast(int c);
|
||||||
void convertToMonochrome();
|
void convertToMonochrome();
|
||||||
|
@ -160,7 +159,6 @@ class ImageViewer : public QMainWindow {
|
||||||
QLabel* imageLabel;
|
QLabel* imageLabel;
|
||||||
QScrollArea* scrollArea;
|
QScrollArea* scrollArea;
|
||||||
double scaleFactor;
|
double scaleFactor;
|
||||||
QImage* image;
|
|
||||||
|
|
||||||
std::fstream logFile;
|
std::fstream logFile;
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,166 @@
|
||||||
|
#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_image;
|
||||||
|
double histogramm_relative_intensity[256];
|
||||||
|
int histogramm_absolute_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;
|
||||||
|
}
|
||||||
|
// 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
|
||||||
|
int pixels = this->img->width()*this->img->height();
|
||||||
|
for(int i=0; i<256; i++) {
|
||||||
|
histogramm_relative_intensity[i] = (((double) histogramm_absolute_intensity[i])/((double) pixels));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
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 generateHistogrammImage(void) {
|
||||||
|
if(this->histogramm_image != NULL) {
|
||||||
|
delete this->histogramm_image;
|
||||||
|
this->histogramm_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_image = new QImage(256, 100, QImage::Format_RGB32);
|
||||||
|
this->histogramm_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_image->setPixel(x, (100-y)-1, black);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
LazyImage(QImage* img) {
|
||||||
|
this->histogramm_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->generateHistogrammImage();
|
||||||
|
};
|
||||||
|
|
||||||
|
QImage* getHistogrammImage(void) {
|
||||||
|
return this->histogramm_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;
|
||||||
|
};
|
||||||
|
|
||||||
|
double* getRelativeIntensityHistogramm(void) {
|
||||||
|
return this->histogramm_relative_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
|
Loading…
Reference in New Issue