diff --git a/08/do_sprawdzenia/cpp/edge_gradient.cpp b/08/do_sprawdzenia/cpp/edge_gradient.cpp new file mode 100644 index 0000000..1d485d5 --- /dev/null +++ b/08/do_sprawdzenia/cpp/edge_gradient.cpp @@ -0,0 +1,105 @@ +#include "edge_gradient.h" + +EdgeGradient::EdgeGradient(PNM* img, ImageViewer* iv) : + Convolution(img, iv) +{ +} + +EdgeGradient::EdgeGradient(PNM* img) : + Convolution(img) +{ +} + +PNM* EdgeGradient::verticalDetection() +{ + return convolute(g_y, RepeatEdge); +} + +PNM* EdgeGradient::horizontalDetection() +{ + return convolute(g_x, RepeatEdge); +} + + +int EdgeGradient::calcValue(int i, int j, Channel channel, PNM* img_x, PNM* img_y) +{ + int value_x, value_y; + double power_x, power_y; + int value_xy; + int result; + + QRgb pixel_x = img_x->pixel(i, j); + QRgb pixel_y = img_y->pixel(i, j); + + switch(channel) + { + + case RChannel: + value_x = qRed(pixel_x); + value_y = qRed(pixel_y); + break; + case GChannel: + value_x = qGreen(pixel_x); + value_y = qGreen(pixel_y); + break; + case BChannel: + value_x = qBlue(pixel_x); + value_y = qBlue(pixel_y); + break; + case LChannel: + value_x = qGray(pixel_x); + value_y = qGray(pixel_y); + break; + } + + power_x = pow(value_x, 2); + power_y = pow(value_y, 2); + + value_xy = (int) sqrt(power_x + power_y); + + result = std::max(0, std::min(255, value_xy)); + + return result; + +} + + +PNM* EdgeGradient::transform() +{ + PNM* newImage = new PNM(image->width(), image->height(), image->format()); + + int width = image->width(); + int height = image->height(); + + // Gradient image by x + PNM* img_x = horizontalDetection(); + + // Gradient image by y + PNM* img_y = verticalDetection(); + + + for (int i = 0; i < width; i++) + { + for (int j = 0; j < height; j++) + { + if (image->format() == QImage::Format_Indexed8) + { + // Calculate gray pixel value + int l = calcValue(i, j, LChannel, img_x, img_y); + newImage->setPixel(i, j, l); + } + else + { + // Calculate RGB values for pixel + int r = calcValue(i, j, RChannel, img_x, img_y); + int g = calcValue(i, j, GChannel, img_x, img_y); + int b = calcValue(i, j, BChannel, img_x, img_y); + + QColor color = QColor(r, g, b); + newImage->setPixel(i, j, color.rgb()); + } + } + } + return newImage; +} + diff --git a/08/do_sprawdzenia/cpp/edge_gradient.h b/08/do_sprawdzenia/cpp/edge_gradient.h new file mode 100644 index 0000000..e2400a2 --- /dev/null +++ b/08/do_sprawdzenia/cpp/edge_gradient.h @@ -0,0 +1,24 @@ +#ifndef EDGE_GRADIENT_H +#define EDGE_GRADIENT_H + +#include "convolution.h" + +class EdgeGradient : public Convolution +{ +public: + EdgeGradient(PNM*); + EdgeGradient(PNM*, ImageViewer*); + + virtual PNM* transform(); + + PNM* verticalDetection(); + PNM* horizontalDetection(); + int calcValue(int i, int j, Channel channel, PNM* img_x, PNM* img_y); + +protected: + virtual void prepareMatrices() = 0; + math::matrix g_x, + g_y; +}; + +#endif // EDGE_GRADIENT_H diff --git a/08/do_sprawdzenia/cpp/edge_laplacian.cpp b/08/do_sprawdzenia/cpp/edge_laplacian.cpp new file mode 100644 index 0000000..368c7d0 --- /dev/null +++ b/08/do_sprawdzenia/cpp/edge_laplacian.cpp @@ -0,0 +1,33 @@ +#include "edge_laplacian.h" + +EdgeLaplacian::EdgeLaplacian(PNM* img) : + Convolution(img) +{ +} + +EdgeLaplacian::EdgeLaplacian(PNM* img, ImageViewer* iv) : + Convolution(img, iv) +{ +} + +math::matrix EdgeLaplacian::getMask(int, Mode) +{ + int size = getParameter("size").toInt(); + math::matrix mask(size, size); + + int center = size / 2; + + for (int i = 0; i < size; i++) + { + for (int j = 0; j < size; j++) + { + mask(i, j) = -1; + } + } + + // Calculate center element of mask + mask(center, center) = pow(size, 2) - 1; + + return mask; +} + diff --git a/08/do_sprawdzenia/cpp/edge_laplacian_of_gauss.cpp b/08/do_sprawdzenia/cpp/edge_laplacian_of_gauss.cpp new file mode 100644 index 0000000..785bfc3 --- /dev/null +++ b/08/do_sprawdzenia/cpp/edge_laplacian_of_gauss.cpp @@ -0,0 +1,55 @@ +#include "edge_laplacian_of_gauss.h" + +#include "blur_gaussian.h" + +EdgeLaplaceOfGauss::EdgeLaplaceOfGauss(PNM* img) : + Convolution(img) +{ +} + +EdgeLaplaceOfGauss::EdgeLaplaceOfGauss(PNM* img, ImageViewer* iv) : + Convolution(img, iv) +{ +} + +math::matrix EdgeLaplaceOfGauss::getMask() +{ + size = getParameter("size").toInt(); + double sigma = getParameter("sigma").toDouble(); + + math::matrix mask(size, size); + + int center = -size / 2; + + + for (int x = 0, k = center; x < size; x++, k++) + { + for (int y = 0, l = center; y < size; y++, l++) + { + mask(x, y) = getLoG(k, l, sigma); + } + } + + return mask; +} + +float EdgeLaplaceOfGauss::getLoG(int x, int y, float s) +{ + int px = pow(x, 2); + int py = pow(y, 2); + + float ps = pow(s, 2); + int numerator = px + py - 2; + + int gauss = BlurGaussian::getGauss(x, y, ps); + + int result = (numerator / ps) * gauss; + + return result; +} + + +int EdgeLaplaceOfGauss::getSize() +{ + return size; +} diff --git a/08/do_sprawdzenia/cpp/edge_laplacian_of_gauss.h b/08/do_sprawdzenia/cpp/edge_laplacian_of_gauss.h new file mode 100644 index 0000000..edb70a5 --- /dev/null +++ b/08/do_sprawdzenia/cpp/edge_laplacian_of_gauss.h @@ -0,0 +1,21 @@ +#ifndef EDGE_LAPLACE_GAUSS_H +#define EDGE_LAPLACE_GAUSS_H + +#include "convolution.h" + +class EdgeLaplaceOfGauss : public Convolution +{ +public: + EdgeLaplaceOfGauss(PNM*); + EdgeLaplaceOfGauss(PNM*, ImageViewer*); + + virtual math::matrix getMask(); + + static float getLoG(int, int, float); + int getSize(); + +private: + int size; +}; + +#endif // EDGE_LAPLACE_GAUSS_H diff --git a/08/do_sprawdzenia/cpp/edge_prewitt.cpp b/08/do_sprawdzenia/cpp/edge_prewitt.cpp new file mode 100644 index 0000000..5ec1ed2 --- /dev/null +++ b/08/do_sprawdzenia/cpp/edge_prewitt.cpp @@ -0,0 +1,19 @@ +#include "edge_prewitt.h" + +EdgePrewitt::EdgePrewitt(PNM*img) : + EdgeGradient(img) +{ + prepareMatrices(); +} + +EdgePrewitt::EdgePrewitt(PNM*img, ImageViewer* iv) : + EdgeGradient(img, iv) +{ + prepareMatrices(); +} + +void EdgePrewitt::prepareMatrices() +{ + g_x = math::matrix(3, 3, {-1, 0, 1, -1, 0, 1, -1, 0, 1}); + g_y = math::matrix(3, 3, {-1, -1, -1, 0, 0, 0, 1, 1, 1}); +} diff --git a/08/do_sprawdzenia/cpp/edge_roberts.cpp b/08/do_sprawdzenia/cpp/edge_roberts.cpp new file mode 100644 index 0000000..8183323 --- /dev/null +++ b/08/do_sprawdzenia/cpp/edge_roberts.cpp @@ -0,0 +1,19 @@ +#include "edge_roberts.h" + +EdgeRoberts::EdgeRoberts(PNM* img) : + EdgeGradient(img) +{ + prepareMatrices(); +} + +EdgeRoberts::EdgeRoberts(PNM* img, ImageViewer* iv) : + EdgeGradient(img, iv) +{ + prepareMatrices(); +} + +void EdgeRoberts::prepareMatrices() +{ + g_x = math::matrix(2, 2, {1, 0, 0, -1}); + g_y = math::matrix(2, 2, {0, 1, -1, 0}); +} diff --git a/08/do_sprawdzenia/cpp/edge_sobel.cpp b/08/do_sprawdzenia/cpp/edge_sobel.cpp new file mode 100644 index 0000000..237ef1d --- /dev/null +++ b/08/do_sprawdzenia/cpp/edge_sobel.cpp @@ -0,0 +1,37 @@ +#include "edge_sobel.h" + +EdgeSobel::EdgeSobel(PNM* img, ImageViewer* iv) : + EdgeGradient(img, iv) +{ + prepareMatrices(); +} + +EdgeSobel::EdgeSobel(PNM* img) : + EdgeGradient(img) +{ + prepareMatrices(); +} + +void EdgeSobel::prepareMatrices() +{ + g_x = math::matrix(3, 3, {-1, 0, 1, -2, 0, 2, -1, 0, 1}); + g_y = math::matrix(3, 3, {-1, -2, -1, 0, 0, 0, 1, 2, 1}); +} + +math::matrix* EdgeSobel::rawHorizontalDetection() +{ + math::matrix* x_gradient = new math::matrix(this->image->width(), this->image->height()); + + qDebug() << Q_FUNC_INFO << "Not implemented yet!"; + + return x_gradient; +} + +math::matrix* EdgeSobel::rawVerticalDetection() +{ + math::matrix* y_gradient = new math::matrix(this->image->width(), this->image->height()); + + qDebug() << Q_FUNC_INFO << "Not implemented yet!"; + + return y_gradient; +} diff --git a/08/do_sprawdzenia/cpp/edge_zero.cpp b/08/do_sprawdzenia/cpp/edge_zero.cpp new file mode 100644 index 0000000..bcad969 --- /dev/null +++ b/08/do_sprawdzenia/cpp/edge_zero.cpp @@ -0,0 +1,59 @@ +#include "edge_zero.h" + +#include "edge_laplacian_of_gauss.h" + +EdgeZeroCrossing::EdgeZeroCrossing(PNM* img) : + Convolution(img) +{ +} + +EdgeZeroCrossing::EdgeZeroCrossing(PNM* img, ImageViewer* iv) : + Convolution(img, iv) +{ +} + +PNM* EdgeZeroCrossing::transform() +{ + int size = getParameter("size").toInt(); + double sigma = getParameter("sigma").toDouble(); + int t = getParameter("threshold").toInt(); + + int width = image->width(); + int height = image->height(); + + int t_width; + int t_height; + + PNM* newImage = new PNM(width, height, QImage::Format_Grayscale8); + + EdgeLaplaceOfGauss *laplace_gauss = new EdgeLaplaceOfGauss(image); + + laplace_gauss->setParameter("size", size); + laplace_gauss->setParameter("sigma", sigma); + + PNM* transformed_image = laplace_gauss->transform(); + + t_width = transformed_image->width(); + t_height = transformed_image->height(); + + for (int i = 0; i < t_width; i++) + { + for (int j = 0; j < t_height; j++) + { + math::matrix window = laplace_gauss->getWindow(i, j, size, LChannel, RepeatEdge); + + if (window.min() < (128 - t) && window.max() > (128 + t)) + { + QRgb pixel = transformed_image->pixel(i, j); + newImage->setPixel(i, j, QColor(pixel).rgb()); + } + else + { + newImage->setPixel(i, j, QColor(0,0,0).rgb()); + } + } + } + + return newImage; +} + diff --git a/08/do_sprawdzenia/cpp/image_laplacian.png b/08/do_sprawdzenia/cpp/image_laplacian.png new file mode 100644 index 0000000..8fffe3d Binary files /dev/null and b/08/do_sprawdzenia/cpp/image_laplacian.png differ diff --git a/08/do_sprawdzenia/cpp/image_prewitt.png b/08/do_sprawdzenia/cpp/image_prewitt.png new file mode 100644 index 0000000..dcf61a4 Binary files /dev/null and b/08/do_sprawdzenia/cpp/image_prewitt.png differ diff --git a/08/do_sprawdzenia/cpp/image_roberts.png b/08/do_sprawdzenia/cpp/image_roberts.png new file mode 100644 index 0000000..838c899 Binary files /dev/null and b/08/do_sprawdzenia/cpp/image_roberts.png differ diff --git a/08/do_sprawdzenia/cpp/image_sobel.png b/08/do_sprawdzenia/cpp/image_sobel.png new file mode 100644 index 0000000..6b4803a Binary files /dev/null and b/08/do_sprawdzenia/cpp/image_sobel.png differ diff --git a/08/do_sprawdzenia/cpp/image_zero_cross.png b/08/do_sprawdzenia/cpp/image_zero_cross.png new file mode 100644 index 0000000..1c7e296 Binary files /dev/null and b/08/do_sprawdzenia/cpp/image_zero_cross.png differ diff --git a/app/cpp/mysimplegimp/src/core/transformations/edge_gradient.cpp b/app/cpp/mysimplegimp/src/core/transformations/edge_gradient.cpp index a36a5b8..1d485d5 100644 --- a/app/cpp/mysimplegimp/src/core/transformations/edge_gradient.cpp +++ b/app/cpp/mysimplegimp/src/core/transformations/edge_gradient.cpp @@ -20,12 +20,86 @@ PNM* EdgeGradient::horizontalDetection() return convolute(g_x, RepeatEdge); } + +int EdgeGradient::calcValue(int i, int j, Channel channel, PNM* img_x, PNM* img_y) +{ + int value_x, value_y; + double power_x, power_y; + int value_xy; + int result; + + QRgb pixel_x = img_x->pixel(i, j); + QRgb pixel_y = img_y->pixel(i, j); + + switch(channel) + { + + case RChannel: + value_x = qRed(pixel_x); + value_y = qRed(pixel_y); + break; + case GChannel: + value_x = qGreen(pixel_x); + value_y = qGreen(pixel_y); + break; + case BChannel: + value_x = qBlue(pixel_x); + value_y = qBlue(pixel_y); + break; + case LChannel: + value_x = qGray(pixel_x); + value_y = qGray(pixel_y); + break; + } + + power_x = pow(value_x, 2); + power_y = pow(value_y, 2); + + value_xy = (int) sqrt(power_x + power_y); + + result = std::max(0, std::min(255, value_xy)); + + return result; + +} + + PNM* EdgeGradient::transform() { PNM* newImage = new PNM(image->width(), image->height(), image->format()); - qDebug() << Q_FUNC_INFO << "Not implemented yet!"; + int width = image->width(); + int height = image->height(); + // Gradient image by x + PNM* img_x = horizontalDetection(); + + // Gradient image by y + PNM* img_y = verticalDetection(); + + + for (int i = 0; i < width; i++) + { + for (int j = 0; j < height; j++) + { + if (image->format() == QImage::Format_Indexed8) + { + // Calculate gray pixel value + int l = calcValue(i, j, LChannel, img_x, img_y); + newImage->setPixel(i, j, l); + } + else + { + // Calculate RGB values for pixel + int r = calcValue(i, j, RChannel, img_x, img_y); + int g = calcValue(i, j, GChannel, img_x, img_y); + int b = calcValue(i, j, BChannel, img_x, img_y); + + QColor color = QColor(r, g, b); + newImage->setPixel(i, j, color.rgb()); + } + } + } return newImage; } diff --git a/app/cpp/mysimplegimp/src/core/transformations/edge_gradient.h b/app/cpp/mysimplegimp/src/core/transformations/edge_gradient.h index 331ccc1..e2400a2 100644 --- a/app/cpp/mysimplegimp/src/core/transformations/edge_gradient.h +++ b/app/cpp/mysimplegimp/src/core/transformations/edge_gradient.h @@ -13,6 +13,7 @@ public: PNM* verticalDetection(); PNM* horizontalDetection(); + int calcValue(int i, int j, Channel channel, PNM* img_x, PNM* img_y); protected: virtual void prepareMatrices() = 0; diff --git a/app/cpp/mysimplegimp/src/core/transformations/edge_laplacian.cpp b/app/cpp/mysimplegimp/src/core/transformations/edge_laplacian.cpp index 8c26718..368c7d0 100644 --- a/app/cpp/mysimplegimp/src/core/transformations/edge_laplacian.cpp +++ b/app/cpp/mysimplegimp/src/core/transformations/edge_laplacian.cpp @@ -15,7 +15,18 @@ math::matrix EdgeLaplacian::getMask(int, Mode) int size = getParameter("size").toInt(); math::matrix mask(size, size); - qDebug() << Q_FUNC_INFO << "Not implemented yet!"; + int center = size / 2; + + for (int i = 0; i < size; i++) + { + for (int j = 0; j < size; j++) + { + mask(i, j) = -1; + } + } + + // Calculate center element of mask + mask(center, center) = pow(size, 2) - 1; return mask; } diff --git a/app/cpp/mysimplegimp/src/core/transformations/edge_laplacian_of_gauss.cpp b/app/cpp/mysimplegimp/src/core/transformations/edge_laplacian_of_gauss.cpp index dcacb71..785bfc3 100644 --- a/app/cpp/mysimplegimp/src/core/transformations/edge_laplacian_of_gauss.cpp +++ b/app/cpp/mysimplegimp/src/core/transformations/edge_laplacian_of_gauss.cpp @@ -12,25 +12,43 @@ EdgeLaplaceOfGauss::EdgeLaplaceOfGauss(PNM* img, ImageViewer* iv) : { } -math::matrix EdgeLaplaceOfGauss::getMask(int, Mode) +math::matrix EdgeLaplaceOfGauss::getMask() { size = getParameter("size").toInt(); double sigma = getParameter("sigma").toDouble(); math::matrix mask(size, size); - qDebug() << Q_FUNC_INFO << "Not implemented yet!"; + int center = -size / 2; + + + for (int x = 0, k = center; x < size; x++, k++) + { + for (int y = 0, l = center; y < size; y++, l++) + { + mask(x, y) = getLoG(k, l, sigma); + } + } return mask; } float EdgeLaplaceOfGauss::getLoG(int x, int y, float s) { - qDebug() << Q_FUNC_INFO << "Not implemented yet!"; + int px = pow(x, 2); + int py = pow(y, 2); - return 0; + float ps = pow(s, 2); + int numerator = px + py - 2; + + int gauss = BlurGaussian::getGauss(x, y, ps); + + int result = (numerator / ps) * gauss; + + return result; } + int EdgeLaplaceOfGauss::getSize() { return size; diff --git a/app/cpp/mysimplegimp/src/core/transformations/edge_laplacian_of_gauss.h b/app/cpp/mysimplegimp/src/core/transformations/edge_laplacian_of_gauss.h index d69f564..edb70a5 100644 --- a/app/cpp/mysimplegimp/src/core/transformations/edge_laplacian_of_gauss.h +++ b/app/cpp/mysimplegimp/src/core/transformations/edge_laplacian_of_gauss.h @@ -9,7 +9,7 @@ public: EdgeLaplaceOfGauss(PNM*); EdgeLaplaceOfGauss(PNM*, ImageViewer*); - virtual math::matrix getMask(int, Mode); + virtual math::matrix getMask(); static float getLoG(int, int, float); int getSize(); diff --git a/app/cpp/mysimplegimp/src/core/transformations/edge_prewitt.cpp b/app/cpp/mysimplegimp/src/core/transformations/edge_prewitt.cpp index d6585eb..5ec1ed2 100644 --- a/app/cpp/mysimplegimp/src/core/transformations/edge_prewitt.cpp +++ b/app/cpp/mysimplegimp/src/core/transformations/edge_prewitt.cpp @@ -14,6 +14,6 @@ EdgePrewitt::EdgePrewitt(PNM*img, ImageViewer* iv) : void EdgePrewitt::prepareMatrices() { - qDebug() << Q_FUNC_INFO << "Not implemented yet!"; + g_x = math::matrix(3, 3, {-1, 0, 1, -1, 0, 1, -1, 0, 1}); + g_y = math::matrix(3, 3, {-1, -1, -1, 0, 0, 0, 1, 1, 1}); } - diff --git a/app/cpp/mysimplegimp/src/core/transformations/edge_roberts.cpp b/app/cpp/mysimplegimp/src/core/transformations/edge_roberts.cpp index 0428da9..8183323 100644 --- a/app/cpp/mysimplegimp/src/core/transformations/edge_roberts.cpp +++ b/app/cpp/mysimplegimp/src/core/transformations/edge_roberts.cpp @@ -14,5 +14,6 @@ EdgeRoberts::EdgeRoberts(PNM* img, ImageViewer* iv) : void EdgeRoberts::prepareMatrices() { - qDebug() << Q_FUNC_INFO << "Not implemented yet!"; + g_x = math::matrix(2, 2, {1, 0, 0, -1}); + g_y = math::matrix(2, 2, {0, 1, -1, 0}); } diff --git a/app/cpp/mysimplegimp/src/core/transformations/edge_sobel.cpp b/app/cpp/mysimplegimp/src/core/transformations/edge_sobel.cpp index 6ef4bff..237ef1d 100644 --- a/app/cpp/mysimplegimp/src/core/transformations/edge_sobel.cpp +++ b/app/cpp/mysimplegimp/src/core/transformations/edge_sobel.cpp @@ -14,7 +14,8 @@ EdgeSobel::EdgeSobel(PNM* img) : void EdgeSobel::prepareMatrices() { - qDebug() << Q_FUNC_INFO << "Not implemented yet!"; + g_x = math::matrix(3, 3, {-1, 0, 1, -2, 0, 2, -1, 0, 1}); + g_y = math::matrix(3, 3, {-1, -2, -1, 0, 0, 0, 1, 2, 1}); } math::matrix* EdgeSobel::rawHorizontalDetection() diff --git a/app/cpp/mysimplegimp/src/core/transformations/edge_zero.cpp b/app/cpp/mysimplegimp/src/core/transformations/edge_zero.cpp index 541943f..bcad969 100644 --- a/app/cpp/mysimplegimp/src/core/transformations/edge_zero.cpp +++ b/app/cpp/mysimplegimp/src/core/transformations/edge_zero.cpp @@ -14,16 +14,45 @@ EdgeZeroCrossing::EdgeZeroCrossing(PNM* img, ImageViewer* iv) : PNM* EdgeZeroCrossing::transform() { - int width = image->width(), - height = image->height(); - int size = getParameter("size").toInt(); double sigma = getParameter("sigma").toDouble(); int t = getParameter("threshold").toInt(); + int width = image->width(); + int height = image->height(); + + int t_width; + int t_height; + PNM* newImage = new PNM(width, height, QImage::Format_Grayscale8); - qDebug() << Q_FUNC_INFO << "Not implemented yet!"; + EdgeLaplaceOfGauss *laplace_gauss = new EdgeLaplaceOfGauss(image); + + laplace_gauss->setParameter("size", size); + laplace_gauss->setParameter("sigma", sigma); + + PNM* transformed_image = laplace_gauss->transform(); + + t_width = transformed_image->width(); + t_height = transformed_image->height(); + + for (int i = 0; i < t_width; i++) + { + for (int j = 0; j < t_height; j++) + { + math::matrix window = laplace_gauss->getWindow(i, j, size, LChannel, RepeatEdge); + + if (window.min() < (128 - t) && window.max() > (128 + t)) + { + QRgb pixel = transformed_image->pixel(i, j); + newImage->setPixel(i, j, QColor(pixel).rgb()); + } + else + { + newImage->setPixel(i, j, QColor(0,0,0).rgb()); + } + } + } return newImage; }