diff --git a/06/do_sprawdzenia/cpp/image1.png b/06/do_sprawdzenia/cpp/image1.png new file mode 100644 index 0000000..0284942 Binary files /dev/null and b/06/do_sprawdzenia/cpp/image1.png differ diff --git a/06/do_sprawdzenia/cpp/image2.png b/06/do_sprawdzenia/cpp/image2.png new file mode 100644 index 0000000..6c22036 Binary files /dev/null and b/06/do_sprawdzenia/cpp/image2.png differ diff --git a/06/do_sprawdzenia/cpp/noise_bilateral.cpp b/06/do_sprawdzenia/cpp/noise_bilateral.cpp new file mode 100644 index 0000000..167f112 --- /dev/null +++ b/06/do_sprawdzenia/cpp/noise_bilateral.cpp @@ -0,0 +1,98 @@ +#include "noise_bilateral.h" + +NoiseBilateral::NoiseBilateral(PNM* img) : + Convolution(img) +{ +} + +NoiseBilateral::NoiseBilateral(PNM* img, ImageViewer* iv) : + Convolution(img, iv) +{ +} + +PNM* NoiseBilateral::transform() +{ + int width = image->width(); + int height = image->height(); + + PNM* newImage = new PNM(width, height, image->format()); + + sigma_d = getParameter("sigma_d").toInt(); + sigma_r = getParameter("sigma_r").toInt(); + + radius = sigma_d; + + for (int x = 0; x < width; x++) + { + for (int y = 0; y < height; y++) + { + if (image->format() == QImage::Format_Indexed8) + { + // Get calculated value for LChannel and set as new pixel + newImage->setPixel(x, y, calcVal(x, y, LChannel)); + } + else + { + // Get calculated values for RGB channels + int r_calc = calcVal(x, y, RChannel); + int g_calc = calcVal(x, y, GChannel); + int b_calc = calcVal(x, y, BChannel); + + + QColor color = QColor(r_calc, g_calc, b_calc); + newImage->setPixel(x, y, color.rgb()); + } + } + } + + return newImage; +} + +int NoiseBilateral::calcVal(int x, int y, Channel channel) +{ + // Set variables + float top = 0; + float bottom = 0; + + // Get window + math::matrix window = getWindow(x,y, radius, channel, RepeatEdge); + + // Get size of matrix + int window_row_number = window.rowno(); + int window_col_number = window.colno(); + + // Get central value + float central = window[window_row_number / 2][window_col_number / 2]; + + for (int i = 0; i < window_col_number; i++) + { + for (int j = 0; j < window_row_number; j++) + { + // Get Point in (i, j) + QPoint p1(i,j); + + // Get second Point + QPoint p2(window_row_number / 2, window_col_number / 2); + + // Calculate top value + top = top + window[i][j] * colorCloseness(window[i][j], central) * spatialCloseness(p1, p2); + + // Calculate bottom value + bottom = bottom + colorCloseness(window[i][j], central) * spatialCloseness(p1, p2); + } + } + + return top / bottom; +} + +float NoiseBilateral::colorCloseness(int val1, int val2) +{ + float result = exp(-(pow(val1 - val2, 2) / (2 * sigma_r * sigma_r))); + return result; +} + +float NoiseBilateral::spatialCloseness(QPoint point1, QPoint point2) +{ + float result = exp(-(pow(point1.x() - point2.x(), 2) + pow(point1.y() - point2.y(), 2) / (2 * sigma_d * sigma_d))); + return result; +} diff --git a/06/do_sprawdzenia/cpp/noise_median.cpp b/06/do_sprawdzenia/cpp/noise_median.cpp new file mode 100644 index 0000000..35316b3 --- /dev/null +++ b/06/do_sprawdzenia/cpp/noise_median.cpp @@ -0,0 +1,112 @@ +#include "noise_median.h" + +NoiseMedian::NoiseMedian(PNM* img) : + Convolution(img) +{ +} + +NoiseMedian::NoiseMedian(PNM* img, ImageViewer* iv) : + Convolution(img, iv) +{ +} + +PNM* NoiseMedian::transform() +{ + int width = image->width(); + int height = image->height(); + + PNM* newImage = new PNM(width, height, image->format()); + + + for (int i = 0; i < width; i++) + { + for (int j = 0; j < height; j++) + { + if (image->format() == QImage::Format_Indexed8) + { + // Get median value for LChannel and set as new pixel + newImage->setPixel(i, j, getMedian(i, j, LChannel)); + } + else + { + // Get median values for RGB channels + int r_med = getMedian(i, j, RChannel); + int g_med = getMedian(i, j, GChannel); + int b_med = getMedian(i, j, BChannel); + + // Create new color + QColor color = QColor(r_med, g_med, b_med); + + // Set new pixel with rgb color + newImage->setPixel(i, j, color.rgb()); + } + } + } + + return newImage; +} + +int NoiseMedian::getMedian(int x, int y, Channel channel) +{ + int radius = getParameter("radius").toInt(); + int window_size = 2 * radius + 1; + + math::matrix window = getWindow(x, y, window_size, channel, RepeatEdge); + std::vector result; //list does not provide a subscript operator + + for(std::size_t i=0; i < window.rowno(); i++){ + for(std::size_t j=0; j < window.colno(); j++){ + result.push_back(window[i][j]); + } + } + std::sort(result.begin(), result.end()); + int middle = result.size()/2; + return result[middle]; +} + +/* +// Different solution +int NoiseMedian::getMedian(int x, int y, Channel channel) +{ + int radius = getParameter("radius").toInt(); + int window_size = 2 * radius + 1; + + int powSize = size*size; + int window[powSize]; + + int sr = 0; + int sc = 0; + int lp = 0; + float value; + + for (sr = x-radius; sr <= x+radius; sr++) + { + for (sc = y-radius; sc <= y+radius; sc++) + { + QRgb color = getPixel(sr, sc, CyclicEdge); + + switch(channel) + { + case LChannel: + value = qGray (color); + break; + case RChannel: + value = qRed (color); + break; + case GChannel: + value = qGreen(color); + break; + case BChannel: + value = qBlue (color); + break; + } + window[lp++] = value; + } + } + + std::sort(window, window + powSize); + int center = powSize / 2; + int result = window[center]; + return result; +} +*/ diff --git a/app/cpp/mysimplegimp/src/core/transformations/noise_bilateral.cpp b/app/cpp/mysimplegimp/src/core/transformations/noise_bilateral.cpp index cc6579f..167f112 100644 --- a/app/cpp/mysimplegimp/src/core/transformations/noise_bilateral.cpp +++ b/app/cpp/mysimplegimp/src/core/transformations/noise_bilateral.cpp @@ -19,30 +19,80 @@ PNM* NoiseBilateral::transform() sigma_d = getParameter("sigma_d").toInt(); sigma_r = getParameter("sigma_r").toInt(); + radius = sigma_d; - qDebug() << Q_FUNC_INFO << "Not implemented yet!"; + for (int x = 0; x < width; x++) + { + for (int y = 0; y < height; y++) + { + if (image->format() == QImage::Format_Indexed8) + { + // Get calculated value for LChannel and set as new pixel + newImage->setPixel(x, y, calcVal(x, y, LChannel)); + } + else + { + // Get calculated values for RGB channels + int r_calc = calcVal(x, y, RChannel); + int g_calc = calcVal(x, y, GChannel); + int b_calc = calcVal(x, y, BChannel); + + + QColor color = QColor(r_calc, g_calc, b_calc); + newImage->setPixel(x, y, color.rgb()); + } + } + } return newImage; } int NoiseBilateral::calcVal(int x, int y, Channel channel) { - qDebug() << Q_FUNC_INFO << "Not implemented yet!"; + // Set variables + float top = 0; + float bottom = 0; - return 0; + // Get window + math::matrix window = getWindow(x,y, radius, channel, RepeatEdge); + + // Get size of matrix + int window_row_number = window.rowno(); + int window_col_number = window.colno(); + + // Get central value + float central = window[window_row_number / 2][window_col_number / 2]; + + for (int i = 0; i < window_col_number; i++) + { + for (int j = 0; j < window_row_number; j++) + { + // Get Point in (i, j) + QPoint p1(i,j); + + // Get second Point + QPoint p2(window_row_number / 2, window_col_number / 2); + + // Calculate top value + top = top + window[i][j] * colorCloseness(window[i][j], central) * spatialCloseness(p1, p2); + + // Calculate bottom value + bottom = bottom + colorCloseness(window[i][j], central) * spatialCloseness(p1, p2); + } + } + + return top / bottom; } float NoiseBilateral::colorCloseness(int val1, int val2) { - qDebug() << Q_FUNC_INFO << "Not implemented yet!"; - - return 0; + float result = exp(-(pow(val1 - val2, 2) / (2 * sigma_r * sigma_r))); + return result; } float NoiseBilateral::spatialCloseness(QPoint point1, QPoint point2) { - qDebug() << Q_FUNC_INFO << "Not implemented yet!"; - - return 0; + float result = exp(-(pow(point1.x() - point2.x(), 2) + pow(point1.y() - point2.y(), 2) / (2 * sigma_d * sigma_d))); + return result; } diff --git a/app/cpp/mysimplegimp/src/core/transformations/noise_median.cpp b/app/cpp/mysimplegimp/src/core/transformations/noise_median.cpp index 1d8a9f7..35316b3 100644 --- a/app/cpp/mysimplegimp/src/core/transformations/noise_median.cpp +++ b/app/cpp/mysimplegimp/src/core/transformations/noise_median.cpp @@ -17,7 +17,31 @@ PNM* NoiseMedian::transform() PNM* newImage = new PNM(width, height, image->format()); - qDebug() << Q_FUNC_INFO << "Not implemented yet!"; + + for (int i = 0; i < width; i++) + { + for (int j = 0; j < height; j++) + { + if (image->format() == QImage::Format_Indexed8) + { + // Get median value for LChannel and set as new pixel + newImage->setPixel(i, j, getMedian(i, j, LChannel)); + } + else + { + // Get median values for RGB channels + int r_med = getMedian(i, j, RChannel); + int g_med = getMedian(i, j, GChannel); + int b_med = getMedian(i, j, BChannel); + + // Create new color + QColor color = QColor(r_med, g_med, b_med); + + // Set new pixel with rgb color + newImage->setPixel(i, j, color.rgb()); + } + } + } return newImage; } @@ -25,8 +49,64 @@ PNM* NoiseMedian::transform() int NoiseMedian::getMedian(int x, int y, Channel channel) { int radius = getParameter("radius").toInt(); + int window_size = 2 * radius + 1; - qDebug() << Q_FUNC_INFO << "Not implemented yet!"; + math::matrix window = getWindow(x, y, window_size, channel, RepeatEdge); + std::vector result; //list does not provide a subscript operator - return 0; + for(std::size_t i=0; i < window.rowno(); i++){ + for(std::size_t j=0; j < window.colno(); j++){ + result.push_back(window[i][j]); + } + } + std::sort(result.begin(), result.end()); + int middle = result.size()/2; + return result[middle]; } + +/* +// Different solution +int NoiseMedian::getMedian(int x, int y, Channel channel) +{ + int radius = getParameter("radius").toInt(); + int window_size = 2 * radius + 1; + + int powSize = size*size; + int window[powSize]; + + int sr = 0; + int sc = 0; + int lp = 0; + float value; + + for (sr = x-radius; sr <= x+radius; sr++) + { + for (sc = y-radius; sc <= y+radius; sc++) + { + QRgb color = getPixel(sr, sc, CyclicEdge); + + switch(channel) + { + case LChannel: + value = qGray (color); + break; + case RChannel: + value = qRed (color); + break; + case GChannel: + value = qGreen(color); + break; + case BChannel: + value = qBlue (color); + break; + } + window[lp++] = value; + } + } + + std::sort(window, window + powSize); + int center = powSize / 2; + int result = window[center]; + return result; +} +*/