2016-01-06 17:36:04 +01:00
|
|
|
#ifndef HOUGH_MACHINE_C
|
|
|
|
#define HOUGH_MACHINE_C
|
|
|
|
|
|
|
|
#include <QtGlobal>
|
|
|
|
#include <QMainWindow>
|
|
|
|
#include <QColor>
|
|
|
|
|
|
|
|
#include <iostream>
|
|
|
|
|
|
|
|
#include <math.h>
|
|
|
|
|
2016-01-06 18:30:00 +01:00
|
|
|
#include "lazy_image.cpp"
|
|
|
|
|
2016-01-06 17:36:04 +01:00
|
|
|
class HoughMachine {
|
|
|
|
|
|
|
|
private:
|
2016-01-06 18:30:00 +01:00
|
|
|
LazyImage* original;
|
|
|
|
LazyImage* working_copy;
|
2016-01-06 17:36:04 +01:00
|
|
|
|
2016-01-06 18:30:00 +01:00
|
|
|
int x_center;
|
|
|
|
int y_center;
|
|
|
|
int n_ang;
|
|
|
|
double d_ang;
|
|
|
|
int n_rad;
|
|
|
|
double d_rad;
|
|
|
|
int* hough_arr;
|
2016-01-07 18:45:22 +01:00
|
|
|
|
|
|
|
int matching_threshold;
|
2016-01-06 17:36:04 +01:00
|
|
|
|
|
|
|
public:
|
2016-01-06 18:30:00 +01:00
|
|
|
HoughMachine(LazyImage* original, LazyImage* working_copy) {
|
|
|
|
this->original = original;
|
|
|
|
this->working_copy = working_copy;
|
|
|
|
this->hough_arr = NULL;
|
2016-01-06 17:36:04 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
~HoughMachine() {
|
2016-01-06 18:30:00 +01:00
|
|
|
this->reset();
|
|
|
|
};
|
|
|
|
|
|
|
|
void reset(void) {
|
|
|
|
this->x_center = 0;
|
|
|
|
this->y_center = 0;
|
|
|
|
this->n_ang = 0;
|
|
|
|
this->d_ang = 0;
|
|
|
|
this->n_rad = 0;
|
|
|
|
this->d_rad = 0;
|
2016-01-07 09:45:52 +01:00
|
|
|
if(this->hough_arr != NULL) {
|
2016-01-06 18:30:00 +01:00
|
|
|
free(this->hough_arr);
|
|
|
|
this->hough_arr = NULL;
|
|
|
|
}
|
2016-01-07 18:45:22 +01:00
|
|
|
this->matching_threshold = 0;
|
|
|
|
};
|
|
|
|
|
|
|
|
void setMatchingThreshold(int matching_threshold) {
|
|
|
|
// If negative, pixels greater than the absolute value match.
|
|
|
|
// If positive, pixels less than the absolute value match.
|
|
|
|
this->matching_threshold = matching_threshold;
|
2016-01-06 17:36:04 +01:00
|
|
|
};
|
|
|
|
|
2016-01-06 18:30:00 +01:00
|
|
|
void run(int a_steps, int r_steps) {
|
|
|
|
this->x_center = this->original->width()/2;
|
|
|
|
this->y_center = this->original->height()/2;
|
|
|
|
this->n_ang = a_steps;
|
|
|
|
this->d_ang = M_PI / this->n_ang;
|
|
|
|
this->n_rad = r_steps;
|
|
|
|
double r_max = sqrt(pow(this->x_center, 2) + pow(this->y_center, 2));
|
|
|
|
this->d_rad = (2*r_max)/this->n_rad;
|
|
|
|
this->hough_arr = (int*) malloc(sizeof(int) * this->n_ang * this->n_rad);
|
|
|
|
for(int i=0; i< this->n_ang*this->n_rad; i++) this->hough_arr[i] = 0;
|
2016-01-07 18:38:36 +01:00
|
|
|
std::cout << "Hough params: x_center: " << this->x_center << ", y_center: " << this->y_center << std::endl;
|
|
|
|
std::cout << "n_ang: " << this->n_ang << ", d_ang: " << this->d_ang << std::endl;
|
|
|
|
std::cout << "n_rad: " << this->n_rad << ", d_rad: " << this->d_rad << ", r_max: " << r_max << std::endl;
|
2016-01-06 18:30:00 +01:00
|
|
|
this->fillHoughAccumulator();
|
|
|
|
this->debugShow();
|
|
|
|
};
|
|
|
|
|
|
|
|
void fillHoughAccumulator() {
|
|
|
|
for(int v=0; v<this->original->height(); v++) {
|
|
|
|
for(int u=0; u<this->original->width(); u++) {
|
|
|
|
QColor pixel = QColor::fromRgb(this->original->getPixel(u, v, LazyImage::DEFAULT));
|
|
|
|
int h, s, l;
|
|
|
|
pixel.getHsl(&h, &s, &l);
|
2016-01-07 18:45:22 +01:00
|
|
|
if(this->matching_threshold > 0) {
|
|
|
|
int threshold = this->matching_threshold;
|
2016-01-07 18:57:26 +01:00
|
|
|
std::cout << "Comparing " << l << " < " << threshold << std::endl;
|
2016-01-07 18:45:22 +01:00
|
|
|
if(l < threshold) this->doPixel(u, v);
|
|
|
|
} else {
|
|
|
|
int threshold = -this->matching_threshold;
|
2016-01-07 18:57:26 +01:00
|
|
|
std::cout << "Comparing " << l << " > " << threshold << std::endl;
|
2016-01-07 18:45:22 +01:00
|
|
|
if(l > threshold) this->doPixel(u, v);
|
2016-01-06 18:30:00 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
void doPixel(int u, int v) {
|
|
|
|
int x = u - this->x_center;
|
|
|
|
int y = v - this->y_center;
|
|
|
|
for(int a=0; a<this->n_ang; a++) {
|
|
|
|
double theta = this->d_ang * a;
|
|
|
|
int r = (int) qRound( (x*cos(theta) + y*sin(theta)) / this->d_rad ) + this->n_rad / 2;
|
|
|
|
if(r >= 0 && r < this->n_rad) {
|
|
|
|
this->hough_arr[a*this->n_ang+r] += 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2016-01-07 18:45:22 +01:00
|
|
|
void drawLines(int n) {
|
|
|
|
// TODO: Sort stuff in hough_arr by value, get the n top values and draw them using bresenham.
|
|
|
|
|
|
|
|
};
|
|
|
|
|
2016-01-06 18:30:00 +01:00
|
|
|
void debugShow() {
|
|
|
|
std::cout << "Dimensions: " << this->n_ang << " x " << this->n_rad << " | " << std::endl;
|
|
|
|
|
|
|
|
int max_value = 0;
|
|
|
|
for(int i=0; i<this->n_ang*this->n_rad; i++) {
|
|
|
|
int current_value = this->hough_arr[i];
|
|
|
|
if(current_value > max_value) max_value = current_value;
|
|
|
|
}
|
|
|
|
|
|
|
|
for(int x=0; x<this->n_ang; x++) {
|
|
|
|
for(int y=0; y<this->n_rad; y++) {
|
|
|
|
int value = qRound(255.0*this->hough_arr[x*this->n_ang+y] / max_value);
|
|
|
|
if(value < 0) {
|
|
|
|
std::cout << value << std::endl;
|
|
|
|
value = 0;
|
|
|
|
}
|
|
|
|
if(value > 255) {
|
|
|
|
std::cout << value << std::endl;
|
|
|
|
value = 255;
|
|
|
|
}
|
|
|
|
int color = QColor::fromRgb(value, value, value).rgb();
|
|
|
|
this->working_copy->getImage()->setPixel(x,y,color);
|
|
|
|
}
|
|
|
|
}
|
2016-01-06 17:36:04 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
#endif
|