From 5057dc3a24a74ada5cb4e6f8ad2412f9174f15c1 Mon Sep 17 00:00:00 2001 From: Dawid_Kreft Date: Mon, 11 May 2020 23:18:35 +0200 Subject: [PATCH] Zadanie_10 and fix convolution --- src/core/transformations/convolution.cpp | 118 +++++++------- src/core/transformations/convolution.h | 1 + src/core/transformations/edge_canny.cpp | 186 ++++++++++++++++++++++- src/core/transformations/edge_canny.h | 2 + src/core/transformations/edge_sobel.cpp | 20 ++- 5 files changed, 267 insertions(+), 60 deletions(-) diff --git a/src/core/transformations/convolution.cpp b/src/core/transformations/convolution.cpp index e3f3ec6..497aa64 100644 --- a/src/core/transformations/convolution.cpp +++ b/src/core/transformations/convolution.cpp @@ -55,69 +55,78 @@ PNM* Convolution::convolute(math::matrix mask, Mode mode = CyclicEdge) float blue_sum; float gray_sum; - - for (int x=0; xformat() == QImage::Format_Indexed8) + gray_window=getWindow(x,y,size,LChannel,mode); + else{ red_window=getWindow(x,y,size,RChannel,mode); blue_window=getWindow(x,y,size,BChannel,mode); green_window=getWindow(x,y,size,GChannel,mode); - //gray_window=getWindow(x,y,size,LChannel,mode); - + } + if (image->format() == QImage::Format_Indexed8){ + gray_window=join(gray_window,mask); + }else{ red_window=join(red_window,mask); blue_window=join(blue_window,mask); green_window=join(green_window,mask); - //gray_window=join(gray_window,mask); - - red_sum=sum(red_window); - green_sum=sum(green_window); - blue_sum=sum(blue_window); - //gray_sum=sum(gray_window); + } - if(mask_weight>0) - { - red_sum=red_sum/mask_weight; - blue_sum=blue_sum/mask_weight; - green_sum=green_sum/mask_weight; - //gray_sum=gray_sum/mask_weight; - } - - - - - if(red_sum>=0 && red_sum<=255 && green_sum>=0 && green_sum<=255 && blue_sum>=0 && blue_sum<=255) - { - newImage->setPixel(x,y, QColor(red_sum,green_sum,blue_sum).rgb()); - } - else if (red_sum>=0 && red_sum<=255 && green_sum>=0 && green_sum<=255) - { - int old_blue = qBlue(newImage->pixel(x,y)); - newImage->setPixel(x,y, QColor(red_sum,green_sum,old_blue).rgb()); - } - else if (blue_sum>=0 && blue_sum<=255 && green_sum>=0 && green_sum<=255) - { - int old_red = qRed(newImage->pixel(x,y)); - newImage->setPixel(x,y, QColor(old_red,green_sum,blue_sum).rgb()); - } - else if (blue_sum>=0 && blue_sum<=255 && red_sum>=0 && red_sum<=255) - { - int old_green = qGreen(newImage->pixel(x,y)); - newImage->setPixel(x,y, QColor(red_sum,old_green,blue_sum).rgb()); - } - + if (image->format() == QImage::Format_Indexed8){ + gray_sum=sum(gray_window); + }else{ + red_sum=sum(red_window); + green_sum=sum(green_window); + blue_sum=sum(blue_window); } + if(mask_weight>0) + { + + if (image->format() == QImage::Format_Indexed8){ + gray_sum=gray_sum/mask_weight; + } + else{ + red_sum=red_sum/mask_weight; + blue_sum=blue_sum/mask_weight; + green_sum=green_sum/mask_weight; + + } + } + + + if (image->format() == QImage::Format_Indexed8) { + newImage->setPixel(x, y, validateValue(gray_sum)); + } + else { + newImage->setPixel(x,y, QColor(validateValue(red_sum),validateValue(green_sum),validateValue(blue_sum)).rgb()); + } + + } return newImage; } +int Convolution::validateValue(int value){ + + if (value > 255) { + return 255; + } + else if (value < 0) { + return 0; + } + + return value; +} + /** Joins to matrices by multiplying the A[i,j] with B[i,j]. * Warning! Both Matrices must be squares with the same size! */ @@ -141,18 +150,15 @@ const float Convolution::sum(const math::matrix A) { float sum = 0.0; - int size=A.rowno(); - for (int x=0; x Convolution::reflection(const math::matrix A) int counter_j=0; - for (int x=size-1; x>=0; x--) - { - for (int y=size-1; y>=0; y--) - { - C[x][y]=A[counter_i][counter_j]; - counter_j++; - } - counter_i++; - } + for (int x = 0; x < size; x++) + { + for (int y = 0; y < size; y++) + { + C(size - x, size - y) = A(x, y); + } + } return C; -} \ No newline at end of file +} diff --git a/src/core/transformations/convolution.h b/src/core/transformations/convolution.h index f7f1994..3afa6f6 100644 --- a/src/core/transformations/convolution.h +++ b/src/core/transformations/convolution.h @@ -18,6 +18,7 @@ protected: const math::matrix join(math::matrix, math::matrix); const float sum(math::matrix); const math::matrix reflection(math::matrix); + int validateValue(int); }; #endif // CONVOLUTION_H diff --git a/src/core/transformations/edge_canny.cpp b/src/core/transformations/edge_canny.cpp index b52129f..cfe8c57 100644 --- a/src/core/transformations/edge_canny.cpp +++ b/src/core/transformations/edge_canny.cpp @@ -23,8 +23,192 @@ PNM* EdgeCanny::transform() lower_thresh = getParameter("lower_threshold").toInt(); PNM* newImage = new PNM(width, height, QImage::Format_Grayscale8); + QPoint point_vector[7] = { + QPoint(-1, 0), + QPoint(-1, 1), + QPoint(0, -1), + QPoint(0, 1), + QPoint(1, -1), + QPoint(1, 0), + QPoint(1, 1), + }; - qDebug() << Q_FUNC_INFO << "Not implemented yet!"; + // step 1 + PNM* tmpImage = new PNM(width, height, QImage::Format_Indexed8); + tmpImage = ConversionGrayscale(image).transform(); + // step 2 + BlurGaussian gaus(tmpImage); + gaus.setParameter("sigma", 1.6); + gaus.setParameter("size", 3); + tmpImage = gaus.transform(); + // step 3 + EdgeSobel sobel(tmpImage); + math::matrix* Gx = sobel.rawHorizontalDetection(); + math::matrix* Gy = sobel.rawVerticalDetection(); + //step 4 + math::matrix direction = math::matrix(width, height); + math::matrix power = math::matrix(width, height); + for (int i = 0; i < width; i++) + { + for (int j = 0; j < height; j++) + { + newImage->setPixel(i, j, PIXEL_VAL_MIN); + power(i, j) = sqrt(pow((*Gx)(i, j), 2) + pow((*Gy)(i, j), 2)); + direction(i, j) = (int)((atan2 ((*Gy)(i, j), (*Gx)(i, j)) / (3.142)) * 180 + 360) % 360; + } + } + + //step 5 + std::list initialPoints; + for (int i = 1; i < width - 1; i++) + { + for (int j = 1; j < height - 1; j++) + { + + int pos = direction(i, j); + + QPoint point1; + QPoint point2; + + if (getOrient(pos) == 0) + { + point1 = QPoint(0, -1); + point2 = QPoint(0, 1); + } + else if (getOrient(pos) == 1) + { + point1 = QPoint(1, -1); + point2 = QPoint(-1, 1); + } + else if (getOrient(pos) == 2) + { + point1 = QPoint(-1, 0); + point2 = QPoint(1, 0); + } + else if (getOrient(pos) == 3) + { + point1 = QPoint(-1, -1); + point2 = QPoint(1, 1); + } + + double temp1 = power(i + point1.x(), j + point1.y()); + double temp2= power(i + point2.x(), j + point2.y()); + + if (power(i, j) > temp1 && power(i, j) > temp2 &&power(i, j) > upper_thresh) + { + newImage->setPixel(i, j, PIXEL_VAL_MAX); + initialPoints.push_back(QPoint(i, j)); + } + } + } + + //step 6 + while (!initialPoints.empty()) + { + QPoint point = initialPoints.back(); + initialPoints.pop_back(); + int pos = direction(point.x(), point.y()); + + for (int i = 1; i <= 2; i++) + { + int x,y; + + if ( i == 1) + { + if (getOrient(pos) == 0) + { + x= 0; + y= -1; + + } + else if (getOrient(pos) == 1) + { + x= 1; + y= -1; + } + else if (getOrient(pos) == 2) + { + x= -1; + y= 1; + } + else if (getOrient(pos) == 3) + { + x= -1; + y= -1; + } + } + else + { + if (getOrient(pos) == 0) + { + x= 0; + y= 1; + } + else if (getOrient(pos) == 1) + { + x= -1; + y= 1; + } + else if (getOrient(pos) == 2) + { + x= 1; + y= 0; + } + else if (getOrient(pos) == 3) + { + x= 1; + y= 1; + } + } + QPoint cPoint = point; + while (true) + { + QPoint point_ = QPoint(cPoint.x() + x, cPoint.y() + y); + if (point_.x() == width - 1 || point_.x() == 0 || point_.y() == height - 1 || point_.y() == 0) break; + if (newImage->pixel(point_.x(), point_.y()) == PIXEL_VAL_MAX) break; + if (power(point_.x(), point_.y()) < lower_thresh) break; + if (getOrient((int)direction(point_.x(), point_.y())) != getOrient(pos)) break; + bool flag = true; + + for (int i = 0; i < 7; i++) + { + QPoint point(point_.x() + point_vector[i].x(), point_.y() + point_vector[i].y()); + if (point.x() == cPoint.x() && point.y() == cPoint.y()) continue; + if (getOrient((int)direction(point.x(), point.y())) != getOrient(pos)) continue; + + if (power(point.x(), point.y()) >= power(point_.x(), point_.y())) + { + flag= false; + break; + } + } + if (!flag) break; + newImage->setPixel(point_.x(), point_.y(), PIXEL_VAL_MAX); + cPoint = point_; + } + } + } return newImage; } + + +int EdgeCanny::getOrient(int currentDirection){ + if ((currentDirection >= 0 && currentDirection < 23) || (currentDirection >= 158 && currentDirection < 203) || (currentDirection >= 338 && currentDirection < 361)) + { + return 0; + } + if ((currentDirection >= 23 && currentDirection < 68) || (currentDirection >= 203 && currentDirection < 248)) + { + return 1; + } + if ((currentDirection >= 68 && currentDirection < 113) || (currentDirection >= 248 && currentDirection < 293)) + { + return 2; + } + if ((currentDirection >= 113 && currentDirection < 158) || (currentDirection >= 293 && currentDirection < 338)) + { + return 3; + } + return -1; +} diff --git a/src/core/transformations/edge_canny.h b/src/core/transformations/edge_canny.h index 9bf344d..8d4ad1a 100644 --- a/src/core/transformations/edge_canny.h +++ b/src/core/transformations/edge_canny.h @@ -8,12 +8,14 @@ class EdgeCanny : public Convolution public: EdgeCanny(PNM*); EdgeCanny(PNM*, ImageViewer*); + int getOrient(int); virtual PNM* transform(); private: + }; #endif // EDGECANNY_H diff --git a/src/core/transformations/edge_sobel.cpp b/src/core/transformations/edge_sobel.cpp index d99a057..681c9e0 100644 --- a/src/core/transformations/edge_sobel.cpp +++ b/src/core/transformations/edge_sobel.cpp @@ -47,7 +47,15 @@ math::matrix* EdgeSobel::rawHorizontalDetection() { math::matrix* x_gradient = new math::matrix(this->image->width(), this->image->height()); - qDebug() << Q_FUNC_INFO << "Not implemented yet!"; + for (int x = 0; x < this->image->width(); x++) + { + for (int y = 0; y < this->image->height(); y++) + { + math::matrix temp = getWindow(x, y, 3, LChannel, NullEdge); + x_gradient[x][y] = Convolution::sum(Convolution::join(g_x, temp)); + + } + } return x_gradient; } @@ -56,7 +64,15 @@ math::matrix* EdgeSobel::rawVerticalDetection() { math::matrix* y_gradient = new math::matrix(this->image->width(), this->image->height()); - qDebug() << Q_FUNC_INFO << "Not implemented yet!"; + for (int x = 0; x < this->image->width(); x++) + { + for (int y = 0; y < this->image->height(); y++) + { + math::matrix temp = getWindow(x, y, 3, LChannel, NullEdge); + y_gradient[x][y] = Convolution::sum(Convolution::join(g_y, temp)); + + } + } return y_gradient; }