#ifndef HOUGH_MACHINE_C #define HOUGH_MACHINE_C #include #include #include #include #include #include "lazy_image.cpp" class HoughMachine { private: LazyImage* original; LazyImage* working_copy; int x_center; int y_center; int n_ang; double d_ang; int n_rad; double d_rad; int* hough_arr; int matching_threshold; public: HoughMachine(LazyImage* original, LazyImage* working_copy) { this->original = original; this->working_copy = working_copy; this->hough_arr = NULL; }; ~HoughMachine() { 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; if(this->hough_arr != NULL) { free(this->hough_arr); this->hough_arr = NULL; } 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; }; 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; 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; this->fillHoughAccumulator(); this->debugShow(); }; void fillHoughAccumulator() { for(int v=0; voriginal->height(); v++) { for(int u=0; uoriginal->width(); u++) { QColor pixel = QColor::fromRgb(this->original->getPixel(u, v, LazyImage::DEFAULT)); int h, s, l; pixel.getHsl(&h, &s, &l); if(this->matching_threshold > 0) { int threshold = this->matching_threshold; std::cout << "Comparing " << l << " < " << threshold << std::endl; if(l < threshold) this->doPixel(u, v); } else { int threshold = -this->matching_threshold; std::cout << "Comparing " << l << " > " << threshold << std::endl; if(l > threshold) this->doPixel(u, v); } } } }; void doPixel(int u, int v) { int x = u - this->x_center; int y = v - this->y_center; for(int a=0; an_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; } } }; void drawLines(int n) { // TODO: Sort stuff in hough_arr by value, get the n top values and draw them using bresenham. }; void debugShow() { std::cout << "Dimensions: " << this->n_ang << " x " << this->n_rad << " | " << std::endl; int max_value = 0; for(int i=0; in_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; xn_ang; x++) { for(int y=0; yn_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); } } }; }; #endif