OCR project
This commit is contained in:
		
							
								
								
									
										571
									
								
								ImageTreatment/Segmentation/segmentation.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										571
									
								
								ImageTreatment/Segmentation/segmentation.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,571 @@ | ||||
| #include "segmentation.h" | ||||
|  | ||||
| /*find if a line contain black pixel*/ | ||||
| /*If contain a black pixel return 0*/ | ||||
| /*x is the height*/ | ||||
| int FindBlackPixel(SDL_Surface *img, int x) | ||||
| { | ||||
|     Uint32 pixel; | ||||
|     int w = img->w; | ||||
|     Uint8 r, g, b; | ||||
|     /*A boolean that memorize if the line contain black pixel ornot*/ | ||||
|     int bool = 1; | ||||
|  | ||||
|     for (int i = 0; i < w; i++) | ||||
|     { | ||||
|         pixel = getpixel(img, i, x); | ||||
|         SDL_GetRGB(pixel, img->format, &r, &g, &b); | ||||
|  | ||||
|         if (r == 0) | ||||
|         { | ||||
|             bool = 0; | ||||
|             break; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     return bool; | ||||
| } | ||||
|  | ||||
| /*Main function which print line on image*/ | ||||
|  | ||||
| void CutLines(SDL_Surface *img, int d) | ||||
| { | ||||
|     Uint32 pixel; | ||||
|     Uint8 r, g, b; | ||||
|     int end_line = 0; | ||||
|     int begin_line = 0; | ||||
|     int w = img->w; | ||||
|     int h = img->h; | ||||
|     d = d % 2; | ||||
|  | ||||
|     for (int i = 0; i < h; i++) | ||||
|     { | ||||
|         for (int j = 0; j < w; j++) | ||||
|         { | ||||
|             pixel = getpixel(img, j, i); | ||||
|             SDL_GetRGB(pixel, img->format, &r, &g, &b); | ||||
|  | ||||
|             if (r == 0) /*after binerize is not necessary to test the others | ||||
|                            values*/ | ||||
|             { | ||||
|                 if (FindBlackPixel(img, i - 1)) | ||||
|                 { | ||||
|                     DrawALine(img, i - 1); | ||||
|                     begin_line = i - 1; | ||||
|                 } | ||||
|  | ||||
|                 if (FindBlackPixel(img, i + 1)) /*same but for the under line*/ | ||||
|                 { | ||||
|                     DrawALine(img, i + 1); | ||||
|                     end_line = i + 1; | ||||
|                 } | ||||
|  | ||||
|                 if (end_line && begin_line) | ||||
|                 { | ||||
|                     if (d) | ||||
|                     { | ||||
|                         CutColumn(img, begin_line, end_line); | ||||
|                     } | ||||
|                     end_line = 0; | ||||
|                     begin_line = 0; | ||||
|                 } | ||||
|                 break; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| /*draw a line if necessary*/ | ||||
| void DrawALine(SDL_Surface *img, int x) | ||||
| { | ||||
|     Uint32 pixel; | ||||
|     int w = img->w; | ||||
|  | ||||
|     for (int i = 0; i < w; i++) | ||||
|     { | ||||
|         pixel = SDL_MapRGB(img->format, 255, 150, 255); | ||||
|         putpixel(img, i, x, pixel); | ||||
|     } | ||||
| } | ||||
|  | ||||
| /*Main function for mark the column on the image*/ | ||||
| void CutColumn(SDL_Surface *img, int begin_line, int end_line) | ||||
| { | ||||
|     Uint8 r, g, b; | ||||
|     Uint32 pixel; | ||||
|     int w = img->w; | ||||
|  | ||||
|     for (int i = 0; i < w; i++) | ||||
|     { | ||||
|         for (int j = begin_line; j < end_line; j++) | ||||
|         { | ||||
|             pixel = getpixel(img, i, j); | ||||
|             SDL_GetRGB(pixel, img->format, &r, &g, &b); | ||||
|  | ||||
|             if (r == 0) /*after binerize is not necessary to test the others | ||||
|                            values */ | ||||
|             { | ||||
|                 if (FindBlackPixelInColumn( | ||||
|                         img, begin_line, end_line, | ||||
|                         i - 1)) /*For the first black pixel we meet, we check if | ||||
|                                    the upper line is full of white and then we | ||||
|                                    draw a line for mark the begin of a new | ||||
|                                    line*/ | ||||
|                 { | ||||
|                     DrawAColumn(img, i - 1, begin_line, end_line); | ||||
|                 } | ||||
|  | ||||
|                 if (FindBlackPixelInColumn( | ||||
|                         img, begin_line, end_line, | ||||
|                         i + 1)) /*same but for the under line*/ | ||||
|                 { | ||||
|                     DrawAColumn(img, i + 1, begin_line, end_line); | ||||
|                 } | ||||
|                 break; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| /*find if a column contain black pixel*/ | ||||
| /*If contain a black pixel return 0*/ | ||||
| /*start is the value on weight*/ | ||||
| /*begin_line and end_line the value on height*/ | ||||
| int FindBlackPixelInColumn(SDL_Surface *img, int begin_line, int end_line, | ||||
|                            int start) | ||||
| { | ||||
|     Uint32 pixel; | ||||
|     Uint8 r, g, b; | ||||
|     int bool = | ||||
|         1; /*A boolean that memorize if the line contain black pixel or not*/ | ||||
|  | ||||
|     for (int i = begin_line; i < end_line; i++) | ||||
|     { | ||||
|         pixel = getpixel(img, start, i); | ||||
|         SDL_GetRGB(pixel, img->format, &r, &g, &b); | ||||
|  | ||||
|         if (r == 0) | ||||
|         { | ||||
|             bool = 0; | ||||
|             break; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     return bool; | ||||
| } | ||||
|  | ||||
| /*Draw a column between two lines and characters*/ | ||||
| void DrawAColumn(SDL_Surface *img, int y, int x, int end_line) | ||||
| { | ||||
|     Uint32 pixel; | ||||
|  | ||||
|     for (int i = x; i < end_line; i++) | ||||
|     { | ||||
|         pixel = SDL_MapRGB(img->format, 1, 100, 100); | ||||
|         putpixel(img, y, i, pixel); | ||||
|     } | ||||
| } | ||||
|  | ||||
| int pixelSpacingHorizontal(SDL_Surface *img) | ||||
| { | ||||
|     Uint32 pixel; | ||||
|     Uint8 r; | ||||
|     Uint8 g; | ||||
|     Uint8 b; | ||||
|     int white = 0; | ||||
|     int black = 0; | ||||
|  | ||||
|     for (int i = 0; i < img->h; i++) | ||||
|     { | ||||
|         for (int j = 0; j < img->w; j++) | ||||
|         { | ||||
|             pixel = getpixel(img, j, i); | ||||
|             SDL_GetRGB(pixel, img->format, &r, &g, &b); | ||||
|             if (r == 255 && g == 255 && b == 255) | ||||
|             { | ||||
|                 white++; | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 black++; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|     return (white) / (black / 2); | ||||
| } | ||||
|  | ||||
| // fonctionne pareil que la version horizontale | ||||
| int pixelSpacingVertical(SDL_Surface *img) | ||||
| { | ||||
|     Uint32 pixel; | ||||
|     Uint8 r; | ||||
|     Uint8 g; | ||||
|     Uint8 b; | ||||
|     int white = 0; | ||||
|     int black = 0; | ||||
|  | ||||
|     for (int i = 0; i < img->w; i++) | ||||
|     { | ||||
|         for (int j = 0; j < img->h; j++) | ||||
|         { | ||||
|             pixel = getpixel(img, i, j); | ||||
|             SDL_GetRGB(pixel, img->format, &r, &g, | ||||
|                        &b); // recup les r g b du pixel (i, j) car vertical | ||||
|             if (r == 255 && g == 255 | ||||
|                 && b == 255) // pareil qu'en version horizontal | ||||
|             { | ||||
|                 white++; | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 black++; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|     return (white) / (black); | ||||
| } | ||||
|  | ||||
| void blockDetection_horizontal(SDL_Surface *img) | ||||
| { | ||||
|     Uint32 pixel; | ||||
|     Uint8 r, g, b; | ||||
|     int hori = pixelSpacingHorizontal(img) * 30; | ||||
|     int countWhite; | ||||
|  | ||||
|     for (int i = 0; i < img->h; i++) | ||||
|     { | ||||
|         countWhite = 0; | ||||
|         for (int j = 0; j < img->w; j++) | ||||
|         { | ||||
|             pixel = getpixel(img, j, i); | ||||
|             SDL_GetRGB(pixel, img->format, &r, &g, &b); | ||||
|             if (r == 255 && g == 255 && b == 255) | ||||
|             { | ||||
|                 countWhite++; | ||||
|             } | ||||
|             if (r == 0 && g == 0 && b == 0) | ||||
|             { | ||||
|                 if (countWhite <= hori) | ||||
|                 { | ||||
|                     int k = j - 1; | ||||
|                     while (countWhite > 0) | ||||
|                     { | ||||
|                         pixel = SDL_MapRGB(img->format, 0, 0, 0); | ||||
|                         putpixel(img, k, i, pixel); | ||||
|                         countWhite--; | ||||
|                         k--; | ||||
|                     } | ||||
|                 } | ||||
|                 else | ||||
|                 { | ||||
|                     countWhite = 0; | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| // remplis les espaces verticaux entre deux pixels. | ||||
| // Fonctionne pareil que la version horizontale | ||||
| void blockDetection_vertical(SDL_Surface *img) | ||||
| { | ||||
|     Uint32 pixel; | ||||
|     Uint8 r; | ||||
|     Uint8 g; | ||||
|     Uint8 b; | ||||
|     int verti = pixelSpacingVertical(img) * 3; | ||||
|     int countBlack; | ||||
|  | ||||
|     for (int i = 0; i < img->w; i++) | ||||
|     { | ||||
|         countBlack = 0; | ||||
|         for (int j = 0; j < img->h; j++) | ||||
|         { | ||||
|             pixel = getpixel(img, i, j); | ||||
|             SDL_GetRGB(pixel, img->format, &r, &g, &b); | ||||
|             if (r == 255 && g == 255 && b == 255) | ||||
|             { | ||||
|                 countBlack++; | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 if (countBlack <= verti) | ||||
|                 { | ||||
|                     int k = j - 1; | ||||
|                     while (countBlack > 0) | ||||
|                     { | ||||
|                         pixel = SDL_MapRGB(img->format, 0, 0, 0); | ||||
|                         putpixel(img, i, k, pixel); | ||||
|                         countBlack--; | ||||
|                         k--; | ||||
|                     } | ||||
|                 } | ||||
|                 else | ||||
|                 { | ||||
|                     countBlack = 0; | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| // dessine les blocs en les noircissant entierement | ||||
| //(fait un ET logique du RLSA horizontal et RLSA vertical) | ||||
| // img c'est l'image qui va contenir des blocs remplis de noir | ||||
| // imgHor a subi bloc detection horizontal | ||||
| // imgver a subi bloc detection vertical | ||||
| void drawBlocksMulti(SDL_Surface *img, SDL_Surface *imgHor, SDL_Surface *imgVer) | ||||
| { | ||||
|     Uint32 pixelHor; | ||||
|     Uint32 pixelVer; | ||||
|     Uint32 pixel; | ||||
|     Uint8 r; | ||||
|     Uint8 g; | ||||
|     Uint8 b; | ||||
|  | ||||
|     for (int i = 1; i + 1 < img->w; i++) | ||||
|     { | ||||
|         for (int j = 1; j + 1 < img->h; j++) | ||||
|         { | ||||
|             pixelHor = getpixel(imgHor, i, j); | ||||
|             SDL_GetRGB(pixelHor, imgHor->format, &r, &g, &b); | ||||
|             if (r == 0 && g == 0 && b == 0) | ||||
|             { | ||||
|                 pixelVer = getpixel(imgVer, i, j); | ||||
|                 SDL_GetRGB(pixelVer, imgVer->format, &r, &g, &b); | ||||
|                 if (r == 0 && g == 0 && b == 0) | ||||
|                 { | ||||
|                     pixel = SDL_MapRGB(img->format, 0, 0, 0); | ||||
|                     putpixel(img, i, j, pixel); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| void drawBlocks(SDL_Surface *img, SDL_Surface *imgHor) | ||||
| { | ||||
|     Uint32 pixelHor; | ||||
|     Uint32 pixelLine; | ||||
|     Uint8 r; | ||||
|     Uint8 g; | ||||
|     Uint8 b; | ||||
|     int w; | ||||
|     for (int i = 1; i + 1 < img->w; i++) | ||||
|     { | ||||
|         for (int j = 1; j + 1 < img->h; j++) | ||||
|         { | ||||
|             pixelHor = getpixel(imgHor, i, j); | ||||
|             SDL_GetRGB(pixelHor, imgHor->format, &r, &g, &b); | ||||
|             if (r == 0 && g == 0 && b == 0) | ||||
|             { | ||||
|                 w = img->w; | ||||
|                 for (int k = 0; k < w; k++) | ||||
|                 { | ||||
|                     pixelLine = SDL_MapRGB(img->format, 0, 0, 0); | ||||
|                     putpixel(img, k, j, pixelLine); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| void drawBlocksLines(SDL_Surface *img, SDL_Surface *imgRLSA) | ||||
| { | ||||
|     Uint32 pixel; | ||||
|     Uint32 pixelRLSA; | ||||
|     Uint32 pixelUp; | ||||
|     Uint32 pixelDown; | ||||
|     Uint32 pixelLeft; | ||||
|     Uint32 pixelRight; | ||||
|     Uint8 r; | ||||
|     Uint8 g; | ||||
|     Uint8 b; | ||||
|  | ||||
|     for (int i = 1; i + 1 < img->w; i++) | ||||
|     { | ||||
|         for (int j = 1; j + 1 < img->h; j++) | ||||
|         { | ||||
|             pixelRLSA = getpixel(imgRLSA, i, j); | ||||
|             SDL_GetRGB(pixelRLSA, imgRLSA->format, &r, &g, &b); | ||||
|             if (r == 0 && g == 0 && b == 0) // si le pixel est noir, | ||||
|             { | ||||
|                 pixelUp = getpixel(imgRLSA, i, j - 1); | ||||
|                 SDL_GetRGB(pixelUp, imgRLSA->format, &r, &g, &b); | ||||
|                 if (r == 255 && g == 255 && b == 255) // pixel du haut | ||||
|                 { | ||||
|                     pixel = SDL_MapRGB(img->format, 0, 0, 255); | ||||
|                     putpixel(img, i, j - 1, pixel); | ||||
|                 } | ||||
|                 else | ||||
|                 { | ||||
|                     pixelDown = getpixel(imgRLSA, i, j + 1); | ||||
|                     SDL_GetRGB(pixelDown, imgRLSA->format, &r, &g, &b); | ||||
|                     if (r == 255 && g == 255 && b == 255) // pixel d'en bas | ||||
|                     { | ||||
|                         pixel = SDL_MapRGB(img->format, 0, 0, 255); | ||||
|                         putpixel(img, i, j + 1, pixel); | ||||
|                     } | ||||
|                     else | ||||
|                     { | ||||
|                         pixelLeft = getpixel(imgRLSA, i - 1, j); | ||||
|                         SDL_GetRGB(pixelLeft, imgRLSA->format, &r, &g, &b); | ||||
|                         if (r == 255 && g == 255 && b == 255) // pixel de gauche | ||||
|                         { | ||||
|                             pixel = SDL_MapRGB(img->format, 0, 0, 255); | ||||
|                             putpixel(img, i, j - 1, pixel); | ||||
|                         } | ||||
|                         else | ||||
|                         { | ||||
|                             pixelRight = getpixel(imgRLSA, i + 1, j); | ||||
|                             SDL_GetRGB(pixelRight, imgRLSA->format, &r, &g, &b); | ||||
|                             if (r == 255 && g == 255 | ||||
|                                 && b == 255) // pixel de droite | ||||
|                             { | ||||
|                                 pixel = SDL_MapRGB(img->format, 0, 0, 255); | ||||
|                                 putpixel(img, i, j + 1, pixel); | ||||
|                             } | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| /*make an histogramme of the black pixel in column of the image*/ | ||||
| /*histo1 is a pointer on a int array*/ | ||||
| void histo(SDL_Surface *img, int *histo1) | ||||
| { | ||||
|     Uint32 pixel; | ||||
|     Uint8 r, g, b; | ||||
|     int w = img->w; | ||||
|     int h = img->h; | ||||
|  | ||||
|     for (int r = 0; r < w; r++) | ||||
|     { | ||||
|         histo1[r] = 0; | ||||
|     } | ||||
|  | ||||
|     for (int i = 0; i < w; i++) | ||||
|     { | ||||
|         int s = 0; | ||||
|         for (int j = 0; j < h; j++) | ||||
|         { | ||||
|             pixel = getpixel(img, i, j); | ||||
|             SDL_GetRGB(pixel, img->format, &r, &g, &b); | ||||
|  | ||||
|             if (r == 255) | ||||
|             { | ||||
|                 s++; | ||||
|             } | ||||
|         } | ||||
|         histo1[i] = h - s; | ||||
|     } | ||||
| } | ||||
| /*useless actually*/ | ||||
| /*void cutchar(SDL_Surface *img){ | ||||
|   int w; | ||||
|   w = img -> w; | ||||
|   int *histog = malloc(w * sizeof(int)); | ||||
|   int average = average1(img); | ||||
|   printf("%i\n",average); | ||||
|   int s = 0; | ||||
|   int bool1=0; | ||||
|   histo(img, histog); | ||||
|   for (int i = 0; i < img -> w; i++){ | ||||
|     if (s > average){ | ||||
|       printf("histo(%i) = %i",i,histog[i]); | ||||
|       DrawAColumn(img, i-s/2, 0,img->h -1); | ||||
|     } | ||||
|     if (histog[i] != 0){ | ||||
|         if(bool1) | ||||
|         { | ||||
|           bool1 =0; | ||||
|         } | ||||
|       s++; | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|       bool1=1; | ||||
|       s =0; | ||||
|     } | ||||
|   } | ||||
|   free(histog); | ||||
| }*/ | ||||
|  | ||||
| /*make the average of all suite of zero in the histogramme*/ | ||||
| int average(SDL_Surface *img) | ||||
| { | ||||
|     int w = img->w; | ||||
|     int *histog = malloc(w * sizeof(int)); | ||||
|     histo(img, histog); | ||||
|     int s = 0; | ||||
|     int sum = 0; | ||||
|     int r = 0; | ||||
|     int bool1 = 1; | ||||
|  | ||||
|     for (int i = 0; i < img->w; i++) | ||||
|     { | ||||
|         if (histog[i] == 0) | ||||
|         { | ||||
|             if (bool1) | ||||
|             { | ||||
|                 bool1 = 0; | ||||
|                 r += 1; | ||||
|             } | ||||
|             s++; | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             sum += s; | ||||
|             bool1 = 1; | ||||
|             s = 0; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     free(histog); | ||||
|     return sum / r; | ||||
| } | ||||
|  | ||||
| /*cut all of the word of a line*/ | ||||
| void cutword(SDL_Surface *img) | ||||
| { | ||||
|     int w = img->w; | ||||
|     int *histog = malloc(w * sizeof(int)); | ||||
|     histo(img, histog); | ||||
|     int bool1 = 1; | ||||
|     int r = average(img); | ||||
|     int s = 0; | ||||
|     int pos = 0; | ||||
|     int i; | ||||
|  | ||||
|     for (i = 0; i < img->w; i++) | ||||
|     { | ||||
|         if (histog[i] == 0) | ||||
|         { | ||||
|             if (bool1) | ||||
|             { | ||||
|                 pos = i; | ||||
|                 bool1 = 0; | ||||
|             } | ||||
|             s++; | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             if (s >= r * 1.4) | ||||
|             { | ||||
|                 DrawAColumn(img, pos, 0, img->h); | ||||
|             } | ||||
|             bool1 = 1; | ||||
|             s = 0; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     if (i == img->w) | ||||
|     { | ||||
|         DrawAColumn(img, pos, 0, img->h); | ||||
|     } | ||||
|  | ||||
|     free(histog); | ||||
| } | ||||
							
								
								
									
										53
									
								
								ImageTreatment/Segmentation/segmentation.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										53
									
								
								ImageTreatment/Segmentation/segmentation.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,53 @@ | ||||
| #ifndef _SEGMENTATION_H | ||||
|  | ||||
| #define _SEGMENTATION_H | ||||
|  | ||||
| #include <SDL2/SDL.h> | ||||
|  | ||||
| #include "../Tools/tools.h" | ||||
|  | ||||
| void CutLines(SDL_Surface *img, int d); | ||||
|  | ||||
| void cutword(SDL_Surface *img); | ||||
|  | ||||
| int seuil(SDL_Surface *img); | ||||
|  | ||||
| void drawBlocksLines(SDL_Surface *img, SDL_Surface *imgRLSA); | ||||
|  | ||||
| void histo(SDL_Surface *img, int *histo1); | ||||
|  | ||||
| int average1(SDL_Surface *img); | ||||
|  | ||||
| void drawBlocksMulti(SDL_Surface *img, SDL_Surface *imgHor, | ||||
|                      SDL_Surface *imgVer); | ||||
|  | ||||
| void drawBlocks(SDL_Surface *img, SDL_Surface *imgHor); | ||||
|  | ||||
| void cutchar(SDL_Surface *img); | ||||
|  | ||||
| int pixelSpacingHorizontal(SDL_Surface *img); | ||||
|  | ||||
| int pixelSpacingVertical(SDL_Surface *img); | ||||
|  | ||||
| void blockDetection_horizontal(SDL_Surface *img); | ||||
|  | ||||
| int average(SDL_Surface *img); | ||||
|  | ||||
| void blockDetection_vertical(SDL_Surface *img); | ||||
|  | ||||
| void CutColumn(SDL_Surface *img, int begin_line, int end_line); | ||||
|  | ||||
| int FindBlackPixelInColumn(SDL_Surface *img, int begin_line, int end_line, | ||||
|                            int start); | ||||
|  | ||||
| void DrawAColumn(SDL_Surface *img, int y, int x, int end_line); | ||||
|  | ||||
| int FindBlackPixel(SDL_Surface *img, int x); | ||||
|  | ||||
| void DrawInImage(SDL_Surface *img); | ||||
|  | ||||
| void DrawALine(SDL_Surface *img, int x); | ||||
|  | ||||
| void lines(SDL_Surface *img); | ||||
|  | ||||
| #endif | ||||
		Reference in New Issue
	
	Block a user