From 57923519df599d59aae9c8692e8941b3e968009a Mon Sep 17 00:00:00 2001 From: Jan Philipp Timme Date: Fri, 4 Dec 2015 12:57:31 +0100 Subject: [PATCH] [TASK] Begin implementing filters with overflow modes. --- imageviewer-qt4.cpp | 64 ++++++++++++++++++++++++++++++++++++++++++++- imageviewer-qt4.h | 1 + lazy_image.cpp | 52 ++++++++++++++++++++++++++++++++++++ 3 files changed, 116 insertions(+), 1 deletion(-) diff --git a/imageviewer-qt4.cpp b/imageviewer-qt4.cpp index 347f6eb..bd2a98e 100644 --- a/imageviewer-qt4.cpp +++ b/imageviewer-qt4.cpp @@ -537,7 +537,69 @@ void ImageViewer::applyBasicFilter() { updateImageDisplay(); } - +/** + * Basic filter PLUS different overflow modes + * + * @brief ImageViewer::applyBasicFilterWithOverflowHandling + */ +void ImageViewer::applyBasicFilterWithOverflowHandling() { + // TODO: Get overflow mode here + LazyImage::overflowMode overflowMode = LazyImage::CONSTANT; + logFile << "Applying basic filter - overflow mode: " << overflowMode << std::endl; + renewLogging(); + + int* data = filter_gui->getData(); + int filter_size = filter_gui->getSize(); + + // sum up the filter weights + int filter_sum = 0; + for(int i=0; i " << current_data << " "; + } + logFile << std::endl; + } + logFile << "Beginning calculation ... " << std::endl; + renewLogging(); + + int h, s, l; + // for each pixel + for(int x=0; xgetImage()->width(); x++) { + for(int y=0; ygetImage()->height(); y++) { + int intensity_sum = 0; + // sum up weighted intensity for each matrix entry + for(int fx=0; fxgetPixel(x+dx, y+dy, overflowMode)); + color.getHsl(&h, &s, &l); + //std::cout << "[" << fx << "," << fy <<"] " << l << " * " << data[fx*filter_size + fy] << " = "; + intensity_sum += (l * data[fx*filter_size + fy]); + //std::cout << intensity_sum << std::endl; + } + } + QColor color = QColor::fromRgb(original->getImage()->pixel(x, y)); + color.getHsl(&h, &s, &l); + //std::cout << "old lightness: " << l << ", filter_sum: " << filter_sum << ", intensity_sum:" << intensity_sum; + // divide by sum of weights + l = qRound((intensity_sum*1.0) / filter_sum); + //optional clamping for exotic stuff like negative values + if(l > 255) l = 255; + if(l < 0) l = 0; + //std::cout << " --> new l: " << l << std::endl; + color.setHsl(h, s, l); + // and set it. + working_copy->getImage()->setPixel(x, y, color.rgb()); + } + } + + logFile << "done." << std::endl; + renewLogging(); + updateImageDisplay(); +} /**************************************************************************************** * * GUI elements related to the tasks are set up here. diff --git a/imageviewer-qt4.h b/imageviewer-qt4.h index 30d13a6..7b87d93 100644 --- a/imageviewer-qt4.h +++ b/imageviewer-qt4.h @@ -158,6 +158,7 @@ class ImageViewer : public QMainWindow { void succeedingHistogrammAdaption(); void changeFilterSize(int s); void applyBasicFilter(); + void applyBasicFilterWithOverflowHandling(); void open(); void openReference(); diff --git a/lazy_image.cpp b/lazy_image.cpp index 8e9a195..3ab5d72 100644 --- a/lazy_image.cpp +++ b/lazy_image.cpp @@ -116,6 +116,8 @@ class LazyImage { public: + enum overflowMode {ZERO_PADDING, CONSTANT, MIRRORED, CONTINUOUS}; + LazyImage(QImage* img) { this->histogramm_normal_image = NULL; this->histogramm_cumulative_image = NULL; @@ -201,6 +203,56 @@ class LazyImage { } } }; + + /** + * Takes coordinates and a mode about how to handle overflows. + * Not all modes are 100% bullet proof - it is still possible to + * get unexpected results out of this for very big overflows. + * + * @brief LazyImage::getPixel + */ + QColor getPixel(int x, int y, overflowMode mode) { + int width = this->img->width(); + int height = this->img->height(); + QRgb result = NULL; + switch(mode) { + case ZERO_PADDING: // Return black for all out of bound requests + if(x < 0 || x >= width || y < 0 || y >= height) { + result = QRgb(qRgb(0, 0, 0); + } + break; + case CONSTANT: // Simply clamp to the border it is stuck on + if(x < 0) x = 0; + else if(x >= width) x = width - 1; + if(y < 0) y = 0; + else if(y >= height) y = height - 1; + break; + case MIRRORED: // Mirror on overflowed axis + if(x < 0) x *= -1; + else if(x >= width) { + int delta = x - (width-1); + x = (width-1) - delta; + } + if(y < 0) y *= -1; + else if(y > (height-1)) { + int delta = y - (height-1); + y = (height-1) - delta; + } + break; + case CONTINUOUS: // simply start over at the other side again + x = x % width; + y = y % height; + break; + default: + std::cout << "HELP, SOMETHING WENT WRONG! I DON'T KNOW THIS MODE!" << std::endl; + break; // BOOM! + } + if(result == NULL) { + return this->img->pixel(x, y); + } else { + return result; + } + }; };