diff --git a/13/do_sprawdzenia/cpp/corner_harris.cpp b/13/do_sprawdzenia/cpp/corner_harris.cpp new file mode 100644 index 0000000..53c25db --- /dev/null +++ b/13/do_sprawdzenia/cpp/corner_harris.cpp @@ -0,0 +1,162 @@ +#include "corner_harris.h" + +#include "blur_gaussian.h" +#include "conversion_grayscale.h" +#include "edge_sobel.h" +#include + +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); + + this->corner_candidates = new math::matrix(width, height); + this->corner_nonmax_suppress = new math::matrix(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, 0); + } + else + { + // std::cout << "White corner" << std::endl; + newImage->setPixel(i, j, 1); + } + } + } + return newImage; +} + + diff --git a/13/do_sprawdzenia/cpp/hough_lines.cpp b/13/do_sprawdzenia/cpp/hough_lines.cpp new file mode 100644 index 0000000..cec7e58 --- /dev/null +++ b/13/do_sprawdzenia/cpp/hough_lines.cpp @@ -0,0 +1,87 @@ +#include "hough_lines.h" +#include "bin_gradient.h" +#include "edge_laplacian.h" + +#include "hough.h" +#include +#include +#include + +HoughLines::HoughLines(PNM* img) : + Transformation(img) +{ +} + +HoughLines::HoughLines(PNM* img, ImageViewer* iv) : + Transformation(img, iv) +{ +} + + +PNM* HoughLines::transform() +{ + + // Cut of value from the image; + int threshold = getParameter("threshold").toInt(); + bool drawWholeLines = getParameter("draw_whole_lines").toBool(); + int theta_density = 3; + + PNM* newImage = new PNM(image->copy()); + + EdgeLaplacian el(image); + el.setParameter("size", 3); + PNM* image_edge = el.transform(); + + PNM* image_bin = BinarizationGradient(image_edge).transform(); + + Hough h(image_edge); + + h.setParameter("theta_density", theta_density); + h.setParameter("skip_edge_detection", true); + PNM* image_hough = h.transform(); + + int hough_width = image_hough->width(); + int hough_height = image_hough->height(); + + int width = image_bin->width(); + int height = image_bin->height(); + + qPainter = new QPainter(newImage); + qPainter->setPen(Qt::black); + + for (int theta = 0; theta < hough_width; theta++) + { + for (int rho = 0; rho < hough_height; rho++) + { + int val = (int) qGray(image_hough->pixel(theta, rho)); + if (val > threshold) + { + double rtheta = ((double)theta / 3.0) * M_PI / 180.0; + int rrho = rho - hough_height / 2; + qPainter->drawLine(0, round(rrho / sin(rtheta)), width - 1, round((rrho - (width - 1) * cos(rtheta)) / sin(rtheta))); + + } + } + } + + int counter_pixels = 0; + if (!drawWholeLines) + { + for (int x = 0; x < width; x++) + { + for (int y = 0; y < height; y++) + { + QRgb pixel = image_bin->pixel(x, y); + + if (qGray(pixel) == 0) + { + counter_pixels++; + newImage->setPixel(x, y, image->pixel(x, y)); + } + } + } + std::cout << "counter " << counter_pixels << std::endl; + } + + return newImage; +} diff --git a/13/do_sprawdzenia/cpp/hough_lines.h b/13/do_sprawdzenia/cpp/hough_lines.h new file mode 100644 index 0000000..fd4e20f --- /dev/null +++ b/13/do_sprawdzenia/cpp/hough_lines.h @@ -0,0 +1,15 @@ +#ifndef HOUGH_LINES_H +#define HOUGH_LINES_H + +#include "transformation.h" + +class HoughLines : public Transformation +{ +public: + explicit HoughLines(PNM*); + explicit HoughLines(PNM*, ImageViewer*); + QPainter* qPainter; + virtual PNM* transform(); +}; + +#endif // HOUGH_LINES_H diff --git a/13/do_sprawdzenia/cpp/hough_rectangles.cpp b/13/do_sprawdzenia/cpp/hough_rectangles.cpp new file mode 100644 index 0000000..c09bc24 --- /dev/null +++ b/13/do_sprawdzenia/cpp/hough_rectangles.cpp @@ -0,0 +1,195 @@ +#include "hough_rectangles.h" + +#include "corner_harris.h" +#include "hough_lines.h" + +#include +#include + +struct RightAngle { + QPoint middle; + QPoint a; + QPoint b; + + inline bool operator==(RightAngle r) { + if (r.middle.x() == middle.x() && r.middle.y() == middle.y() && + ((r.a.x()==a.x() && r.a.y()== a.y() && r.b.x() == b.x() && r.b.y() == b.y()) || + (r.a.x()==b.x() && r.a.y()== b.y() && r.b.x() == a.x() && r.b.y() == a.y()))) + return true; + else + return false; + } +} ; + +struct Rectangle { + QPoint a; + QPoint b; + QPoint c; + QPoint d; +} ; + + +HoughRectangles::HoughRectangles(PNM* img) : + Transformation(img) +{ +} + +HoughRectangles::HoughRectangles(PNM* img, ImageViewer* iv) : + Transformation(img, iv) +{ +} + +PNM* HoughRectangles::transform() +{ + int width = image->width(); + int height = image->height(); + + PNM* newImage = new PNM(image->copy()); + + CornerHarris* cornerHarris = new CornerHarris(image); + cornerHarris->setParameter("threshold", 30000000); + cornerHarris->setParameter("sigma", 1.00), + cornerHarris->setParameter("sigma_weight", 0.78), + cornerHarris->setParameter("k", 0.0500); + PNM* cornersImage = cornerHarris->transform(); + + HoughLines* houghLines = new HoughLines(image); + + houghLines->setParameter("threshold", 15); + houghLines->setParameter("draw_whole_lines", true); + PNM* linesImage = houghLines->transform(); + + QPainter* qPainter = new QPainter(newImage); + QPen* pen = new QPen(Qt::black); + pen->setWidth(3); + qPainter->setPen(*pen); + + QMap cl; //corners on lines + + //look for corners on lines + int position = 0; + for (int i = 0; i < width; i++) + { + for (int j = 0; j < height; j++) + { + if (QColor::fromRgb(cornersImage->pixel(i,j)) == Qt::color0) + { + if (QColor::fromRgb(linesImage->pixel(i,j)) == Qt::color1) + { + cl.insert(position, QPoint(i,j)); + position++; + } + } + } + } + + int s = cl.size(); + int points[s][s][s]; + + QList rightAngles; + + //look for 90 degree angles + int count= 0; + for (int a = 0; a < s; a++) + { + for (int b = 0; b < s; b++) + { + for (int c = 0; c < s; c++) + { + if (a == b || a == c || b == c) + { + points[a][b][c] = -1; + } + else + { + double s1 = (cl[b].x() - cl[a].x()); + double s2 = (cl[b].x() - cl[c].x()); + double s3 = (cl[b].y() - cl[a].y()); + double s4 = (cl[b].y() - cl[c].y()); + + if (s1*s2 + s3*s4 > -50 && s1*s2 + s3*s4 < 50) + { + points[a][b][c] = 1; + RightAngle ra; + ra.a = cl[a]; + ra.middle = cl[b]; + ra.b = cl[c]; + rightAngles.push_back(ra); + count++; + } + else + { + points[a][b][c] = 0; + } + } + } + } + } + + QList rectangles; + + + //match rectangles + for (QList::iterator r = rightAngles.begin(); r != rightAngles.end(); r++) + { + bool found = false; + QPoint newPoint1; + + for (QList::iterator r1 = rightAngles.begin(); r1!=rightAngles.end(); r1++) + { + if ((*r1).middle.x() == (*r).a.x() && (*r1).middle.y() == (*r).a.y() && + (((*r1).a.x() == (*r).middle.x() && (*r1).a.y() == (*r).middle.y()) || + ((*r1).b.x() == (*r).middle.x() && (*r1).b.y() == (*r).middle.y()))) + { + newPoint1 = ((*r1).a.x() == (*r).middle.x()&& (*r1).a.y() == (*r).middle.y() ? (*r1).b : (*r1).a); + + QPoint newPoint2; + for (QList::iterator r2 = rightAngles.begin(); r2!=rightAngles.end();r2++) + { + if ((*r2).middle.x() == (*r).b.x() && (*r2).middle.y() == (*r).b.y() && + (((*r2).a.x() == (*r).middle.x() && (*r2).a.y() == (*r).middle.y()) || + ((*r2).b.x() == (*r).middle.x() && (*r2).b.y() == (*r).middle.y()))) + { + newPoint2 = (((*r2).a.x() == (*r).middle.x() && (*r2).a.y() == (*r).middle.y()) ? (*r2).b : (*r2).a); + + if (newPoint1.x() == newPoint2.x() && newPoint1.y() == newPoint2.y()) + { + Rectangle rect; + rect.a = (*r).a; + rect.b = (*r).middle; + rect.c = (*r).b; + rect.d = newPoint1; + rectangles.push_back(rect); + + rightAngles.removeAll(*r); + rightAngles.removeAll(*r1); + rightAngles.removeAll(*r2); + + found = true; + break; + } + } + if (found) + { + break; + } + } + } + if (found) + break; + } + } + + for (QList::iterator rect = rectangles.begin(); rect != rectangles.end(); rect++) + { + qPainter->drawLine((*rect).a, (*rect).b); + qPainter->drawLine((*rect).b, (*rect).c); + qPainter->drawLine((*rect).c, (*rect).d); + qPainter->drawLine((*rect).d, (*rect).a); + } + + return newImage; +} + + + diff --git a/13/do_sprawdzenia/cpp/image_1.png b/13/do_sprawdzenia/cpp/image_1.png new file mode 100644 index 0000000..768ea83 Binary files /dev/null and b/13/do_sprawdzenia/cpp/image_1.png differ diff --git a/app/cpp/mysimplegimp/src/core/transformations/corner_harris.cpp b/app/cpp/mysimplegimp/src/core/transformations/corner_harris.cpp index ec7e944..53c25db 100644 --- a/app/cpp/mysimplegimp/src/core/transformations/corner_harris.cpp +++ b/app/cpp/mysimplegimp/src/core/transformations/corner_harris.cpp @@ -25,7 +25,7 @@ PNM* CornerHarris::transform() int width = image->width(); int height = image->height(); - PNM* newImage = new PNM(width, height, QImage::Format_Grayscale8); + PNM* newImage = new PNM(width, height, QImage::Format_Mono); math::matrix Ixx(width, height); math::matrix Iyy(width, height); @@ -147,12 +147,12 @@ PNM* CornerHarris::transform() if ((*corner_candidates)[i][j] == 0) { - newImage->setPixel(i, j, QColor(0, 0, 0).rgb()); + newImage->setPixel(i, j, 0); } else { // std::cout << "White corner" << std::endl; - newImage->setPixel(i, j, QColor(255, 255, 255).rgb()); + newImage->setPixel(i, j, 1); } } } diff --git a/app/cpp/mysimplegimp/src/core/transformations/hough_lines.cpp b/app/cpp/mysimplegimp/src/core/transformations/hough_lines.cpp index df6001b..cec7e58 100644 --- a/app/cpp/mysimplegimp/src/core/transformations/hough_lines.cpp +++ b/app/cpp/mysimplegimp/src/core/transformations/hough_lines.cpp @@ -18,10 +18,6 @@ HoughLines::HoughLines(PNM* img, ImageViewer* iv) : } - - - - PNM* HoughLines::transform() { @@ -50,8 +46,8 @@ PNM* HoughLines::transform() int width = image_bin->width(); int height = image_bin->height(); - QPainter qPainter (newImage); - qPainter.setPen(Qt::yellow); + qPainter = new QPainter(newImage); + qPainter->setPen(Qt::black); for (int theta = 0; theta < hough_width; theta++) { @@ -62,7 +58,7 @@ PNM* HoughLines::transform() { double rtheta = ((double)theta / 3.0) * M_PI / 180.0; int rrho = rho - hough_height / 2; - qPainter.drawLine(0, round(rrho / sin(rtheta)), width - 1, round((rrho - (width - 1) * cos(rtheta)) / sin(rtheta))); + qPainter->drawLine(0, round(rrho / sin(rtheta)), width - 1, round((rrho - (width - 1) * cos(rtheta)) / sin(rtheta))); } } diff --git a/app/cpp/mysimplegimp/src/core/transformations/hough_lines.h b/app/cpp/mysimplegimp/src/core/transformations/hough_lines.h index 6569e3d..fd4e20f 100644 --- a/app/cpp/mysimplegimp/src/core/transformations/hough_lines.h +++ b/app/cpp/mysimplegimp/src/core/transformations/hough_lines.h @@ -8,7 +8,7 @@ class HoughLines : public Transformation public: explicit HoughLines(PNM*); explicit HoughLines(PNM*, ImageViewer*); - + QPainter* qPainter; virtual PNM* transform(); }; diff --git a/app/cpp/mysimplegimp/src/core/transformations/hough_rectangles.cpp b/app/cpp/mysimplegimp/src/core/transformations/hough_rectangles.cpp index c0bbbc1..c09bc24 100644 --- a/app/cpp/mysimplegimp/src/core/transformations/hough_rectangles.cpp +++ b/app/cpp/mysimplegimp/src/core/transformations/hough_rectangles.cpp @@ -1,5 +1,34 @@ #include "hough_rectangles.h" +#include "corner_harris.h" +#include "hough_lines.h" + +#include +#include + +struct RightAngle { + QPoint middle; + QPoint a; + QPoint b; + + inline bool operator==(RightAngle r) { + if (r.middle.x() == middle.x() && r.middle.y() == middle.y() && + ((r.a.x()==a.x() && r.a.y()== a.y() && r.b.x() == b.x() && r.b.y() == b.y()) || + (r.a.x()==b.x() && r.a.y()== b.y() && r.b.x() == a.x() && r.b.y() == a.y()))) + return true; + else + return false; + } +} ; + +struct Rectangle { + QPoint a; + QPoint b; + QPoint c; + QPoint d; +} ; + + HoughRectangles::HoughRectangles(PNM* img) : Transformation(img) { @@ -12,8 +41,155 @@ HoughRectangles::HoughRectangles(PNM* img, ImageViewer* iv) : PNM* HoughRectangles::transform() { - qDebug() << Q_FUNC_INFO << "Not implemented yet!"; + int width = image->width(); + int height = image->height(); - return 0; + PNM* newImage = new PNM(image->copy()); + + CornerHarris* cornerHarris = new CornerHarris(image); + cornerHarris->setParameter("threshold", 30000000); + cornerHarris->setParameter("sigma", 1.00), + cornerHarris->setParameter("sigma_weight", 0.78), + cornerHarris->setParameter("k", 0.0500); + PNM* cornersImage = cornerHarris->transform(); + + HoughLines* houghLines = new HoughLines(image); + + houghLines->setParameter("threshold", 15); + houghLines->setParameter("draw_whole_lines", true); + PNM* linesImage = houghLines->transform(); + + QPainter* qPainter = new QPainter(newImage); + QPen* pen = new QPen(Qt::black); + pen->setWidth(3); + qPainter->setPen(*pen); + + QMap cl; //corners on lines + + //look for corners on lines + int position = 0; + for (int i = 0; i < width; i++) + { + for (int j = 0; j < height; j++) + { + if (QColor::fromRgb(cornersImage->pixel(i,j)) == Qt::color0) + { + if (QColor::fromRgb(linesImage->pixel(i,j)) == Qt::color1) + { + cl.insert(position, QPoint(i,j)); + position++; + } + } + } + } + + int s = cl.size(); + int points[s][s][s]; + + QList rightAngles; + + //look for 90 degree angles + int count= 0; + for (int a = 0; a < s; a++) + { + for (int b = 0; b < s; b++) + { + for (int c = 0; c < s; c++) + { + if (a == b || a == c || b == c) + { + points[a][b][c] = -1; + } + else + { + double s1 = (cl[b].x() - cl[a].x()); + double s2 = (cl[b].x() - cl[c].x()); + double s3 = (cl[b].y() - cl[a].y()); + double s4 = (cl[b].y() - cl[c].y()); + + if (s1*s2 + s3*s4 > -50 && s1*s2 + s3*s4 < 50) + { + points[a][b][c] = 1; + RightAngle ra; + ra.a = cl[a]; + ra.middle = cl[b]; + ra.b = cl[c]; + rightAngles.push_back(ra); + count++; + } + else + { + points[a][b][c] = 0; + } + } + } + } + } + + QList rectangles; + + + //match rectangles + for (QList::iterator r = rightAngles.begin(); r != rightAngles.end(); r++) + { + bool found = false; + QPoint newPoint1; + + for (QList::iterator r1 = rightAngles.begin(); r1!=rightAngles.end(); r1++) + { + if ((*r1).middle.x() == (*r).a.x() && (*r1).middle.y() == (*r).a.y() && + (((*r1).a.x() == (*r).middle.x() && (*r1).a.y() == (*r).middle.y()) || + ((*r1).b.x() == (*r).middle.x() && (*r1).b.y() == (*r).middle.y()))) + { + newPoint1 = ((*r1).a.x() == (*r).middle.x()&& (*r1).a.y() == (*r).middle.y() ? (*r1).b : (*r1).a); + + QPoint newPoint2; + for (QList::iterator r2 = rightAngles.begin(); r2!=rightAngles.end();r2++) + { + if ((*r2).middle.x() == (*r).b.x() && (*r2).middle.y() == (*r).b.y() && + (((*r2).a.x() == (*r).middle.x() && (*r2).a.y() == (*r).middle.y()) || + ((*r2).b.x() == (*r).middle.x() && (*r2).b.y() == (*r).middle.y()))) + { + newPoint2 = (((*r2).a.x() == (*r).middle.x() && (*r2).a.y() == (*r).middle.y()) ? (*r2).b : (*r2).a); + + if (newPoint1.x() == newPoint2.x() && newPoint1.y() == newPoint2.y()) + { + Rectangle rect; + rect.a = (*r).a; + rect.b = (*r).middle; + rect.c = (*r).b; + rect.d = newPoint1; + rectangles.push_back(rect); + + rightAngles.removeAll(*r); + rightAngles.removeAll(*r1); + rightAngles.removeAll(*r2); + + found = true; + break; + } + } + if (found) + { + break; + } + } + } + if (found) + break; + } + } + + for (QList::iterator rect = rectangles.begin(); rect != rectangles.end(); rect++) + { + qPainter->drawLine((*rect).a, (*rect).b); + qPainter->drawLine((*rect).b, (*rect).c); + qPainter->drawLine((*rect).c, (*rect).d); + qPainter->drawLine((*rect).d, (*rect).a); + } + + return newImage; } + +