#ifndef CANNY_EDGE_MACHINE_C #define CANNY_EDGE_MACHINE_C #include #include #include #include #include #include "lazy_image.cpp" class CannyEdgeMachine { private: LazyImage* original; LazyImage* working_copy; int width; int height; int pixels; double* gradient_magnitude; double* maximum_magnitude; int* binary_edge_pixels; int* gradient_x; int* gradient_y; // Params double t_low; double t_high; public: CannyEdgeMachine(LazyImage* original, LazyImage* working_copy){ this->original = original; this->working_copy = working_copy; this->width = this->original->width(); this->height = this->original->height(); this->pixels = this->width * this->height; this->gradient_magnitude = (double*) malloc(sizeof(double) * this->pixels); this->maximum_magnitude = (double*) malloc(sizeof(double) * this->pixels); this->binary_edge_pixels = (int*) malloc(sizeof(int) * this->pixels); this->gradient_x = (int*) malloc(sizeof(int) * this->pixels); this->gradient_y = (int*) malloc(sizeof(int) * this->pixels); }; ~CannyEdgeMachine() { free(this->gradient_magnitude); free(this->maximum_magnitude); free(this->binary_edge_pixels); free(this->gradient_x); free(this->gradient_y); }; void setThresholdValues(double t_low, double t_high) { this->t_low = t_low; this->t_high = t_high; }; void reset(void) { for(int i=0; ipixels; i++) { this->gradient_magnitude = 0; this->maximum_magnitude = 0; this->binary_edge_pixels = 0; this->gradient_x = 0; this->gradient_y = 0; } }; void doGaussBlur(int filter_width=3) { // build the gauss filter int* filter = (int*) malloc(sizeof(int) * filter_width* filter_width); int sum_weights = 0; for(int i=0; iwidth-filter_offset); x++) { for(int y=(0+filter_offset); y<(this->height-filter_offset); y++) { int sum_intensity = 0; int h, s, l; for(int fx=0; fxoriginal->getPixel(x+dx, y+dy, LazyImage::DEFAULT)); color.getHsl(&h, &s, &l); sum_intensity += (l * filter[fy*filter_width + fx]); } } QColor color = QColor::fromRgb(this->original->getPixel(x, y, LazyImage::DEFAULT)); color.getHsl(&h, &s, &l); l = qRound((1.0*sum_intensity) / (1.0*sum_weights)); if(l > 255) l = 255; if(l < 0) l = 0; color.setHsl(h, s, l); this->working_copy->getImage()->setPixel(x, y, color.rgb()); } } free(filter); }; void doGradiants(void) { // build the gradiant vector int gradiant_size = 3; double* gradiant_vector = (double*) malloc(sizeof(double) * gradiant_size); gradiant_vector[0] = -0.5; gradiant_vector[1] = 0; gradiant_vector[2] = 0.5; int gradiant_offset = gradiant_size; // calculate gradiants for(int x=(0+gradiant_offset); x<(this->width-gradiant_offset); x++) { for(int y=(0+gradiant_offset); y<(this->height-gradiant_offset); y++) { int h, s, l; // x gradiant double sum_intensity = 0; for(int i=0; ioriginal->getPixel(x+dx, y, LazyImage::DEFAULT)); color.getHsl(&h, &s, &l); sum_intensity += l * gradiant_vector[i]; } this->gradient_x[y*width + x] = sum_intensity; // y gradiant double sum_intensity = 0; for(int i=0; ioriginal->getPixel(x, y+dy, LazyImage::DEFAULT)); color.getHsl(&h, &s, &l); sum_intensity += l * gradiant_vector[i]; } this->gradient_y[y*width + x] = sum_intensity; } } free(gradiant_vector); }; void work() { this->reset(); this->doGaussBlur(); this->doGradiants(); }; }; #endif