1
0
lpo-image-processing/13/do_sprawdzenia/cpp/hough_rectangles.cpp
2021-05-20 19:39:32 +02:00

196 lines
5.8 KiB
C++

#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;
}