1
0

Zadanie 13

This commit is contained in:
Jarosław Wieczorek 2021-05-20 19:39:32 +02:00
parent be58a899a8
commit f6bbf14157
9 changed files with 644 additions and 13 deletions

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

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

View 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

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.3 KiB

View File

@ -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);
} }
} }
} }

View File

@ -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)));
} }
} }

View File

@ -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();
}; };

View File

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