From 58953ada3ddf0b4f95145d0aac41608dab15cc8d Mon Sep 17 00:00:00 2001 From: Joanne Jabbour Date: Fri, 8 Dec 2023 23:47:57 +0100 Subject: [PATCH 1/2] auto --- src/edge_detection/hough.c | 261 +++++++++++++++++++++++++++++++++++++ 1 file changed, 261 insertions(+) diff --git a/src/edge_detection/hough.c b/src/edge_detection/hough.c index 4a168f0..e128dad 100644 --- a/src/edge_detection/hough.c +++ b/src/edge_detection/hough.c @@ -977,7 +977,268 @@ printf("t r %f,%f\n", s.bottomright.x, s.bottomright.y); } } +///AUTOMATIC ROTATION + +//HOUGH +struct DetectedLines auto_performHoughTransform(SDL_Surface *surface) +{ + const double DIAGONAL = sqrt(surface->w * surface->w+ + surface->h * surface->h); + + const int RHO_MAX = (int)(2 * DIAGONAL ) +1; + + const int RHO_OFFSET = RHO_MAX / 2; + + + int w = surface->w; + int h = surface->h; + int n = 50; + //create pointer of lines + struct Line* lines = calloc(n ,sizeof(struct Line)); + + + //create accumulator + int ** accumulator = malloc(RHO_MAX * sizeof(int*)); + for (int i = 0; i < RHO_MAX; i++) + accumulator[i] = calloc(theta_s, sizeof(int)); + + + if (SDL_MUSTLOCK(surface) && SDL_LockSurface(surface) != 0) { + // Handle the error, perhaps log it or exit + fprintf(stderr, "Could not lock surface: %s\n", SDL_GetError()); + exit(EXIT_FAILURE); + } + // Iterate over the pixels to collect votes + for (int x = 0; x < w; x++) + { + for (int y = 0; y < h; y++) + { + Uint8 r,g,b; + Uint32 pixelvalue = get_pixel(surface, x, y); + SDL_GetRGB(pixelvalue, surface->format, &r, &g, &b); + + + if (r == 255 && g == 255 && b == 255) { //or r>128 + for (int t = 0; t < theta_s; t++) + { + double currentTheta = t * theta; + double rho = (x * cos(currentTheta )) + + (y * sin(currentTheta)); + + int rhoIndex = (int)(rho + RHO_OFFSET); + + if (rhoIndex >= 0 && rhoIndex < RHO_MAX) + { + accumulator[rhoIndex][t]++; + } + + } + } + + } + } + + + if (SDL_MUSTLOCK(surface)) { + SDL_UnlockSurface(surface); + } + + int maxval = accu_maxvalue(accumulator, RHO_MAX, theta_s); + + + // The threshold will depend on your specific + // application and image characteristics + int lineindex= 0; + const int THRESHOLD = maxval * 0.2; + + + for (int r = 0; r < RHO_MAX; r++) + { + for (int t = 0; t < theta_s; t++) + { + //printf("%i",accumulator[r][t]); + if (accumulator[r][t] > THRESHOLD) + { + double foundRho = (r - RHO_OFFSET); + double foundTheta = t * theta; + // float epsilon = 0.01; + + int x1, y1, x2, y2; + if ( foundTheta< 0.01 ||fabs(foundTheta - M_PI) + < 0.01){ //works perfectly //near 0 or pi + + // Line is approximately vertical + x1 = x2 = foundRho / cos(foundTheta); + y1 = 0; + y2 = h; + + if (x1 < 0) x1=x2=0; + if (x1 >= w) x1 = x2 = w-1; + + + } else if ( fabs(foundTheta - M_PI/2 ) < 0.01) { + // Line is approximately horizontal + + y1 = y2 = (foundRho/ sin (foundTheta )); + x1 = 0; + x2 = w; + + if (y1 < 0) y1 = y2 = 0; + if (y1 >= h) y1 = y2 = h - 1; + + //x1=x2=y1=y2=0; + + + } else { + // diagonal + x1 = 0; + y1 = foundRho / sin(foundTheta) ; + x2 = w; + y2 = ((foundRho - x2 * cos(foundTheta)) / sin(foundTheta) ); + + // x1=x2=y1=y2=0; + + + + if (lineindex == n) { + n *= 2; + lines = (struct Line*) realloc(lines, + n * sizeof(struct Line)); + } + + lines[lineindex].start.x = x1; + lines[lineindex].end.x = x2; + lines[lineindex].start.y = y1; + lines[lineindex].end.y = y2; + lines[lineindex].theta = t; + lines[lineindex].rho = foundRho; + lineindex++; + } + + } + } + } + for (int i = 0; i < RHO_MAX; i++) { + free(accumulator[i]); + } + free(accumulator); + + + struct Line* temp = (struct Line*) realloc(lines, + lineindex * sizeof(struct Line)); + if (temp == NULL) { + // Handle memory allocation failure + } + lines = temp; + + //printf("%i",lineindex); + struct DetectedLines result; + result.lines = lines; + result.count = lineindex; + + return result; + + //return lines; + + } + +double calculate_angle( struct DetectedLines result ) +{ + struct Line* lines = result.lines; + int count = result.count; + + int theta_bins[360] = {0}; + + // Count occurrences of each theta in bins + for (int i = 0; i < count; ++i) { + int bin_index = (int)(lines[i].theta ) % 360; + + theta_bins[bin_index]++; + } + + // Find the theta bin with the highest count + int most_common_theta = 0, max_count = 0; + for (int i = 0; i < 360; ++i) { + if (theta_bins[i] > max_count) { + max_count = theta_bins[i]; + most_common_theta = i; + } + } + + //if (most_common_theta < 90) most_common_theta +=90; + return (double) (most_common_theta -90); +} + + +//rotate the image with corrersponding angle +SDL_Surface* RotateImage(SDL_Surface* image, double angledegree) +{ + //angledegree = fmod(angledegree, 360.0); + + int w1 = image->w; + int h1 = image->h; + if (angledegree == 0) { + return SDL_ConvertSurface(image, image->format, 0); // Create a copy + } + + float rad = angledegree * M_PI /180.0; + + double coco = cos(rad); + double sisi = sin(rad); + + + int w2 = fabs(coco * w1) + fabs(sisi *h1); //x' = xcos + ysin + int h2 = fabs(sisi*w1) + fabs(coco*h1); + + SDL_Surface* rot = SDL_CreateRGBSurface(0,w2,h2,32,0,0,0,0); + + SDL_UnlockSurface(image); + SDL_UnlockSurface(rot); + + for(int y = 0; y < h2; y++) + { + for(int x = 0; x < w2; x++) + { + int middlex = w1 / 2; //center coordinates of + //the source image + int middley = h1 / 2; + + + //with the distance to the center for each pixe + //-> trigonometric calculations can be used + //(the rotation matrix) + + int distancex = x - w2 / 2; // distance of + // current pixel + // from the center of the destination image in the x direction. + int distancey = y - w2 / 2; + + //the corresponding pixel in the source image + int truex = middlex + distancex *coco - distancey *sisi; + int truey = middley+ distancey *coco+ distancex *sisi; + + if (truex >= 0 && truey >=0 && truex pixels)[y * w2 + x]= ((Uint32*) + image->pixels)[truey * w1 + truex]; + else + ((Uint32*)rot->pixels)[y * w2 + x] = 0x000000; + //transparent sdl rgb + } + } + + SDL_UnlockSurface(image); + SDL_UnlockSurface(rot); + + //memcpy(image->pixels, rot->pixels, w * h * sizeof(Uint32)) + + return rot; + +} + + + +/* ///AUTOMATIC ROTATION //HOUGH From fcc00a64af04e37d7be9635662e226a883bb13a9 Mon Sep 17 00:00:00 2001 From: Joanne Jabbour Date: Sat, 9 Dec 2023 01:37:23 +0100 Subject: [PATCH 2/2] cleann --- .DS_Store | Bin 10244 -> 10244 bytes src/.DS_Store | Bin 6148 -> 6148 bytes src/edge_detection/.DS_Store | Bin 8196 -> 6148 bytes src/edge_detection/Makefile | 4 +- src/edge_detection/detection.c | 24 +- src/edge_detection/hough.c | 425 +---------- src/edge_detection/hough.h | 7 +- src/edge_detection/houghstore.c | 0 src/edge_detection/houghstore2.c | 967 ------------------------ src/edge_detection/image.c | 380 ---------- src/edge_detection/image.h | 21 - src/image_processing/.DS_Store | Bin 0 -> 6148 bytes src/image_processing/Makefile | 4 +- src/image_processing/detection.c | 211 ------ src/image_processing/detection.h | 27 - src/image_processing/processing.c | 152 ---- src/image_processing/square_detection.c | 157 ---- src/image_processing/square_detection.h | 15 - 18 files changed, 29 insertions(+), 2365 deletions(-) delete mode 100644 src/edge_detection/houghstore.c delete mode 100644 src/edge_detection/houghstore2.c delete mode 100644 src/edge_detection/image.c delete mode 100644 src/edge_detection/image.h create mode 100644 src/image_processing/.DS_Store delete mode 100644 src/image_processing/detection.c delete mode 100644 src/image_processing/detection.h delete mode 100644 src/image_processing/square_detection.c delete mode 100644 src/image_processing/square_detection.h diff --git a/.DS_Store b/.DS_Store index 084ebf79d7a7414563081004e668858f2929b269..d5eb55620e8d1a005b7e8b6fc678f75923b1bdd3 100644 GIT binary patch delta 46 vcmZn(XbIRLBFJH6W}u^BY-BV!U&?-Sv|uD78IY L6>ZL!n#v0R)SVCm diff --git a/src/.DS_Store b/src/.DS_Store index 5cc186682fdb4c063cc1bc71e37e1e235ed55c85..5aac0dc454e8ae7c25c177fd7fcbeb452ec45403 100644 GIT binary patch delta 87 zcmZoMXfc@J&&azmU^g=(?_?g9WJb=(RV<2=TiFFBuV#^*+{3bm!^q4)N5R<0XmbFo k4TP>BW8rt^$^0^oAlHDbV*$}j5a)o!HplbKVFmz>2p{DD literal 8196 zcmeHM&2AGh5dK^u8mUlm=%J!Q+80Qagf>67v`UaTaG@_iHrb|#lpsnZj=A#=yaLb1 z3BDOyXl-XxDkMaN9oZA@&WvZinek>e0L;Z|)&`CN)H#JdIpDHk$bFg7*mGB&k{Zeb zAF;$IOgP_0-04C>AR&+tNC+eZ5(57M0(@r6s8>Aq?cKB{1QG)OB?59jWSl~Wj;<}$ zql1gK0Hifu*1_-W15_q+bm-{XQWd36+dUX3YFvw9tT^vy!cIDLbZw~>hq2-?ZfD~< z6r;OSE>m`xp`~d}2qXkz1f+LAVaL8=&%X5f_a)w=fh!Df%2j3`&(S1Tle{E_VuV~z&P~LrKQCm+c%*1 zIcK4I2i5u_oDV1w;ulBuTY&mzsihw)^DK}$!Zq`5g*j&Z33ZCcdhoK)+HYGl9USA?BmhItw5a|d-Gy0>r#2uH{~Dp_*t&H~A< zuu>UMugV{9lrp|i0=q*h}N80)L>3`nNKZ6aKNZko-@W5JpEdBqu z`u+dT`IQV#2qXl49|2PvU5+lu?|SP #include #include -#include "image.h" +#include +#include +#include #include "hough.h" int original_image_width = 0; int original_image_height = 0; +SDL_Surface* load_image(const char* path) +{ + SDL_Surface* is = IMG_Load(path); + if (is == NULL) + errx(EXIT_FAILURE, "%s", SDL_GetError()); + + SDL_Surface* fs = SDL_ConvertSurfaceFormat(is, SDL_PIXELFORMAT_RGB888, 0); + if (fs == NULL) + errx(EXIT_FAILURE, "%s", SDL_GetError()); + + SDL_FreeSurface(is); + return fs; +} + + void update_render_scale(SDL_Renderer* renderer, int new_width, int new_height) { float scale_x = (float)new_width / original_image_width; @@ -395,7 +411,7 @@ int main(int argc, char **argv){ free(vertical); } struct Squares* sq = drawsquares( lines, num_lines,horizon, vertical); - struct Squares s = findbestsquare( surface, vertical, horizon, sq, num_lines/2 ); + struct Squares s = findbestsquare( surface, vertical, horizon, num_lines/2 ); SDL_Texture* grayscale_texture = @@ -441,7 +457,7 @@ int main(int argc, char **argv){ } struct Squares* sq = drawsquares(lines, num_lines, horizon, vertical); - struct Squares s = findbestsquare( surface, vertical, horizon, sq, num_lines/2 ); + struct Squares s = findbestsquare( surface, vertical, horizon, num_lines/2 ); SDL_Texture* grayscale_texture = SDL_CreateTextureFromSurface(renderer, surface); diff --git a/src/edge_detection/hough.c b/src/edge_detection/hough.c index e128dad..2161642 100644 --- a/src/edge_detection/hough.c +++ b/src/edge_detection/hough.c @@ -575,7 +575,7 @@ int check_square_edges(SDL_Surface *surface, struct Squares sq) { return 1; } struct Squares findbestsquare(SDL_Surface* original_image, -struct Line* vertical, struct Line* horizon, struct Squares *squares, int len) +struct Line* vertical, struct Line* horizon, int len) { struct Squares max_square; int max_size = -1; @@ -659,7 +659,7 @@ void printvalues(struct Line* lines, int len,SDL_Surface* original_image) } struct Squares ss = findbestsquare(original_image, vertical, - horizon, squares, len); + horizon, len); printf("last big \n"); printf("Top Left: (%f, %f)\n", ss.topleft.x, ss.topleft.y); @@ -765,127 +765,11 @@ struct Squares* drawsquares(struct Line* lines, int len,struct Line* horizon, free(squares);*/ } - - -/* - -// Function to extract and save squares as images -void extract_and_save_squares(SDL_Surface* original_image, struct Squares* - squares,int num_squares,struct Squares s){ - const int target_width = 28; - const int target_height = 28; - int j = 0; - - float average_width, average_height; - calculate_average_dimensions(squares, num_squares, - &average_width, &average_height); - - printf("last big \n"); - - printf("Top Left: (%f, %f)\n", - s.topleft.x, s.topleft.y); - printf("Top Right: (%f, %f)\n", - s.topright.x, s.topright.y); - printf("Bottom Right: (%f, %f)\n", - s.bottomright.x, s.bottomright.y); - printf("Bottom Left: (%f, %f)\n", - s.bottomleft.x, s.bottomleft.y); - printf("\n"); - - - for (int i = 0; i < num_squares; i++) { - if (s.topleft.x <= squares[i].topleft.x && - s.topright.x >= squares[i].topright.x && s.topleft.y - <= squares[i].topleft.y && s.bottomleft.y >= - squares[i].bottomleft.y) { - - - float width = squares[i].topright.x - - squares[i].topleft.x; - float height = squares[i].bottomleft.y - - squares[i].topleft.y; - - // Check if the square's dimensions are - // close to the average - if ((fabs(width - average_width) < 20 || - fabs(height - average_height) < 20 )&& - fabs(width - height) < 10) - { - // Skip this square as its dimensions are too different - - // Create a new surface for each square - SDL_Surface* square_surface = - SDL_CreateRGBSurface(0, width, height, - original_image->format->BitsPerPixel, - original_image->format->Rmask, - original_image->format->Gmask, - original_image->format->Bmask, - original_image->format->Amask); - - if (square_surface == NULL) { - fprintf(stderr, - "SDL_CreateRGBSurface failed: %s\n", - SDL_GetError()); - continue; // Skip this square - } - - // Define the rectangle to be copied - SDL_Rect square_rect; - square_rect.x = squares[i].topleft.x; - square_rect.y = squares[i].topleft.y; - square_rect.w = width; - square_rect.h = height; - - // Blit the square area - // from the original image to the new surface - SDL_BlitSurface(original_image, - &square_rect, square_surface, NULL); - - - // Create a new surface for the resized square - SDL_Surface* resized_surface = - SDL_CreateRGBSurface(0, target_width, - target_height, original_image->format->BitsPerPixel, - original_image->format->Rmask, - original_image->format->Gmask, - original_image->format->Bmask, - original_image->format->Amask); - - if (resized_surface == NULL) { - fprintf(stderr, - "SDL_CreateRGBSurface failed for resized surface: %s\n" - , SDL_GetError()); - SDL_FreeSurface(square_surface); - continue; - } - - SDL_BlitScaled(square_surface, NULL, - resized_surface, NULL); - - // Save each square as an image - char filename[64]; - sprintf(filename, "square_%d.bmp", j); - j++; - if (SDL_SaveBMP(resized_surface, filename) - != 0) { - fprintf(stderr, "SDL_SaveBMP failed: %s\n" - , SDL_GetError()); - } - - // Free the square surface after saving - SDL_FreeSurface(square_surface); - // SDL_FreeSurface(resized_surface); - } - } - } -}*/ - // Function to extract and save squares as images void extract_and_save_squares(SDL_Surface* original_image, struct Squares* squares, int num_squares,struct Squares s){ const int target_width = 28; const int target_height = 28; - int j = 0; float average_width, average_height; calculate_average_dimensions(squares, num_squares, &average_width, &average_height); @@ -964,7 +848,7 @@ printf("t r %f,%f\n", s.bottomright.x, s.bottomright.y); // Save each square as an image char filename[64]; sprintf(filename, "square_%d.bmp", counter); - j++; + if (SDL_SaveBMP(resized_surface, filename) != 0) { fprintf(stderr, "SDL_SaveBMP failed: %s\n", SDL_GetError()); } @@ -1236,306 +1120,3 @@ SDL_Surface* RotateImage(SDL_Surface* image, double angledegree) } - - -/* -///AUTOMATIC ROTATION - -//HOUGH -struct DetectedLines auto_performHoughTransform(SDL_Surface *surface) -{ - const double DIAGONAL = sqrt(surface->w * surface->w+ - surface->h * surface->h); - - const int RHO_MAX = (int)(2 * DIAGONAL ) +1; - - const int RHO_OFFSET = RHO_MAX / 2; - - - int w = surface->w; - int h = surface->h; - int n = 50; - //create pointer of lines - struct Line* lines = calloc(n ,sizeof(struct Line)); - - - //create accumulator - int ** accumulator = malloc(RHO_MAX * sizeof(int*)); - for (int i = 0; i < RHO_MAX; i++) - accumulator[i] = calloc(theta_s, sizeof(int)); - - - if (SDL_MUSTLOCK(surface) && SDL_LockSurface(surface) != 0) { - // Handle the error, perhaps log it or exit - fprintf(stderr, "Could not lock surface: %s\n", SDL_GetError()); - exit(EXIT_FAILURE); - } - // Iterate over the pixels to collect votes - for (int x = 0; x < w; x++) - { - for (int y = 0; y < h; y++) - { - Uint8 r,g,b; - Uint32 pixelvalue = get_pixel(surface, x, y); - SDL_GetRGB(pixelvalue, surface->format, &r, &g, &b); - - - if (r == 255 && g == 255 && b == 255) { //or r>128 - for (int t = 0; t < theta_s; t++) - { - double currentTheta = t * theta; - double rho = (x * cos(currentTheta )) - + (y * sin(currentTheta)); - - int rhoIndex = (int)(rho + RHO_OFFSET); - - if (rhoIndex >= 0 && rhoIndex < RHO_MAX) - { - accumulator[rhoIndex][t]++; - } - - } - } - - } - } - - - if (SDL_MUSTLOCK(surface)) { - SDL_UnlockSurface(surface); - } - - int maxval = accu_maxvalue(accumulator, RHO_MAX, theta_s); - - - // The threshold will depend on your specific - // application and image characteristics - int lineindex= 0; - const int THRESHOLD = maxval * 0.2; - - - for (int r = 0; r < RHO_MAX; r++) - { - for (int t = 0; t < theta_s; t++) - { - //printf("%i",accumulator[r][t]); - if (accumulator[r][t] > THRESHOLD) - { - double foundRho = (r - RHO_OFFSET); - double foundTheta = t * theta; - // float epsilon = 0.01; - - int x1, y1, x2, y2; - if ( foundTheta< 0.01 || - fabs(foundTheta - M_PI)< 0.01){ - - // Line is approximately vertical - x1 = x2 = - foundRho / cos(foundTheta); - y1 = 0; - y2 = h; - - if (x1 < 0) x1=x2=0; - if (x1 >= w) x1 = x2 = w-1; - - - } else if ( fabs(foundTheta - M_PI/2 ) - < 0.01) { - // Line is approximately horizontal - - y1 = y2 = - (foundRho/ sin (foundTheta )); - x1 = 0; - x2 = w; - - if (y1 < 0) y1 = y2 = 0; - if (y1 >= h) y1 = y2 = h - 1; - - //x1=x2=y1=y2=0; - - - } else { - // diagonal - x1 = 0; - y1 = foundRho / sin(foundTheta) ; - x2 = w; - y2 = ((foundRho - x2 * - cos(foundTheta)) / sin(foundTheta) ); - - // x1=x2=y1=y2=0; - - - - if (lineindex == n) { - n *= 2; - lines = (struct Line*) - realloc(lines, - n * sizeof(struct Line)); - } - - lines[lineindex].start.x = x1; - lines[lineindex].end.x = x2; - lines[lineindex].start.y = y1; - lines[lineindex].end.y = y2; - lines[lineindex].theta = t; - lines[lineindex].rho = foundRho; - lineindex++; - } - } - - - } - } - for (int i = 0; i < RHO_MAX; i++) { - free(accumulator[i]); - } - free(accumulator); - - - struct Line* temp = (struct Line*) realloc(lines, - lineindex * sizeof(struct Line)); - if (temp == NULL) { - // Handle memory allocation failure - } - lines = temp; - - //printf("%i",lineindex); - struct DetectedLines result; - result.lines = lines; - result.count = lineindex; - - return result; - - //return lines; - - } - -double calculate_angle( struct DetectedLines result ) -{ - struct Line* lines = result.lines; - int count = result.count; - double total_angle = 0; - - for (int i = 0; i < count; ++i) { - double dx = fabs(lines[i].end.x - lines[i].start.x); - double dy = fabs(lines[i].end.y - lines[i].start.y); - - double angle = atan2(dy, dx); // Angle in radians - - // Convert to degree - angle = angle * (180.0 / M_PI); - - total_angle += angle; - } - - double average_angle = total_angle / count; - - - //printf("%f\n", average_angle - 8); - //printf("%f\n", total_angle); - //printf("%i\n",count); - return average_angle - 8; - -} - - -//rotate the image with corrersponding angle -SDL_Surface* RotateImage(SDL_Surface* image, double angledegree) -{ - float rad = angledegree * M_PI /180.0; - - double coco = cos(rad); - double sisi = sin(rad); - - int w1 = image->w; - int h1 = image->h; - - int w2 = fabs(coco * w1) + fabs(sisi *h1); //x' = xcos + ysin - int h2 = fabs(sisi*w1) + fabs(coco*h1); - - SDL_Surface* rot = SDL_CreateRGBSurface(0,w2,h2,32,0,0,0,0); - - SDL_UnlockSurface(image); - SDL_UnlockSurface(rot); - - for(int y = 0; y < h2; y++) - { - for(int x = 0; x < w2; x++) - { - int middlex = w1 / 2; //center coordinates of - //the source image - int middley = h1 / 2; - - - //with the distance to the center for each pixe - //-> trigonometric calculations can be used - //(the rotation matrix) - - int distancex = x - w2 / 2; // distance of - // current pixel - // from the center of the destination image in the x direction. - int distancey = y - w2 / 2; - - //the corresponding pixel in the source image - int truex = middlex + distancex *coco - distancey *sisi; - int truey = middley+ distancey *coco+ distancex *sisi; - - if (truex >= 0 && truey >=0 && truex pixels)[y * w2 + x]= ((Uint32*) - image->pixels)[truey * w1 + truex]; - else - ((Uint32*)rot->pixels)[y * w2 + x] = 0x000000; - //transparent sdl rgb - } - } - - SDL_UnlockSurface(image); - SDL_UnlockSurface(rot); - - //memcpy(image->pixels, rot->pixels, w * h * sizeof(Uint32)) - - return rot; - -} - -/* -double calculate_angle(struct DetectedLines result) { - struct Line* lines = result.lines; - int count = result.count; - for (int i =0; i < count; i++) - { - printf ("diagonal %i:start x: %f y: %f | end x: %f y: %f \n", - i, lines[i].start.x, - lines[i].start.y,lines[i].end.x,lines[i].end.y); - } - double sin_sum = 0.0; - double cos_sum = 0.0; - - for (int i = 0; i < count; ++i) { - double dx = fabs(lines[i].end.x - lines[i].start.x); - double dy = fabs(lines[i].end.y - lines[i].start.y); - - double angle = atan2(dy, dx); // Angle in radians - printf(" angle (): %f\n", angle); - sin_sum += sin(angle); - cos_sum += cos(angle); - } - - - - double average_angle_radians = atan2(sin_sum / count, cos_sum / count); - double average_angle_degrees = average_angle_radians * (180.0 / M_PI); - - printf(" angle (degrees): %f\n", average_angle_degrees); - - // Normalize the average angle to the range [-180, 180] - if (average_angle_degrees > 180) { - average_angle_degrees -= 360; - } else if (average_angle_degrees < -180) { - average_angle_degrees += 360; - } - - printf("Average angle (degrees): %f\n", average_angle_degrees); - return average_angle_degrees; -} -*/ diff --git a/src/edge_detection/hough.h b/src/edge_detection/hough.h index ba1ad18..52a054b 100644 --- a/src/edge_detection/hough.h +++ b/src/edge_detection/hough.h @@ -39,10 +39,9 @@ struct Squares { void printvalues(struct Line* lines, int len,SDL_Surface* original_image); -struct Squares findbestsquare(SDL_Surface* original_image, struct Line* vertical, struct Line* horizon, struct Squares *squares, int len); +struct Squares findbestsquare(SDL_Surface* original_image, struct Line* vertical, struct Line* horizon, int len); -//struct Squares* drawsquares(struct Line* lines, int len); struct Squares* drawsquares(struct Line* lines, int len,struct Line* horizon, struct Line* vertical ); void get_sudoku_lines(struct Line *lines, int lineCount, struct Line *topLines, int topCount) ; @@ -51,11 +50,9 @@ struct DetectedLines averagearray(struct Line* Line, int len); void drawl(struct Line* line, int len,SDL_Renderer* renderer, SDL_Texture* texture); -//void print_h_v(struct Line* lines, int len, struct Line* horizon, struct Line* vertical, -//struct Line* topLinesh,struct Line* topLinesv); struct DetectedLines performHoughTransform(SDL_Surface *surface); -//void extract_and_save_squares(SDL_Surface* original_image, struct Squares* squares, int num_squares); + void extract_and_save_squares(SDL_Surface* original_image, struct Squares* squares, int num_squares,struct Squares s); //rot struct DetectedLines auto_performHoughTransform(SDL_Surface *surface); diff --git a/src/edge_detection/houghstore.c b/src/edge_detection/houghstore.c deleted file mode 100644 index e69de29..0000000 diff --git a/src/edge_detection/houghstore2.c b/src/edge_detection/houghstore2.c deleted file mode 100644 index e22c171..0000000 --- a/src/edge_detection/houghstore2.c +++ /dev/null @@ -1,967 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include "hough.h" - -//noir 0 -//blanc 1 - - -const int theta_s = 180; // Adjust as needed for precision -const double rho = 1; // Distance resolution in pixels -const double theta = M_PI / theta_s; // Angle resolution in radians - - -//HOUGH ALGO - -Uint32 get_pixel(SDL_Surface *surface, int x, int y) -{ - if (x < 0 || y < 0 || x >= surface->w || y >= surface->h) - return 0; // Out of bounds - - Uint32 *pixels = (Uint32 *)surface->pixels; - Uint32 pixel_value = pixels[y * surface->w + x]; - - return pixel_value; -} - - - -int accu_maxvalue(int ** accumulator,int rows, int cols) -{ - int maxVal = accumulator[0][0]; - - for (int i = 0; i < rows; i++) { - for (int j = 0; j < cols; j++) { - if (accumulator[i][j] > maxVal) { - maxVal = accumulator[i][j]; - } - } - } - - return maxVal; -} - - -int isNearZero(double value, double epsilon) { - if (fabs(value) < epsilon || fabs(value - M_PI) < epsilon || - fabs(value - M_PI_2) < epsilon) - return 1; - return 0; -} - - -struct DetectedLines performHoughTransform(SDL_Surface *surface) -{ - const double DIAGONAL = sqrt(surface->w * surface->w+ - surface->h * surface->h); - - const int RHO_MAX = (int)(2 * DIAGONAL ) +1; - - const int RHO_OFFSET = RHO_MAX / 2; - - - int w = surface->w; - int h = surface->h; - int n = 50; - //create pointer of lines - struct Line* lines = calloc(n ,sizeof(struct Line)); - - - //create accumulator - int ** accumulator = malloc(RHO_MAX * sizeof(int*)); - for (int i = 0; i < RHO_MAX; i++) - accumulator[i] = calloc(theta_s, sizeof(int)); - - - if (SDL_MUSTLOCK(surface) && SDL_LockSurface(surface) != 0) { - // Handle the error, perhaps log it or exit - fprintf(stderr, "Could not lock surface: %s\n", SDL_GetError()); - exit(EXIT_FAILURE); - } - // Iterate over the pixels to collect votes - for (int x = 0; x < w; x++) - { - for (int y = 0; y < h; y++) - { - Uint8 r,g,b; - Uint32 pixelvalue = get_pixel(surface, x, y); - SDL_GetRGB(pixelvalue, surface->format, &r, &g, &b); - - - if (r == 255 && g == 255 && b == 255) { //or r>128 - for (int t = 0; t < theta_s; t++) - { - double currentTheta = t * theta; - double rho = (x * cos(currentTheta )) - + (y * sin(currentTheta)); - - int rhoIndex = (int)(rho + RHO_OFFSET); - - if (rhoIndex >= 0 && rhoIndex < RHO_MAX) - { - accumulator[rhoIndex][t]++; - } - - } - } - - } - } - - - if (SDL_MUSTLOCK(surface)) { - SDL_UnlockSurface(surface); - } - - int maxval = accu_maxvalue(accumulator, RHO_MAX, theta_s); - - - // The threshold will depend on your specific - // application and image characteristics - int lineindex= 0; - const int THRESHOLD = maxval * 0.2; - - - for (int r = 0; r < RHO_MAX; r++) - { - for (int t = 0; t < theta_s; t++) - { - //printf("%i",accumulator[r][t]); - if (accumulator[r][t] > THRESHOLD) - { - double foundRho = (r - RHO_OFFSET); - double foundTheta = t * theta; - // float epsilon = 0.01; - - int x1, y1, x2, y2; - if ( foundTheta< 0.01 ||fabs(foundTheta - M_PI) - < 0.01){ //works perfectly //near 0 or pi - - // Line is approximately vertical - x1 = x2 = foundRho / cos(foundTheta); - y1 = 0; - y2 = h; - - if (x1 < 0) x1=x2=0; - if (x1 >= w) x1 = x2 = w-1; - - - } else if ( fabs(foundTheta - M_PI/2 ) < 0.01) { - // Line is approximately horizontal - - y1 = y2 = (foundRho/ sin (foundTheta )); - x1 = 0; - x2 = w; - - if (y1 < 0) y1 = y2 = 0; - if (y1 >= h) y1 = y2 = h - 1; - - //x1=x2=y1=y2=0; - - - } else { - // diagonal - x1 = 0; - y1 = foundRho / sin(foundTheta) ; - x2 = w; - y2 = ((foundRho - x2 * cos(foundTheta)) / sin(foundTheta) ); - - x1=x2=y1=y2=0; - - } - - if (lineindex == n) { - n *= 2; - lines = (struct Line*) realloc(lines, - n * sizeof(struct Line)); - } - - lines[lineindex].start.x = x1; - lines[lineindex].end.x = x2; - lines[lineindex].start.y = y1; - lines[lineindex].end.y = y2; - lines[lineindex].theta = t; - lines[lineindex].rho = foundRho; - lineindex++; - - - - }} - } - for (int i = 0; i < RHO_MAX; i++) { - free(accumulator[i]); - } - free(accumulator); - - - struct Line* temp = (struct Line*) realloc(lines, - lineindex * sizeof(struct Line)); - if (temp == NULL) { - // Handle memory allocation failure - } - lines = temp; - - //printf("%i",lineindex); - struct DetectedLines result; - result.lines = lines; - result.count = lineindex; - - return result; - - //return lines; - - } - - - - -//CALCULATE AVERAGE OF THE LINES - - -float distance(struct Point a, struct Point b) -{ - return sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y)); -} - -int thelinebelongs(struct Line l1, struct Line l2) -{ - - //if (fabs(l1.rho - l2.rho) <= rhoThreshold && fabs(l1.theta - - //l2.theta) <= thetaThreshold) - - float startDistance = distance(l1.start, l2.start); - float endDistance = distance(l1.end, l2.end); - - if (startDistance < startThreshold && endDistance < endThreshold) - return 1; - return 0; -} - -void addtogroup(struct Line line, struct Linegroup* group) -{ - group->average.start.x = (group->average.start.x * group->numlines - + line.start.x) / (group->numlines + 1); - group->average.start.y = (group->average.start.y * group->numlines - + line.start.y) / (group->numlines + 1); - group->average.end.x = (group->average.end.x * group->numlines - + line.end.x) / (group->numlines + 1); - group->average.end.y = (group->average.end.y * group->numlines - + line.end.y) / (group->numlines + 1); - group->average.theta = line.theta; - group->average.rho = line.rho; - group->numlines +=1; -} - - - -int averagelines(struct Line* line, int len, struct Linegroup** group) { - int n = 100; - int ncurrent = 0; - - for(int i = 0; i < len; i++) - { - int loner = 1; //true = 1 - for(int j = 0; j < ncurrent; j++) - { - if(thelinebelongs(line[i], group[j]->average) == 1) - { - addtogroup(line[i], group[j]); - loner = 0; //false - } - } - if (loner == 1) - { - if(ncurrent == n) - { - n *= 2; - group = realloc(group, n * - sizeof(struct Linegroup*)); - - if (!group) - { - fprintf(stderr, "Memory allocation failed.\n"); - exit(EXIT_FAILURE); - } - - for (int j = ncurrent; j < n; j++) - { - group[j] = NULL; - } - } - group[ncurrent] = calloc(1, sizeof(struct Linegroup)); - if (!group[ncurrent]) - { - fprintf(stderr, "Memory allocation failed.\n"); - exit(EXIT_FAILURE); - } - group[ncurrent]->average.start.x = line[i].start.x; - group[ncurrent]->average.start.y = line[i].start.y; - - group[ncurrent]->average.end.x = line[i].end.x; - group[ncurrent]->average.end.y = line[i].end.y; - - group[ncurrent]->average.theta = line[i].theta; - group[ncurrent]->average.rho = line[i].rho; - - group[ncurrent]->numlines = 1; - ncurrent++; - } - } - return ncurrent; - -} - - - -void drawl(struct Line* line, int len, SDL_Renderer* renderer, - SDL_Texture* texture) -{ - struct Linegroup** group = calloc(len, sizeof(struct Linegroup*)); - // use len as it represents the number of lines - if (!group) { - fprintf(stderr, "Memory allocation failed.\n"); - exit(EXIT_FAILURE); - } - int nmax = averagelines(line, len, group); - - // SDL_RenderClear(renderer); - - -// SDL_RenderCopy(renderer, backgroundTexture, NULL, NULL); - - int render = SDL_RenderCopy(renderer, texture, NULL, NULL); - if (render != 0) - errx(EXIT_FAILURE, "%s", SDL_GetError()); - - for(int i = 0; i < nmax; i++) - { - printf("start x %f y %f, end x%f y %f", group[i]-> - average.start.x, group[i]->average.start.y, - group[i]->average.end.x, group[i]-> - average.end.y); - SDL_SetRenderDrawColor(renderer, 255, 0, 0, - SDL_ALPHA_OPAQUE); // Red color for the lines - SDL_RenderDrawLine(renderer, group[i]->average.start.x, - group[i]->average.start.y, - group[i]->average.end.x, group[i]-> - average.end.y); - } - SDL_RenderPresent(renderer); - - for (int i = 0; i < nmax; i++) - free(group[i]); - free(group); - - -} - - - -struct DetectedLines averagearray(struct Line* Line, int len) -{ - struct Linegroup** group = calloc(len, sizeof(struct Linegroup*)); - // use len as it represents the number of lines - if (!group) { - fprintf(stderr, "Memory allocation failed.\n"); - exit(EXIT_FAILURE); - } - int nmax = averagelines(Line, len, group); - - struct DetectedLines result; - result.lines = calloc(nmax, sizeof(struct Line)); - result.count = nmax; - //printf("nmax %i \n", nmax); - - for(int i = 0; i < nmax; i++) - { - //if (isPartOfSudoku(group, nmax, group[i])) { - - result.lines[i].start.x = group[i]->average.start.x; - result.lines[i].start.y = group[i]->average.start.y; - result.lines[i].end.x = group[i]->average.end.x; - result.lines[i].end.y = group[i]->average.end.y; - result.lines[i].rho = group[i]->average.rho; - result.lines[i].theta = group[i]->average.theta; - - //printf("nmax %i\n x %f",j , result.lines[j].start.x); - - //} - - free(group[i]); - - } - free(group); - - return result; -} - -//DETECT THE SQUARES - -void horizontal_vertical_lines( struct Line* lines, int len, struct - Line* horizon, struct Line* vertical) -{ - //thtea en degree - int j = 0, k = 0; - for (int i = 0; i < len; i++) - { - float t = lines[i].theta; - //printf("t value %f \n",t); - float foundTheta = t *theta; - if ( foundTheta< 0.01 || fabs(foundTheta - M_PI) < 0.01) - //if ( (t>= -10 && t <= 10) || (t>= 170 && t<=190)) - - { - vertical[j] = lines[i]; - j++; - } - else if ( fabs(foundTheta - M_PI/2 ) < 0.01) - { - horizon[k] = lines[i]; - k++; - } - } - //printf("len h %i, len v %i \n",j+1,k+1); -} - - -void sort_horizontal_lines(struct Line* horizon, int len) -{ - int i, j; - struct Line compare; - - for (i = 1; i < len; i++) - { - //printf("(%f,%f)",horizon[i].start.x,horizon[i].start.y); - compare = horizon[i]; - j = i - 1; - - // Move elements that are greater - // than key to one position ahead of their current position - while (j >= 0 && horizon[j].start.y > compare.start.y) - { - horizon[j + 1] = horizon[j]; - j = j - 1; - } - horizon[j + 1] = compare; - } - -/* for(int k = 0; k = 0 && vertical[j].start.x > compare.start.x) - { - vertical[j + 1] = vertical[j]; - j = j - 1; - } - vertical[j + 1] = compare; - } - -/* for(int k = 0; k start.x - line2->start.x); -} - -// A helper function to compare lines for sorting -int compare_Horizon_Lines(const void *a, const void *b) { - struct Line *line1 = (struct Line *)a; - struct Line *line2 = (struct Line *)b; - - // y-coordinate for horizontal lines - return (line1->start.y - line2->start.y); -} - -// Function to check if a sequence of lines are evenly spaced -int isEvenlySpacedSequence_vertical(struct Line* lines, int start, int sequenceLength, float averageDistance, float tolerance) { - for (int i = start; i < start + sequenceLength - 1; i++) { - - float distance = fabs(lines[i + 1].start.x - lines[i].start.x); - float minDistance = 0.000001 * averageDistance; - - if (fabs(distance - averageDistance) > tolerance) { - return 0; // Not evenly spaced - } - } - return 1; // Evenly spaced -} - - -// Function to check if a sequence of lines are evenly spaced -int isEvenlySpacedSequence_horizon(struct Line* lines, int start, int sequenceLength, float averageDistance, float tolerance) -{ - for (int i = start; i < start + sequenceLength - 1; i++) - { - float distance = fabs(lines[i + 1].start.y - lines[i].start.y); - float minDistance = 0.00000001 * averageDistance; - if (fabs(distance - averageDistance) > tolerance ) { - return 0; // Not evenly spaced - } - } - return 1; // Evenly spaced -} - -void get_sudoku_lines (struct Line* vertical, struct Line* horizon, struct Line *topLinesv, -struct Line *topLinesh, int len) -{ - //printf("%f",horizon[1].end.x); - int topCount = 10; - int lineCount = len/2; - //vertical - // Sort the lines - - qsort(vertical, len/2, sizeof(struct Line), compare_Vertical_Lines); - - // We assume the lines are sorted by their x-coordinate (for vertical lines) - float averageDistance = 0; - int count = 0; - - // Calculate average distance between lines - for (int i = 0; i < lineCount - 1; ++i) { - averageDistance += fabs(vertical[i + 1].start.x - vertical[i].start.x); - count++; - } - if (count > 0) averageDistance /= count; - printf("averageDistance %f \n",averageDistance); - - float tolerance = averageDistance * 0.2; // 20% tolerance - int foundCount = 0, i = 0; - - // Look for a sequence of 10 lines with consistent spacing - while (foundCount < topCount && i <= lineCount - 10) { - if (isEvenlySpacedSequence_vertical(vertical, i, 10, averageDistance, tolerance)) { - for (int j = i; j < i + 10 && foundCount < topCount; j++) { - - topLinesv[foundCount].start.x = vertical[j].start.x; - topLinesv[foundCount].start.y = vertical[j].start.y; - topLinesv[foundCount].end.x = vertical[j].end.x; - topLinesv[foundCount].end.y = vertical[j].end.y; - - foundCount++; - printf("vertical1 %d: Start (%f, %f) - End (%f, %f)\n", j, - topLinesv[foundCount].start.x, topLinesv[foundCount].start.y, - topLinesv[foundCount].end.x, topLinesv[foundCount].end.y); - - - } - break; // Found a sequence, exit loop - } else { - i++; - } - } - /*for (int i = 0; i < 10; ++i) { - printf("topLinesv %d: Start (%f, %f) - End (%f, %f)\n", i, - topLinesv[i].start.x, topLinesv[i].start.y, - topLinesv[i].end.x, topLinesv[i].end.y); - - }*/ - - //horizon - //vertical - // Sort the lines - qsort(horizon, len/2, sizeof(struct Line), compare_Horizon_Lines); - - // We assume the lines are sorted by their x-coordinate (for vertical lines) - float averageDistancey = 0; - int county = 0; - - // Calculate average distance between lines - for (int i = 0; i < lineCount - 1; ++i) { - averageDistancey += fabs(horizon[i + 1].start.y - horizon[i].start.y); - county++; - } - if (county > 0) averageDistancey /= county; - - float tolerancey = averageDistance * 0.2; // 20% tolerance - int foundCounty = 0, iy = 0; - - - // Look for a sequence of 10 lines with consistent spacing - while (foundCounty < topCount && iy <= lineCount - 10) { - if (isEvenlySpacedSequence_horizon(horizon, iy, 10, averageDistancey, tolerancey)) { - for (int j = iy; j < iy + 10 && foundCounty < topCount; j++) { - topLinesh[foundCounty].start.x = horizon[j].start.x; - topLinesh[foundCounty].start.y = horizon[j].start.y; - topLinesh[foundCounty].end.x = horizon[j].end.x; - topLinesh[foundCounty].end.y = horizon[j].end.y; - foundCounty++; - } - break; // Found a sequence, exit loop - } else { - iy++; - } - } -} - -void print_h_v(struct Line* lines, int len, struct Line* horizon, struct Line* vertical, -struct Line* topLinesh,struct Line* topLinesv) -{ - - if (!horizon || !vertical) - { - fprintf(stderr, "Memory allocation failed.\n"); - free(horizon); - free(vertical); - return; - } - - horizontal_vertical_lines(lines, len, horizon, vertical); - - - - sort_horizontal_lines(horizon, len /2 ); - - - sort_vertical_lines(vertical, len/2); - - get_sudoku_lines (vertical, horizon, topLinesv, topLinesh, len) ; - - free(horizon); - free(vertical); - -} - - -void printvalues(struct Line* lines, int len) -{ - struct Line* horizon = calloc( len/2, sizeof(struct Line)); - struct Line* vertical = calloc( len/2, sizeof(struct Line)); - - if (!horizon || !vertical) - { - fprintf(stderr, "Memory allocation failed.\n"); - free(horizon); - free(vertical); - return; - } - - horizontal_vertical_lines(lines, len, horizon, vertical); - - sort_horizontal_lines(horizon, len /2 ); - - sort_vertical_lines(vertical, len/2); - - struct Line* topLinesh = calloc( 10, sizeof(struct Line)); - struct Line* topLinesv = calloc( 10, sizeof(struct Line)); - - get_sudoku_lines (vertical, horizon, topLinesv, topLinesh, len) ; - - - len = 20; - - int num_squares = (len/2 -1) * (len/2 -1); - - struct Squares* squares = calloc(num_squares, sizeof(struct Squares)); - -/* if (!squares) { - fprintf(stderr, "Memory allocation failed.\n");*/ - - fillsquares(topLinesv, topLinesh, squares, 10); - - - for (int i = 0; i < num_squares; i++) - { - printf("%i \n",i); - printf("Top Left: (%f, %f)\n", - squares[i].topleft.x, squares[i].topleft.y); - printf("Top Right: (%f, %f)\n", - squares[i].topright.x, squares[i].topright.y); - printf("Bottom Right: (%f, %f)\n", - squares[i].bottomright.x, squares[i].bottomright.y); - printf("Bottom Left: (%f, %f)\n", - squares[i].bottomleft.x, squares[i].bottomleft.y); - printf("\n"); - - } - free(horizon); - free(vertical); - free(squares); -} - - -//Calculate the average with and height of the squares -void calculate_average_dimensions(struct Squares* squares, int num_squares, -float *average_width, float *average_height) { - -//int n = 0; - float total_width = 0, total_height = 0; - - for (int i = 0; i < num_squares; i++) - { - float width = squares[i].topright.x - squares[i].topleft.x; - float height = squares[i].bottomleft.y - squares[i].topleft.y; - - //if (fabs(width - height) <10) - //{ - total_width += width; - total_height += height; - - //} - } - if (num_squares > 0) { - *average_width = total_width / num_squares; - *average_height = total_height / num_squares; - } else { - *average_width = 0; - *average_height = 0; - } -} - -//sort squares in order -int compare_squares(const void *a, const void *b) { - struct Squares *squareA = (struct Squares *)a; - struct Squares *squareB = (struct Squares *)b; - - // First sort by top Y coordinate, then by left X coordinate - if (squareA->topleft.y < squareB->topleft.y) return -1; - if (squareA->topleft.y > squareB->topleft.y) return 1; - if (squareA->topleft.x < squareB->topleft.x) return -1; - if (squareA->topleft.x > squareB->topleft.x) return 1; - - return 0; -} - -void sort_squares_horizontal(struct Squares* squares, int num_squares) { - qsort(squares, num_squares, sizeof(struct Squares), compare_squares); -} - - - -struct Squares* drawsquares(struct Line* lines, int len) -{ - struct Line* horizon = calloc( len/2, sizeof(struct Line)); - struct Line* vertical = calloc( len/2, sizeof(struct Line)); - - if (!horizon || !vertical) - { - fprintf(stderr, "Memory allocation failed.\n"); - free(horizon); - free(vertical); - } - - horizontal_vertical_lines(lines, len, horizon, vertical); - - sort_horizontal_lines(horizon, len /2 ); - - sort_vertical_lines(vertical, len/2); - - int num_squares = (len/2 -1) * (len/2 -1); - -// struct Squares* sq = calloc(num_squares, sizeof(struct Squares)); - - struct Squares* sq = calloc(num_squares, sizeof(struct Squares)); - -/* if (!squares) { - fprintf(stderr, "Memory allocation failed.\n");*/ - fillsquares(vertical, horizon, sq, len/2); - - - //sort_squares_horizontal(sq, num_squares); - - - return sq; -/* free(horizon); - free(vertical); - free(squares);*/ -} - - - - - - -// Function to check if the squares are part of a consistent sequence -int isPartOfSequence(struct Squares* squares, int index, int num_squares, float average_dimension, float tolerance) { - const int sequenceLength = 10; // Looking for 10 squares in sequence - - if (index + sequenceLength > num_squares) { - return 0; // Not enough squares left for a full sequence - } - - for (int i = index; i < index + sequenceLength - 1; i++) { - float distance = squares[i + 1].topleft.x - squares[i].topleft.x; - if (fabs(distance - average_dimension) > tolerance) { - return 0; // Distance is outside of tolerance - } - } - return 1; // All distances within sequence are within tolerance -} - -// Find the horizontal and vertical edges of the Sudoku -int findSudokuEdges(struct Squares* squares, int num_squares, float average_dimension) { - float tolerance = average_dimension * 0.2; // 20% tolerance - - - - // struct Squares horizontalEdges[2]; // Top and bottom horizontal lines - //struct Squares verticalEdges[2]; // Left and right vertical lines - - int i = 0; - // Find vertical edges - while( i < num_squares) { - if (isPartOfSequence(squares, i, num_squares, average_dimension, tolerance)) { - //verticalEdges[0] = squares[i]; // Left edge - //verticalEdges[1] = squares[i + 9]; // Right edge - return i; - break; - } - i++; - } - return 0; - //int edges_length = verticalEdges[1].topright.x - verticalEdges[1].topleft.x; - - //horizontalEdges[1] = squares[i+ 72]; -} - - - - - -// Function to extract and save squares as images -void extract_and_save_squares(SDL_Surface* original_image, struct Squares* squares, int num_squares) { - - const int target_width = 28; - const int target_height = 28; - int j = 0; - - float average_width, average_height; - calculate_average_dimensions(squares, num_squares, &average_width, &average_height); - - int k = findSudokuEdges(squares, num_squares, average_width); - - - for (int i = k; i < k+ 89; i++) - { - float width = squares[i].topright.x - squares[i].topleft.x; - float height = squares[i].bottomleft.y - squares[i].topleft.y; - - // Check if the square's dimensions are close to the average - if ((fabs(width - average_width) < 100 || fabs(height - average_height) < 100 ) && fabs(width - height) < 50) - { - // Skip this square as its dimensions are too different - - // Create a new surface for each square - SDL_Surface* square_surface = SDL_CreateRGBSurface(0, width, height, original_image->format->BitsPerPixel, - original_image->format->Rmask, original_image->format->Gmask, - original_image->format->Bmask, original_image->format->Amask); - - if (square_surface == NULL) { - fprintf(stderr, "SDL_CreateRGBSurface failed: %s\n", SDL_GetError()); - continue; // Skip this square and move to the next - } - - // Define the rectangle to be copied - SDL_Rect square_rect; - square_rect.x = squares[i].topleft.x; - square_rect.y = squares[i].topleft.y; - square_rect.w = width; - square_rect.h = height; - - // Blit the square area from the original image to the new surface - SDL_BlitSurface(original_image, &square_rect, square_surface, NULL); - - // Create a new surface for the resized square - SDL_Surface* resized_surface = SDL_CreateRGBSurface(0, target_width, target_height, original_image->format->BitsPerPixel, - original_image->format->Rmask, original_image->format->Gmask, - original_image->format->Bmask, original_image->format->Amask); - if (resized_surface == NULL) { - fprintf(stderr, "SDL_CreateRGBSurface failed for resized surface: %s\n", SDL_GetError()); - SDL_FreeSurface(square_surface); - continue; - } - - // Blit the square surface to the resized surface with scaling - SDL_BlitScaled(square_surface, NULL, resized_surface, NULL); - - // Save each square as an image - char filename[64]; - sprintf(filename, "square_%d.bmp", j); - j++; - if (SDL_SaveBMP(resized_surface, filename) != 0) { - fprintf(stderr, "SDL_SaveBMP failed: %s\n", SDL_GetError()); - } - - // Free the square surface after saving - SDL_FreeSurface(square_surface); - // SDL_FreeSurface(resized_surface); - } - } -} - - diff --git a/src/edge_detection/image.c b/src/edge_detection/image.c deleted file mode 100644 index aa8c082..0000000 --- a/src/edge_detection/image.c +++ /dev/null @@ -1,380 +0,0 @@ - -#include -#include -#include -#include -#include -#include -#include "image.h" - -// Loads an image in a surface. -// The format of the surface is SDL_PIXELFORMAT_RGB888. -// -// path: Path of the image. -SDL_Surface* load_image(const char* path) -{ - SDL_Surface* is = IMG_Load(path); - if (is == NULL) - errx(EXIT_FAILURE, "%s", SDL_GetError()); - - SDL_Surface* fs = SDL_ConvertSurfaceFormat(is, SDL_PIXELFORMAT_RGB888, 0); - if (fs == NULL) - errx(EXIT_FAILURE, "%s", SDL_GetError()); - - SDL_FreeSurface(is); - return fs; -} - - - -// pixel_color: Color of the pixel to convert in the RGB format. -// format: Format of the pixel used by the surface. -Uint32 pixel_to_grayscale(Uint32 pixel_color, SDL_PixelFormat* format) -{ - Uint8 r, g, b; - SDL_GetRGB(pixel_color, format, &r, &g, &b); - - double average = 0.3*r + 0.59*g + 0.11*b; - return SDL_MapRGB(format, average, average, average); -} - -void surface_to_grayscale(SDL_Surface* surface) -{ - Uint32* pixels = surface->pixels; - if (pixels == NULL) - errx(EXIT_FAILURE, "%s", SDL_GetError()); - - int len = surface->w * surface->h; - SDL_PixelFormat* format = surface->format; - - if (format == NULL || pixels == NULL || SDL_LockSurface(surface) != 0) - errx(EXIT_FAILURE, "%s", SDL_GetError()); - - for (int i = 0; i < len; i++) - { - pixels[i] = pixel_to_grayscale(pixels[i], format); - } - - SDL_UnlockSurface(surface); -} - - -void surface_to_inverse(SDL_Surface* surface) -{ - Uint32* pixels = surface->pixels; - if (pixels == NULL) - errx(EXIT_FAILURE, "%s", SDL_GetError()); - - int len = surface->w * surface->h; - SDL_PixelFormat* format = surface->format; - - if (format == NULL || pixels == NULL || SDL_LockSurface(surface) != 0) - errx(EXIT_FAILURE, "%s", SDL_GetError()); - - for (int i = 0; i < len; i++) - { - Uint8 r, g, b; - SDL_GetRGB(pixels[i], format, &r, &g, &b); - if (r == 255) - r =0; - else{ - r = 255; - } - if (g == 255) - g =0; - else{ - g = 255; - } - if (b == 255) - b = 0; - else{ - b = 255; - } - - pixels[i] = SDL_MapRGB(format, r, g, b); - - } - - SDL_UnlockSurface(surface); -} - - - - - -Uint32* integral_image(SDL_Surface* surface) { - Uint32* integral = malloc(surface->w * surface->h * sizeof(Uint32)); - if (!integral) { - errx(EXIT_FAILURE, "Memory allocation for integral image failed"); - } - - SDL_LockSurface(surface); - - for (int y = 0; y < surface->h; y++) { - Uint32 sum = 0; - for (int x = 0; x < surface->w; x++) { - Uint32 pixel = ((Uint32*)surface->pixels)[y * surface->w + x]; - Uint8 r, g, b; - SDL_GetRGB(pixel, surface->format, &r, &g, &b); - Uint8 average = (r + g + b) / 3; - - sum += average; - if (y == 0) { - integral[y * surface->w + x] = sum; - } else { - integral[y * surface->w + x] = integral[(y - 1) * - surface->w + x] + sum; - } - } - } - - SDL_UnlockSurface(surface); - return integral; -} - -Uint8 fast_local_threshold(Uint32* integral, int x, int y, - int neighborhood_size, int width, int height) { - int side = neighborhood_size / 2; - int x1 = x - side - 1; - int y1 = y - side - 1; - int x2 = x + side; - int y2 = y + side; - - x1 = (x1 < 0) ? 0 : x1; - y1 = (y1 < 0) ? 0 : y1; - x2 = (x2 >= width) ? width - 1 : x2; - y2 = (y2 >= height) ? height - 1 : y2; - - int count = (x2 - x1) * (y2 - y1); - - Uint32 sum = integral[y2 * width + x2] - integral[y1 * width + x2] - - integral[y2 * width + x1] + integral[y1 * width + x1]; - return (Uint8)(sum / count); -} - - - -void surface_to_blackwhite(SDL_Surface* surface) { - int neighborhood_size = 15; - if (neighborhood_size % 2 == 0) neighborhood_size++; - - SDL_Surface* copy = SDL_ConvertSurfaceFormat(surface, - SDL_PIXELFORMAT_RGB888, 0); - if (!copy) { - errx(EXIT_FAILURE, "Unable to create surface copy: %s", SDL_GetError()); - } - - Uint32* integral = integral_image(copy); - - SDL_LockSurface(surface); - for (int y = 0; y < surface->h; y++) { - for (int x = 0; x < surface->w; x++) { - Uint8 local_threshold = fast_local_threshold(integral, x, y, - neighborhood_size, copy->w, copy->h); - - Uint32 pixel = ((Uint32*)surface->pixels)[y * surface->w + x]; - Uint8 r, g, b; - SDL_GetRGB(pixel, surface->format, &r, &g, &b); - Uint8 average = (r + g + b) / 3; - - if (average < local_threshold) { - ((Uint32*)surface->pixels)[y * surface->w + x] = - SDL_MapRGB(surface->format, 0, 0, 0); - } else { - ((Uint32*)surface->pixels)[y * surface->w + x] = - SDL_MapRGB(surface->format, 255, 255, 255); - } - } - } - - SDL_UnlockSurface(surface); - - SDL_FreeSurface(copy); - free(integral); -} - - - -// Adjusts the contrast of a single pixel. -// -// pixel_color: Color of the pixel to adjust in the RGB format. -// format: Format of the pixel used by the surface. -// contrast: Contrast adjustment factor (e.g., 1.5 for increasing contrast). -Uint32 pixel_to_contrast(Uint32 pixel_color, SDL_PixelFormat* format, - float contrast) -{ - Uint8 r, g, b; - SDL_GetRGB(pixel_color, format, &r, &g, &b); - - // Here, we shift the range from [0, 255] to [-128, 127] - // before adjusting contrast - float shifted_contrast_scale = (contrast - 1.0) * 128.0; - - // Adjust contrast - int new_r = r + (int)((r - 128) * shifted_contrast_scale / 128.0); - int new_g = g + (int)((g - 128) * shifted_contrast_scale / 128.0); - int new_b = b + (int)((b - 128) * shifted_contrast_scale / 128.0); - - // Clamp the values to the [0, 255] range - new_r = new_r > 255 ? 255 : new_r < 0 ? 0 : new_r; - new_g = new_g > 255 ? 255 : new_g < 0 ? 0 : new_g; - new_b = new_b > 255 ? 255 : new_b < 0 ? 0 : new_b; - - // Return the new color - return SDL_MapRGB(format, new_r, new_g, new_b); - -} - - -// Adjusts the contrast of an SDL surface. -// -// surface: The SDL surface to adjust. -// contrast: Contrast adjustment factor (e.g., 1.5 for increasing contrast). -void surface_to_contrast(SDL_Surface* surface, float contrast) -{ - Uint32* pixels = surface->pixels; - if (pixels == NULL) - errx(EXIT_FAILURE, "%s", SDL_GetError()); - - int len = surface->w * surface->h; - SDL_PixelFormat* format = surface->format; - if (format == NULL) - errx(EXIT_FAILURE, "%s", SDL_GetError()); - - int i = 0; - SDL_LockSurface(surface); - - while (i < len) { - pixels[i] = pixel_to_contrast(pixels[i], format, contrast); - i++; - } - - SDL_UnlockSurface(surface); -} - - -float** generate_Kernel(int ksize, float sigma) -{ - float sum = 0.0; - - int center = ksize /2; - - - //The kernel matrix is a double pointer - - float** kernel = (float**)malloc(ksize * sizeof(float*)); - - for (int i = 0; i < ksize; i++) { - kernel[i] = (float*)malloc(ksize * sizeof(float));} - - for (int y = 0; y < ksize; y++) { - for (int x = 0; x < ksize; x++) { - - int mx = x - center; - int my = y - center; - double tmp = -(mx * mx + my * my) / (2 * sigma * sigma); - - kernel[y][x] = 1. / (2 * M_PI * sigma * sigma) * exp(tmp); - sum += kernel[y][x]; - } - } - - for (int y = 0; y < ksize; y++) { - for (int x = 0; x < ksize; x++) { - kernel[y][x] /= sum; - } - } - return kernel; -} - - - - -void applyblur (SDL_Surface * image, float** kernel, - int kernelsize, SDL_Surface* filteredimage) -{ - int imageWidth = image->w; - int imageHeight = image->h; - int center = kernelsize /2; - - - //iterating through each pixel in the input image - for (int y = 0; y < imageHeight; y++) { - for (int x = 0; x < imageWidth; x++) { - - float finalr = 0.0; - float finalb = 0.0; - float finalg = 0.0; - - for (int ky = 0; ky < kernelsize; ky++) { - for (int kx = 0; kx < kernelsize; kx++) { - - - - int Xf = x + kx - center; - int Yf = y + ky - center; - - //check if we are outside of the array - if (Xf >= 0 && Xf < imageWidth && Yf < imageHeight - && Xf >=0) { - Uint32* pixelinitial = (Uint32*)image->pixels; - - - Uint32 pi = pixelinitial[Yf * imageWidth + Xf]; - - Uint8 r,g,b,a; - SDL_GetRGBA(pi, image->format, &r, &g, &b, &a); - - finalr += kernel[kx][ky] * r; - finalb += kernel[kx][ky] *b; - finalg += kernel[kx][ky] *g; - } - //if we are outside of the image boundaries, - //the values are treated as being zero. - } - } - Uint32 newPixelValue = SDL_MapRGBA(filteredimage->format, - (Uint8)finalr, (Uint8)finalg, (Uint8)finalb, 255); - ((Uint32*)filteredimage->pixels)[y * imageWidth + x] = - newPixelValue; - - - } - } -} - - - - - -void surface_to_reducenoise(SDL_Surface* surface) -{ - // Define the kernel size and sigma for Gaussian blur - int kernelSize = 9; - float sigma = 10.0; - - // Generate the Gaussian kernel - float** kernel = generate_Kernel(kernelSize, sigma); - - SDL_Surface* outputimage = SDL_CreateRGBSurface(0, - surface->w, surface->h, 32, 0, 0, 0, 0); - if (outputimage == NULL) - errx(EXIT_FAILURE, "%s", SDL_GetError()); - - - applyblur (surface, kernel, kernelSize, outputimage); - - SDL_BlitSurface(outputimage, NULL, surface, NULL); - - SDL_FreeSurface(outputimage); - - - //IMG_SavePNG(outputImage, "output_image.png"); - - // Clean up - for (int i = 0; i < kernelSize; i++) { - free(kernel[i]); - } - free(kernel); -} - diff --git a/src/edge_detection/image.h b/src/edge_detection/image.h deleted file mode 100644 index a664660..0000000 --- a/src/edge_detection/image.h +++ /dev/null @@ -1,21 +0,0 @@ - -#ifndef IMAGE_H -#define IMAGE_H - -void surface_to_grayscale(SDL_Surface* surface); -Uint32 pixel_to_grayscale(Uint32 pixel_color, SDL_PixelFormat* format); -SDL_Surface* load_image(const char* path); -void surface_to_blackwhite(SDL_Surface* surface); -Uint32* intergral_image(SDL_Surface* surface); -Uint8 fast_local_threshold(Uint32* integral, int x, int y, - int neighborhood_size, int width, int height); - -void surface_to_contrast(SDL_Surface* surface, float contrast); -Uint32 pixel_to_contrast(Uint32 pixel_color, SDL_PixelFormat* format, - float contrast); -float** generate_Kernel(int ksize, float sigma); -void applyblur (SDL_Surface * image, float** kernel, int kernelsize, - SDL_Surface* filteredimage); -void surface_to_reducenoise(SDL_Surface* surface); -void surface_to_inverse(SDL_Surface* surface); -#endif diff --git a/src/image_processing/.DS_Store b/src/image_processing/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..8d3f1bfedb0724ff748e8fbb28e5e154d76b9bbf GIT binary patch literal 6148 zcmeHKOHRWu5PdEcROO>CVS$tjP!+)fc4^fvSg?T$&>y9uG!>M6_S}Iha6VS>#jVf5Jvndf77cEG|_v{jl%yBVGhJ#r$;ImAq zq6{blf13e$cdHnok0tuK_qWZl=7$wq#1^J_pydQ(G%*aV&HGyGyU@BaS!%xQ*kXpcAAzh*M8V}VB`7}Dd3*A#P1LLc*zi*ZoqgCm^c4ClOBIH9)4 zL_%GXnMF9G%_7U+PU(zACZ*bJ_N)AIEEVEy;tD;q(Is2GFgLqe*%)=p4}Sx!WXg)> z#TB+|_MJ~|of#cwFIWj#hcHe_9f1$&Q27A{xMz#hwjFA#3@8K2z!wAZeTb-nvB%V* z{dBOgM*w1#-Bx&S|N0Xn=^(})Q-|!K80SiKuErlRj6XRT=g#ri+ouklJB*FYd3rKTYdfyo%Bf=PzL@L1E$)&?siy`-&+gC$zB^# sZ>S<-mpZgAZ2Wd?Z)7Xpr&{4yBsav^W9pDS6#XM$Y0yR)_*Diz0r=>^jsO4v literal 0 HcmV?d00001 diff --git a/src/image_processing/Makefile b/src/image_processing/Makefile index c60ea68..6d9f2b8 100644 --- a/src/image_processing/Makefile +++ b/src/image_processing/Makefile @@ -8,14 +8,14 @@ LDLIBS = `pkg-config --libs sdl2 SDL2_image` -lm all: processing -SRC = processing.c image.c rotation.c detection.c square_detection.c +SRC = processing.c image.c rotation.c DEPS = ${SRC:.c=.d} OBJ = ${SRC:.c=.o} EXE = ${SRC:.c=} .PHONY: clean -processing: image.o processing.o rotation.o detection.o square_detection.o +processing: image.o processing.o rotation.o clean: ${RM} ${DEPS} diff --git a/src/image_processing/detection.c b/src/image_processing/detection.c deleted file mode 100644 index 2043db4..0000000 --- a/src/image_processing/detection.c +++ /dev/null @@ -1,211 +0,0 @@ -#include -#include -#include -#include "detection.h" -#include - - -#define true 1 -#define false 0 - - -float distance(struct Point a, struct Point b) -{ - return sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y)); -} - -int thelinebelongs(struct Line l1, struct Line l2) -{ - - //if (fabs(l1.rho - l2.rho) <= rhoThreshold && fabs(l1.theta - l2.theta) <= thetaThreshold) - - float startDistance = distance(l1.start, l2.start); - float endDistance = distance(l1.end, l2.end); - - if (startDistance < startThreshold && endDistance < endThreshold) - return 1; - return 0; -} - -void addtogroup(struct Line line, struct Linegroup* group) -{ - group->average.start.x = (group->average.start.x * group->numlines + line.start.x) / (group->numlines + 1); - group->average.start.y = (group->average.start.y * group->numlines + line.start.y) / (group->numlines + 1); - group->average.end.x = (group->average.end.x * group->numlines + line.end.x) / (group->numlines + 1); - group->average.end.y = (group->average.end.y * group->numlines + line.end.y) / (group->numlines + 1); - group->numlines +=1; -} - -int averagelines(struct Line* line, int len, struct Linegroup** group) { - int n = 10; - int ncurrent = 0; - - for(int i = 0; i < len; i++) - { - int loner = true; - for(int j = 0; j < ncurrent; j++) - { - if(thelinebelongs(line[i], group[j]->average) == 1) - { - addtogroup(line[i], group[j]); - loner = false; - } - } - if (loner) - { - if(ncurrent == n) - { - n *= 2; - group = realloc(group, n * sizeof(struct Linegroup*)); - - if (!group) - { - fprintf(stderr, "Memory allocation failed.\n"); - exit(EXIT_FAILURE); - } - - for (int j = ncurrent; j < n; j++) - { - group[j] = NULL; - } - } - group[ncurrent] = calloc(1, sizeof(struct Linegroup)); - if (!group[ncurrent]) - { - fprintf(stderr, "Memory allocation failed.\n"); - exit(EXIT_FAILURE); - } - group[ncurrent]->average.start.x = line[i].start.x; - group[ncurrent]->average.start.y = line[i].start.y; - - group[ncurrent]->average.end.x = line[i].end.x; - group[ncurrent]->average.end.y = line[i].end.y; - - group[ncurrent]->numlines = 1; - ncurrent++; - } - } - return ncurrent; - -} - -void drawl(struct Line* line, int len, SDL_Renderer* renderer) -{ - struct Linegroup** group = calloc(len, sizeof(struct Linegroup*)); // use len as it represents the number of lines - if (!group) { - fprintf(stderr, "Memory allocation failed.\n"); - exit(EXIT_FAILURE); - } - int nmax = averagelines(line, len, group); - - for(int i = 0; i < nmax; i++) - { - SDL_SetRenderDrawColor(renderer, 255, 0, 0, SDL_ALPHA_OPAQUE); // Red color for the lines - SDL_RenderDrawLine(renderer, group[i]->average.start.x, group[i]->average.start.y, - group[i]->average.end.x, group[i]->average.end.y); - } - for (int i = 0; i < nmax; i++) - free(group[i]); - free(group); -} - - - - - - - - - - - - - - - - - - - - - - - - -/* -float distance(struct Point a, struct Point b) -{ - return sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y)); -} - - -int thelinebelongs (struct Line l1, struct Line l2) -{ - if (fabs(l1.rho - l2.rho) < rhoThreshold && fabs(l1.theta - l2.theta) < thetaThreshold) - return 1; - return 0; -} - -void addtogroup(struct Line line, struct Linegroup* group) -{ - group->average.start.x =(group->average.start.x * group.numlines + line.start.x) / (group.numlines + 1); - group->average->star =(group->average->start->y * group->numlines + line->start->y) / (group->numlines + 1); - group->average.end- =(group->average.end * group.numlines + line.end) / (group.numlines + 1); - group->average->end->y =(group->average->end->y * group->numlines + line->end->y) / (group->numlines + 1); - group->numlines +=1; -} - - -int averagelines( struct Line* line,int len, SDL_Surface* image, struct Linegroup** group) -{ - - int n = 10; - //Linegroup** group = calloc(n,sizeof(struct Linegroup*)); - int ncurrent = 0; - - for(int i = 0; i < len; i++) - { - int loner = true; //0 if the line does not have a group - for(int j = 0; j <=ncurrent; j++) - { - if(thelinebelongs( line[i], group[j]) == 1) - { - addtogroup(line[i], group[j]); - loner = false; - } - - } - if (loner) - { - if(ncurrent == n) - { - n*=2; - group = realloc(group, n* sizeof(struct Linegroup*)); - } - group[ncurrent] = calloc(1, sizeof(struct Linegroup)); - group[ncurrent]->average.start = line[i].star; - group->average->start->y = line[i]->start->y; - group[ncurrent]->averag.>end = line[i].end; - group->average->end->y = line[i]->end->y; - group->numlines = 1; - ncurrent++; - - } - } - return ncurrent; -} - - - -void drawl(SDL_Surface*image, struct Line* line, int len,SDL_Renderer* renderer) -{ struct Linegroup** group = calloc(n,sizeof(struct Linegroup*)); - - int nmax = averagelines(line, len, image,group); - - for(int i = 0; i < nmax; i++) - { - - SDL_SetRenderDrawColor(renderer, 255, 0, 0, SDL_ALPHA_OPAQUE); // Red color for the lines - SDL_RenderDrawLine(renderer, group[i]->average.start.x, group[i]->average.start.y,group[i]->average.end.x, group[i]->average.end.y); - } -}*/ diff --git a/src/image_processing/detection.h b/src/image_processing/detection.h deleted file mode 100644 index e62d939..0000000 --- a/src/image_processing/detection.h +++ /dev/null @@ -1,27 +0,0 @@ -#ifndef DETECTION_H -#define DETECTION_H - -#define startThreshold 15 -#define endThreshold 15 - - -struct Point { - float x; - float y; -}; - -struct Line { - float rho ; - float theta; - struct Point start; - struct Point end; -}; - - struct Linegroup { - struct Line average; - int numlines; -} ; - - -void drawl(struct Line* line, int len,SDL_Renderer* renderer); -#endif diff --git a/src/image_processing/processing.c b/src/image_processing/processing.c index 0085e2c..fbf4d70 100644 --- a/src/image_processing/processing.c +++ b/src/image_processing/processing.c @@ -4,8 +4,6 @@ #include #include "image.h" #include "rotation.h" -#include "detection.h" -#include "square_detection.h" void draw(SDL_Renderer* renderer, SDL_Texture* texture) { @@ -19,56 +17,6 @@ void draw(SDL_Renderer* renderer, SDL_Texture* texture) SDL_RenderPresent(renderer); } - -void draw_test_averagelines(SDL_Renderer* renderer, SDL_Texture* texture, - struct Line* lines) -{ - int render = SDL_RenderCopy(renderer, texture, NULL, NULL); - if (render != 0) - errx(EXIT_FAILURE, "%s", SDL_GetError()); - - - drawl(lines, 26, renderer); - - -/* for (int i = 0; i <26;i++) - { - - SDL_SetRenderDrawColor(renderer, 0, 0, 255, 255); - - // Draw a line - SDL_RenderDrawLine(renderer, lines[i].start.x ,lines[i].start.y, - lines[i].end.x, lines[i].end.y); - } - - */ - - SDL_RenderPresent(renderer); -} - - -void event_loop_image_test_averagelines(SDL_Renderer* renderer, - SDL_Texture* t_image, struct Line* lines) { - SDL_Event event; - - draw(renderer, t_image); - while (1) { - SDL_WaitEvent(&event); - - switch (event.type) { - case SDL_QUIT: - return; - case SDL_WINDOWEVENT: - if (event.window.event == SDL_WINDOWEVENT_RESIZED) { - draw_test_averagelines(renderer, t_image, lines); - //drawl(lines, 6, renderer); - break; - } - } - } -} - - void event_loop_image(SDL_Renderer* renderer, SDL_Texture* t_image) { SDL_Event event; @@ -240,8 +188,6 @@ int main(int argc, char** argv) Canny_edge_result (surface); IMG_SaveJPG(surface,"canny.jpg",100); -// hough_transform(surface, 10,renderer); -// IMG_SaveJPG(surface,"hough.jpg",100); SDL_Texture* process_texture = SDL_CreateTextureFromSurface(renderer, @@ -277,100 +223,6 @@ int main(int argc, char** argv) SDL_DestroyTexture(im_txt); } } - - - - else if (strcmp(argv[1], "detection") == 0) { - /* struct Line* lines = (struct Line*)calloc(6, sizeof(struct Line)); - if (!lines) { - fprintf(stderr, "Memory allocation failed.\n"); - exit(EXIT_FAILURE); - } - lines[0] = (struct Line){10, 0.0, {10, 0}, {500, 0}}; - lines[1] = (struct Line){20, 0.0, {20, 0}, {500, 0}}; - lines[2] = (struct Line){30, 0.0, {30, 0}, {500, 0}}; - lines[3] = (struct Line){0, 1.5708, {0, 10}, {0, 700}}; - lines[4] = (struct Line){0, 1.5708, {0, 20}, {0, 700}}; - lines[5] = (struct Line){0, 1.5708, {0, 30}, {0, 700}};*/ - - - struct Line lines[26]; // There are 8 horizontal - // and 8 vertical lines - int L = 500; - // Vertical lines - lines[0] = (struct Line){L/9, 0.0, {L/9, 0}, {L/9, L}}; - lines[1] = (struct Line){2*L/9, 0.0, {2*L/9, 0}, {2*L/9, L}}; - lines[2] = (struct Line){3*L/9, 0.0, {3*L/9, 0}, {3*L/9, L}}; - lines[3] = (struct Line){4*L/9, 0.0, {4*L/9, 0}, {4*L/9, L}}; - lines[4] = (struct Line){5*L/9, 0.0, {5*L/9, 0}, {5*L/9, L}}; - lines[5] = (struct Line){6*L/9, 0.0, {6*L/9, 0}, {6*L/9, L}}; - lines[6] = (struct Line){7*L/9, 0.0, {7*L/9, 0}, {7*L/9, L}}; - lines[7] = (struct Line){8*L/9, 0.0, {8*L/9, 0}, {8*L/9, L}}; - - // Horizontal lines - lines[8] = (struct Line){0.0, 5, {0, L/9}, {L, L/9}}; - lines[9] = (struct Line){0.0, 15, {0, 2*L/9}, {L, 2*L/9}}; - lines[10] = (struct Line){0.0, 25, {0, 3*L/9}, {L, 3*L/9}}; - lines[11] = (struct Line){0.0,35, {0, 4*L/9}, {L, 4*L/9}}; - lines[12] = (struct Line){0.0, 45, {0, 5*L/9}, {L, 5*L/9}}; - lines[13] = (struct Line){0.0, 55, {0, 6*L/9}, {L, 6*L/9}}; - lines[14] = (struct Line){0.0, 65, {0, 7*L/9}, {L, 7*L/9}}; - lines[15] = (struct Line){0.0, 75, {0, 8*L/9}, {L, 8*L/9}}; - - // Assume the dimension of the Sudoku grid is L x L - // Also assume a small deviation factor, say 5 pixels - const int deviation = 5; - - // Noisy lines around the first vertical line - lines[16] = (struct Line){L/9 - deviation, 0.0, - {L/9 - deviation, 0}, {L/9 - deviation, L}}; - lines[17] = (struct Line){L/9, 0.0, {L/9, 0}, {L/9, L}}; - lines[18] = (struct Line){L/9 + deviation, 0.0, - {L/9 + deviation, 0}, {L/9 + deviation, L}}; - lines[19] = (struct Line){L/9 - 2*deviation, 0.0, - {L/9 - 2*deviation, 0}, {L/9 - 2*deviation, L}}; - lines[20] = (struct Line){L/9 + 2*deviation, 0.0, - {L/9 + 2*deviation, 0}, {L/9 + 2*deviation, L}}; - - // Noisy lines around the first horizontal line - lines[21] = (struct Line){0.0, 1.5708, {0, L/9 - deviation}, - {L, L/9 - deviation}}; - lines[22] = (struct Line){0.0, 1.5708, {0, L/9}, {L, L/9}}; - lines[23] = (struct Line){0.0, 1.5708, {0, L/9 + deviation}, - {L, L/9 + deviation}}; - lines[23] = (struct Line){0.0, 1.5708, {0, L/9 - 2*deviation}, - {L, L/9 - 2*deviation}}; - lines[25] = (struct Line){0.0, 1.5708, {0, L/9 + 2*deviation}, - {L, L/9 + 2*deviation}}; - - - - SDL_Texture* grayscale_texture = - SDL_CreateTextureFromSurface(renderer, surface); - if (grayscale_texture == NULL) - errx(EXIT_FAILURE, "%s", SDL_GetError()); - - SDL_FreeSurface(surface); - event_loop_image_test_averagelines(renderer, grayscale_texture, - lines); - SDL_DestroyTexture(grayscale_texture); - } - - /* PLEASE LEAVE THE EXAMPLE ! - if (strcmp(argv[1], "FILTER NAME") == 0){ - surface_to_"FILTER NAME"(surface); - SDL_Texture* "FILTER NAME"_texture = - SDL_CreateTextureFromSurface(renderer, surface); - if ("FILTER NAME"_texture == NULL) - errx(EXIT_FAILURE, "%s", SDL_GetError()); - - SDL_FreeSurface(surface); - event_loop_image(renderer, "FILTER NAME"_texture); - SDL_DestroyTexture("FILTER NAME"_texture); - - } - */ - else { errx(EXIT_FAILURE, "Unsupported filter: %s", argv[1]); } @@ -381,7 +233,3 @@ int main(int argc, char** argv) return EXIT_SUCCESS; } - -//printf("i think Ali is the goat...") - - diff --git a/src/image_processing/square_detection.c b/src/image_processing/square_detection.c deleted file mode 100644 index a40bc43..0000000 --- a/src/image_processing/square_detection.c +++ /dev/null @@ -1,157 +0,0 @@ -#include -#include -#include "square_detection.h" -#include -//#include "detection.c" - -struct Square { - struct Point topleft; - struct Point topright; - struct Point bottomleft; - struct Point bottomright; -}; - -void horizontal_vertical_lines( struct Line* lines, int len, - struct Line* horizon, struct Line* vertical) -{ - //thtea en degree - int j = 0, k = 0; - for (int i = 0; i < len; i++) - { - float t = lines[i].theta; - if ( (t>= -10 && t <= 10) || (t>= 170 && t<=190)) - { - vertical[j] = lines[i]; - j++; - } - else - { - horizon[k] = lines[i]; - k++; - } - } - //return (j+1,k+1); -} - -void sort_horizontal_lines(struct Line* horizon, int len) -{ - int i, j; - struct Line compare; - - for (i = 1; i < len; i++) - { - //printf("(%f,%f)",horizon[i].start.x,horizon[i].start.y); - compare = horizon[i]; - j = i - 1; - - while (j >= 0 && horizon[j].start.y > compare.start.y) - { - horizon[j + 1] = horizon[j]; - j = j - 1; - } - horizon[j + 1] = compare; - } - - -} - -void sort_vertical_lines(struct Line* vertical, int len) -{ - int i, j; - struct Line compare; - - for (i = 1; i < len; i++) - { - compare = vertical[i]; - j = i - 1; - - // Move elements that are greater than key to one position - // ahead of their current position - while (j >= 0 && vertical[j].start.x > compare.start.x) - { - vertical[j + 1] = vertical[j]; - j = j - 1; - } - vertical[j + 1] = compare; - } - -/* for(int k = 0; k