Zadanie 13
This commit is contained in:
parent
be58a899a8
commit
f6bbf14157
162
13/do_sprawdzenia/cpp/corner_harris.cpp
Normal file
162
13/do_sprawdzenia/cpp/corner_harris.cpp
Normal file
@ -0,0 +1,162 @@
|
|||||||
|
#include "corner_harris.h"
|
||||||
|
|
||||||
|
#include "blur_gaussian.h"
|
||||||
|
#include "conversion_grayscale.h"
|
||||||
|
#include "edge_sobel.h"
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
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<float> Ixx(width, height);
|
||||||
|
math::matrix<float> Iyy(width, height);
|
||||||
|
math::matrix<float> Ixy(width, height);
|
||||||
|
|
||||||
|
this->corner_candidates = new math::matrix<float>(width, height);
|
||||||
|
this->corner_nonmax_suppress = new math::matrix<float>(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<float>* Gx = edge_sobel->rawHorizontalDetection();
|
||||||
|
math::matrix<float>* 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<float> 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 <height - 1; j++)
|
||||||
|
{
|
||||||
|
float max = (*corner_candidates)[i][j];
|
||||||
|
|
||||||
|
for (int k = -1; k <= 1; k++)
|
||||||
|
{
|
||||||
|
for (int l = -1; l <= 1; l++)
|
||||||
|
{
|
||||||
|
if (max < (*corner_candidates)[i+k][j+l])
|
||||||
|
{
|
||||||
|
max = (*corner_candidates)[i+k][j+l];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((*corner_candidates)[i][j] == max)
|
||||||
|
{
|
||||||
|
(*corner_nonmax_suppress)[i][j] = (*corner_candidates)[i][j];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ((*corner_candidates)[i][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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
87
13/do_sprawdzenia/cpp/hough_lines.cpp
Normal file
87
13/do_sprawdzenia/cpp/hough_lines.cpp
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
#include "hough_lines.h"
|
||||||
|
#include "bin_gradient.h"
|
||||||
|
#include "edge_laplacian.h"
|
||||||
|
|
||||||
|
#include "hough.h"
|
||||||
|
#include <iostream>
|
||||||
|
#include <Qt>
|
||||||
|
#include <QPainter>
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
15
13/do_sprawdzenia/cpp/hough_lines.h
Normal file
15
13/do_sprawdzenia/cpp/hough_lines.h
Normal file
@ -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
|
195
13/do_sprawdzenia/cpp/hough_rectangles.cpp
Normal file
195
13/do_sprawdzenia/cpp/hough_rectangles.cpp
Normal file
@ -0,0 +1,195 @@
|
|||||||
|
#include "hough_rectangles.h"
|
||||||
|
|
||||||
|
#include "corner_harris.h"
|
||||||
|
#include "hough_lines.h"
|
||||||
|
|
||||||
|
#include <QLine>
|
||||||
|
#include <QPainter>
|
||||||
|
|
||||||
|
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<int, QPoint> 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<RightAngle> 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<Rectangle> rectangles;
|
||||||
|
|
||||||
|
|
||||||
|
//match rectangles
|
||||||
|
for (QList<RightAngle>::iterator r = rightAngles.begin(); r != rightAngles.end(); r++)
|
||||||
|
{
|
||||||
|
bool found = false;
|
||||||
|
QPoint newPoint1;
|
||||||
|
|
||||||
|
for (QList<RightAngle>::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<RightAngle>::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<Rectangle>::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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
BIN
13/do_sprawdzenia/cpp/image_1.png
Normal file
BIN
13/do_sprawdzenia/cpp/image_1.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 9.3 KiB |
@ -25,7 +25,7 @@ PNM* CornerHarris::transform()
|
|||||||
int width = image->width();
|
int width = image->width();
|
||||||
int height = image->height();
|
int height = image->height();
|
||||||
|
|
||||||
PNM* newImage = new PNM(width, height, QImage::Format_Grayscale8);
|
PNM* newImage = new PNM(width, height, QImage::Format_Mono);
|
||||||
|
|
||||||
math::matrix<float> Ixx(width, height);
|
math::matrix<float> Ixx(width, height);
|
||||||
math::matrix<float> Iyy(width, height);
|
math::matrix<float> Iyy(width, height);
|
||||||
@ -147,12 +147,12 @@ PNM* CornerHarris::transform()
|
|||||||
if ((*corner_candidates)[i][j] == 0)
|
if ((*corner_candidates)[i][j] == 0)
|
||||||
{
|
{
|
||||||
|
|
||||||
newImage->setPixel(i, j, QColor(0, 0, 0).rgb());
|
newImage->setPixel(i, j, 0);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// std::cout << "White corner" << std::endl;
|
// std::cout << "White corner" << std::endl;
|
||||||
newImage->setPixel(i, j, QColor(255, 255, 255).rgb());
|
newImage->setPixel(i, j, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,10 +18,6 @@ HoughLines::HoughLines(PNM* img, ImageViewer* iv) :
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
PNM* HoughLines::transform()
|
PNM* HoughLines::transform()
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -50,8 +46,8 @@ PNM* HoughLines::transform()
|
|||||||
int width = image_bin->width();
|
int width = image_bin->width();
|
||||||
int height = image_bin->height();
|
int height = image_bin->height();
|
||||||
|
|
||||||
QPainter qPainter (newImage);
|
qPainter = new QPainter(newImage);
|
||||||
qPainter.setPen(Qt::yellow);
|
qPainter->setPen(Qt::black);
|
||||||
|
|
||||||
for (int theta = 0; theta < hough_width; theta++)
|
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;
|
double rtheta = ((double)theta / 3.0) * M_PI / 180.0;
|
||||||
int rrho = rho - hough_height / 2;
|
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)));
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,7 @@ class HoughLines : public Transformation
|
|||||||
public:
|
public:
|
||||||
explicit HoughLines(PNM*);
|
explicit HoughLines(PNM*);
|
||||||
explicit HoughLines(PNM*, ImageViewer*);
|
explicit HoughLines(PNM*, ImageViewer*);
|
||||||
|
QPainter* qPainter;
|
||||||
virtual PNM* transform();
|
virtual PNM* transform();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,5 +1,34 @@
|
|||||||
#include "hough_rectangles.h"
|
#include "hough_rectangles.h"
|
||||||
|
|
||||||
|
#include "corner_harris.h"
|
||||||
|
#include "hough_lines.h"
|
||||||
|
|
||||||
|
#include <QLine>
|
||||||
|
#include <QPainter>
|
||||||
|
|
||||||
|
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) :
|
HoughRectangles::HoughRectangles(PNM* img) :
|
||||||
Transformation(img)
|
Transformation(img)
|
||||||
{
|
{
|
||||||
@ -12,8 +41,155 @@ HoughRectangles::HoughRectangles(PNM* img, ImageViewer* iv) :
|
|||||||
|
|
||||||
PNM* HoughRectangles::transform()
|
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<int, QPoint> 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<RightAngle> 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<Rectangle> rectangles;
|
||||||
|
|
||||||
|
|
||||||
|
//match rectangles
|
||||||
|
for (QList<RightAngle>::iterator r = rightAngles.begin(); r != rightAngles.end(); r++)
|
||||||
|
{
|
||||||
|
bool found = false;
|
||||||
|
QPoint newPoint1;
|
||||||
|
|
||||||
|
for (QList<RightAngle>::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<RightAngle>::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<Rectangle>::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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user