From d264b6070d8c2dcaf2a8954b406f2d4f6fd71243 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaros=C5=82aw=20Wieczorek?= Date: Thu, 15 Apr 2021 23:48:37 +0200 Subject: [PATCH] Zadanie 12 --- 12/do_sprawdzenia/cpp/corner_harris.cpp | 158 ++++++++++++++++++ 12/do_sprawdzenia/cpp/image1.png | Bin 0 -> 5577 bytes .../core/transformations/corner_harris.cpp | 138 ++++++++++++++- 3 files changed, 290 insertions(+), 6 deletions(-) create mode 100644 12/do_sprawdzenia/cpp/corner_harris.cpp create mode 100644 12/do_sprawdzenia/cpp/image1.png diff --git a/12/do_sprawdzenia/cpp/corner_harris.cpp b/12/do_sprawdzenia/cpp/corner_harris.cpp new file mode 100644 index 0000000..ae8d718 --- /dev/null +++ b/12/do_sprawdzenia/cpp/corner_harris.cpp @@ -0,0 +1,158 @@ +#include "corner_harris.h" + +#include "blur_gaussian.h" +#include "conversion_grayscale.h" +#include "edge_sobel.h" + +CornerHarris::CornerHarris(PNM* img) : + Convolution(img) +{ +} + +CornerHarris::CornerHarris(PNM* img, ImageViewer* iv) : + Convolution(img, iv) +{ +} + +PNM* CornerHarris::transform() +{ + int threshold = getParameter("threshold").toInt(); + double sigma = getParameter("sigma").toDouble(); + double sigma_weight = getParameter("sigma_weight").toDouble(); + double k_param = getParameter("k").toDouble(); + + int width = image->width(); + int height = image->height(); + + PNM* newImage = new PNM(width, height, QImage::Format_Mono); + + math::matrix Ixx(width, height); + math::matrix Iyy(width, height); + math::matrix Ixy(width, height); + math::matrix corner_candidates(width, height); + math::matrix corner_nonmax_suppress(width, height); + + ConversionGrayscale* conversion_grayscale = new ConversionGrayscale(image); + PNM* gray_image = conversion_grayscale->transform(); + + BlurGaussian* blur_gaussian = new BlurGaussian(gray_image); + blur_gaussian->setParameter("size", 3); + blur_gaussian->setParameter("sigma", 1.6); + PNM* blur_gauss_image = blur_gaussian->transform(); + + EdgeSobel* edge_sobel = new EdgeSobel(blur_gauss_image); + math::matrix* Gx = edge_sobel->rawHorizontalDetection(); + math::matrix* Gy = edge_sobel->rawVerticalDetection(); + + for (int i = 0; i < width; i++) + { + for (int j = 0; j < height; j++) + { + Ixx[i][j] = (*Gx)[i][j] * (*Gx)[i][j]; + Ixy[i][j] = (*Gx)[i][j] * (*Gy)[i][j]; + Iyy[i][j] = (*Gy)[i][j] * (*Gy)[i][j]; + + corner_candidates[i][j] = 0; + corner_nonmax_suppress[i][j] = 0; + } + } + + for (int i = 1; i < width - 1; i++) + { + for (int j = 1; j < height - 1; j++) + { + float Sxx = 0; + float Syy = 0; + float Sxy = 0; + + for (int k = -1; k <= 1; k++) + { + for (int l = -1; l <= 1; l++) + { + Sxx = Sxx + Ixx[i + k][j + l] * BlurGaussian::getGauss(k, l, sigma); + Syy = Syy + Iyy[i + k][j + l] * BlurGaussian::getGauss(k, l, sigma); + Sxy = Sxy + Ixy[i + k][j + l] * BlurGaussian::getGauss(k, l, sigma); + } + } + + Sxx = Sxx / sigma_weight; + Sxy = Sxy / sigma_weight; + Syy = Syy / sigma_weight; + + math::matrix H(2,2); + + H(0,0) = Sxx; + H(0,1) = Sxy; + H(1,0) = Sxy; + H(1,1) = Syy; + + float detH = H(0, 0) * H(1, 1) - H(0, 1) * H(1, 0); //determinant + float trH = H(0, 0) + H(1, 1); //trace + float r = detH - k_param * pow(trH, 2); + + if (r > threshold) + { + corner_candidates[i][j] = r; + } + } + } + + bool search = true; + + while(search) + { + search = false; + for (int i = 1; i < width - 1; i++) + { + for (int j = 1; j 0) + { + search = true; + } + + corner_nonmax_suppress[i][j] = 0; + } + + } + } + corner_candidates = corner_nonmax_suppress; + } + + for (int i = 0; i < width; i++) + { + for (int j = 0; j < height; j++) + { + if (corner_candidates[i][j] == 0) + { + newImage->setPixel(i, j, Qt::color0); + } + else + { + newImage->setPixel(i, j, Qt::color1); + } + } + } + return newImage; +} + + diff --git a/12/do_sprawdzenia/cpp/image1.png b/12/do_sprawdzenia/cpp/image1.png new file mode 100644 index 0000000000000000000000000000000000000000..80b3ea4b7741edbaf171a2ffe299bd7edad30c43 GIT binary patch literal 5577 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, - height = image->height(); + int width = image->width(); + int height = image->height(); PNM* newImage = new PNM(width, height, QImage::Format_Mono); - qDebug() << Q_FUNC_INFO << "Not implemented yet!"; + math::matrix Ixx(width, height); + math::matrix Iyy(width, height); + math::matrix Ixy(width, height); + math::matrix corner_candidates(width, height); + math::matrix corner_nonmax_suppress(width, height); + ConversionGrayscale* conversion_grayscale = new ConversionGrayscale(image); + PNM* gray_image = conversion_grayscale->transform(); + + BlurGaussian* blur_gaussian = new BlurGaussian(gray_image); + blur_gaussian->setParameter("size", 3); + blur_gaussian->setParameter("sigma", 1.6); + PNM* blur_gauss_image = blur_gaussian->transform(); + + EdgeSobel* edge_sobel = new EdgeSobel(blur_gauss_image); + math::matrix* Gx = edge_sobel->rawHorizontalDetection(); + math::matrix* Gy = edge_sobel->rawVerticalDetection(); + + for (int i = 0; i < width; i++) + { + for (int j = 0; j < height; j++) + { + Ixx[i][j] = (*Gx)[i][j] * (*Gx)[i][j]; + Ixy[i][j] = (*Gx)[i][j] * (*Gy)[i][j]; + Iyy[i][j] = (*Gy)[i][j] * (*Gy)[i][j]; + + corner_candidates[i][j] = 0; + corner_nonmax_suppress[i][j] = 0; + } + } + + for (int i = 1; i < width - 1; i++) + { + for (int j = 1; j < height - 1; j++) + { + float Sxx = 0; + float Syy = 0; + float Sxy = 0; + + for (int k = -1; k <= 1; k++) + { + for (int l = -1; l <= 1; l++) + { + Sxx = Sxx + Ixx[i + k][j + l] * BlurGaussian::getGauss(k, l, sigma); + Syy = Syy + Iyy[i + k][j + l] * BlurGaussian::getGauss(k, l, sigma); + Sxy = Sxy + Ixy[i + k][j + l] * BlurGaussian::getGauss(k, l, sigma); + } + } + + Sxx = Sxx / sigma_weight; + Sxy = Sxy / sigma_weight; + Syy = Syy / sigma_weight; + + math::matrix H(2,2); + + H(0,0) = Sxx; + H(0,1) = Sxy; + H(1,0) = Sxy; + H(1,1) = Syy; + + float detH = H(0, 0) * H(1, 1) - H(0, 1) * H(1, 0); //determinant + float trH = H(0, 0) + H(1, 1); //trace + float r = detH - k_param * pow(trH, 2); + + if (r > threshold) + { + corner_candidates[i][j] = r; + } + } + } + + bool search = true; + + while(search) + { + search = false; + for (int i = 1; i < width - 1; i++) + { + for (int j = 1; j 0) + { + search = true; + } + + corner_nonmax_suppress[i][j] = 0; + } + + } + } + corner_candidates = corner_nonmax_suppress; + } + + for (int i = 0; i < width; i++) + { + for (int j = 0; j < height; j++) + { + if (corner_candidates[i][j] == 0) + { + newImage->setPixel(i, j, Qt::color0); + } + else + { + newImage->setPixel(i, j, Qt::color1); + } + } + } return newImage; } + +