OCR project

This commit is contained in:
brice.boisson
2022-02-08 19:16:25 +01:00
commit eaa4da6ade
3475 changed files with 126899 additions and 0 deletions

View File

@@ -0,0 +1,166 @@
#include "cleanerimage.h"
#include "../display.h"
void grayscale(SDL_Surface *img)
{
Uint32 pixel;
Uint8 r, g, b;
int w = img->w;
int h = img->h;
for (int i = 0; i < w; i++)
{
for (int j = 0; j < h; j++)
{
pixel = getpixel(img, i, j);
SDL_GetRGB(pixel, img->format, &r, &g, &b);
Uint8 results = 0.3 * r + 0.59 * g + 0.11 * b;
pixel = SDL_MapRGB(img->format, results, results, results);
putpixel(img, i, j, pixel);
}
}
}
void binerize(SDL_Surface *img)
{
Uint32 pixel;
Uint8 r, g, b;
int w = img->w;
int h = img->h;
for (int i = 0; i < w; i++)
{
for (int j = 0; j < h; j++)
{
pixel = getpixel(img, i, j);
SDL_GetRGB(pixel, img->format, &r, &g, &b);
Uint32 average = (r + b + g) / 3;
if (average > 150) /*we can make an average here*/
{
r = 255;
g = 255;
b = 255;
}
else
{
r = 0;
g = 0;
b = 0;
}
pixel = SDL_MapRGB(img->format, r, g, b);
putpixel(img, i, j, pixel);
}
}
}
int IsValid(int x, int y, int w, int h)
{
return x >= 0 && x < w && y >= 0 && y < h;
}
SDL_Surface *Convolute(SDL_Surface *img, float mask[3][3])
{
int offset = 3 / 2;
Uint8 r, g, b;
Uint32 pixel = 0;
SDL_Surface *copy = CreateWhiteSurface(img->w, img->h, img);
for (int y = 0; y < img->h; ++y)
{
for (int x = 0; x < img->w; ++x)
{
float red = 0;
float green = 0;
float blue = 0;
for (int dy = -offset; dy <= offset; ++dy)
{
for (int dx = -offset; dx <= offset; ++dx)
{
if (IsValid(x + dx, y + dy, img->w, img->h))
{
pixel = getpixel(img, x + dx, y + dy);
float coefficient = mask[dy + offset][dx + offset];
SDL_GetRGB(pixel, img->format, &r, &g, &b);
red += r * coefficient;
green += g * coefficient;
blue += b * coefficient;
}
}
}
pixel = SDL_MapRGB(img->format, Restrict256(red),
Restrict256(green), Restrict256(blue));
putpixel(copy, x, y, pixel);
}
}
return copy;
}
int Restrict256(int n)
{
if (n < 0)
return 0;
if (n > 255)
return 255;
return n;
}
void ConstrastRenforcement(SDL_Surface *img, int delta)
{
double factor = (259 * (delta + 255)) / (255.0 * (259.0 - delta));
Uint32 pixel;
Uint8 r;
Uint8 g;
Uint8 b;
int w = img->w;
int h = img->h;
if (delta == 259)
{
delta = 258;
}
for (int i = 0; i < w; i++)
{
for (int j = 0; j < h; j++)
{
pixel = getpixel(img, i, j);
SDL_GetRGB(pixel, img->format, &r, &g, &b);
r = Restrict256(factor * (r - 128) + 128);
g = Restrict256(factor * (g - 128) + 128);
b = Restrict256(factor * (b - 128) + 128);
pixel = SDL_MapRGB(img->format, r, g, b);
putpixel(img, i, j, pixel);
}
}
}
void noiseReduction(SDL_Surface *img)
{
int w = img->w;
int h = img->h;
int pixelmap[9];
for (int i = 1; i < h - 1; i++)
{
for (int j = 1; j < w - 1; j++)
{
pixelmap[0] = getpixel(img, j - 1, i - 1);
pixelmap[1] = getpixel(img, j, i - 1);
pixelmap[2] = getpixel(img, j + 1, i - 1);
pixelmap[3] = getpixel(img, j - 1, i);
pixelmap[4] = getpixel(img, j, i);
pixelmap[5] = getpixel(img, j + 1, i);
pixelmap[6] = getpixel(img, j - 1, i + 1);
pixelmap[7] = getpixel(img, j, i + 1);
pixelmap[8] = getpixel(img, j + 1, i + 1);
array_select_sort(pixelmap, 9);
int med = pixelmap[4];
putpixel(img, j, i, med);
}
}
}

View File

@@ -0,0 +1,25 @@
#ifndef _CLEANERIMAGE_H
#define _CLEANERIMAGE_H
#include <SDL2/SDL.h>
#include "../Tools/tools.h"
void grayscale(SDL_Surface *img);
int IsValid(int x, int y, int w, int h);
void ConstrastRenforcement(SDL_Surface *img, int delta);
int Restrict256(int n);
SDL_Surface *Convolute(SDL_Surface *img, float mask[3][3]);
void noiseReduction(SDL_Surface *img);
void blacknwhite(SDL_Surface *img);
void binerize(SDL_Surface *img);
#endif

View 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);
}

View 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

View File

@@ -0,0 +1,264 @@
#include "tools.h"
#include <math.h>
Uint8 *pixelref(SDL_Surface *surf, unsigned x, unsigned y)
{
int bpp = surf->format->BytesPerPixel;
return (Uint8 *)surf->pixels + y * surf->pitch + x * bpp;
}
Uint32 getpixel(SDL_Surface *surface, unsigned x, unsigned y)
{
Uint8 *p = pixelref(surface, x, y);
switch (surface->format->BytesPerPixel)
{
case 1:
return *p;
case 2:
return *(Uint16 *)p;
case 3:
if (SDL_BYTEORDER == SDL_BIG_ENDIAN)
return p[0] << 16 | p[1] << 8 | p[2];
else
return p[0] | p[1] << 8 | p[2] << 16;
case 4:
return *(Uint32 *)p;
}
return 0;
}
void putpixel(SDL_Surface *surface, int x, int y, Uint32 pixel)
{
Uint8 *p = pixelref(surface, x, y);
switch (surface->format->BytesPerPixel)
{
case 1:
*p = pixel;
break;
case 2:
*(Uint16 *)p = pixel;
break;
case 3:
if (SDL_BYTEORDER == SDL_BIG_ENDIAN)
{
p[0] = (pixel >> 16) & 0xff;
p[1] = (pixel >> 8) & 0xff;
p[2] = pixel & 0xff;
}
else
{
p[0] = pixel & 0xff;
p[1] = (pixel >> 8) & 0xff;
p[2] = (pixel >> 16) & 0xff;
}
break;
case 4:
*(Uint32 *)p = pixel;
break;
}
}
void pause1()
{
int continuer = 1;
SDL_Event event;
while (continuer)
{
SDL_WaitEvent(&event);
switch (event.type)
{
case SDL_QUIT:
continuer = 0;
}
}
}
void array_swap(int array[], size_t i, size_t j)
{
int element1 = array[i];
int element2 = array[j];
array[i] = element2;
array[j] = element1;
}
void array_select_sort(int array[], size_t len)
{
size_t i = 0;
size_t j;
int min_index;
while (i < len)
{
j = i;
min_index = j;
while (j < len)
{
if (array[j] < array[min_index])
{
min_index = j;
}
j += 1;
}
array_swap(array, i, min_index);
i++;
}
}
SDL_Surface *copy_image(SDL_Surface *img)
{
Uint32 pixel;
SDL_Surface *copy;
copy = SDL_CreateRGBSurface(0, img->w, img->h, img->format->BitsPerPixel, 0,
0, 0, 0);
for (int i = 0; i < img->w; i++)
{
for (int j = 0; j < img->h; j++)
{
pixel = getpixel(img, i, j);
putpixel(copy, i, j, pixel);
}
}
return (copy);
}
SDL_Surface *resize(SDL_Surface *img, int x, int y)
{
Uint32 pixel;
SDL_Surface *new =
SDL_CreateRGBSurface(0, x, y, img->format->BitsPerPixel, 0, 0, 0, 0);
int w = img->w;
int h = img->h;
float ratioX = (float)w / x;
float ratioY = (float)h / y;
for (int i = 0; i < x; ++i)
{
for (int j = 0; j < y; ++j)
{
pixel = getpixel(img, (int)(i * ratioX), (int)(j * ratioY));
putpixel(new, i, j, pixel);
}
}
return new;
}
SDL_Surface *CreateWhiteSurface(int x, int y, SDL_Surface *img)
{
Uint32 pixel;
SDL_Surface *new =
SDL_CreateRGBSurface(0, x, y, img->format->BitsPerPixel, 0, 0, 0, 0);
for (int i = 0; i < new->w; i++)
{
for (int j = 0; j < new->h; j++)
{
pixel = SDL_MapRGB(img->format, 255, 255, 255);
putpixel(new, i, j, pixel);
}
}
return (new);
}
/*return a new image with a rotation of theta a apply
in the image in paramaters*/
SDL_Surface *rotate(double teta, SDL_Surface *img)
{
double radian = (teta * M_PI) / 180.0;
int certerx = round(((img->w + 1) / 2) - 1);
int centery = round(((img->h + 1) / 2) - 1);
int xprime = 0;
int yprime = 0;
int h = img->h;
int w = img->w;
Uint32 pixel = 0;
SDL_Surface *new = CreateWhiteSurface(w, h, img);
for (int i = 0; i < img->w; i++)
{
for (int j = 0; j < img->h; j++)
{
xprime = round((double)(i - certerx) * cos(radian)
+ (double)(j - centery) * sin(radian));
yprime = round((double)(j - centery) * cos(radian)
- (double)(i - certerx) * sin(radian));
xprime += certerx;
yprime += centery;
if (xprime >= 0 && xprime < img->w && yprime < img->h
&& yprime >= 0)
{
pixel = getpixel(img, i, j);
putpixel(new, xprime, yprime, pixel);
}
}
}
return new;
}
/*apply hough transformy and return the angle detected*/
double houghtrasformy(SDL_Surface *img)
{
double maxrow = sqrt((img->w * img->w) + (img->h * img->h));
int maxteta = 180;
Uint8 r, g, b;
int *tab = calloc((size_t)(maxrow * 181), sizeof(int));
Uint32 pixel = 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);
if (r == 0 && g == 0 && b == 0)
{
int x = i - (img->w / 2);
int y = j - (img->h / 2);
for (int teta_i = 0; teta_i < maxteta; teta_i++)
{
double teta = ((double)teta_i / 180.0) * M_PI;
double row = x * cos(teta) + y * sin(teta);
size_t i_rho = 0.5 + (row / maxrow + 0.5) * (maxrow + 1);
tab[teta_i + maxteta * i_rho] += 1;
}
}
}
}
double resulte = maxhough(tab, maxrow);
free(tab);
return resulte;
}
double maxhough(int *tab, size_t maxrow)
{
double ThetaR;
int max = 0;
size_t maxteta = 180;
for (size_t i = 0; i < maxrow; ++i)
{
for (size_t j = 0; j < maxteta; ++j)
{
if (tab[j + i * maxteta] > max)
{
max = tab[j + i * maxteta];
ThetaR = j;
}
}
}
return ThetaR;
}

View File

@@ -0,0 +1,35 @@
#ifndef TOOLS_H_
#define TOOLS_H_
#include <SDL2/SDL.h>
#include <err.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
void putpixel(SDL_Surface *surface, int x, int y, Uint32 pixel);
void array_select_sort(int array[], size_t len);
void array_swap(int array[], size_t i, size_t j);
void pause1();
SDL_Surface *CreateWhiteSurface(int x, int y, SDL_Surface *img);
int FindBlackPixelv2(SDL_Surface *img, int x);
SDL_Surface *rotate(double teta, SDL_Surface *img);
double houghtrasformy(SDL_Surface *img);
double maxhough(int *tab, size_t maxrow);
SDL_Surface *copy_image(SDL_Surface *img);
SDL_Surface *resize(SDL_Surface *img, int x, int y);
Uint32 getpixel(SDL_Surface *surface, unsigned x, unsigned y);
Uint8 *pixelref(SDL_Surface *surf, unsigned x, unsigned y);
#endif

44
ImageTreatment/display.c Normal file
View File

@@ -0,0 +1,44 @@
#include "display.h"
void wait_for_keypressed()
{
SDL_Event event;
do
{
SDL_PollEvent(&event);
} while (event.type != SDL_KEYDOWN);
do
{
SDL_PollEvent(&event);
} while (event.type != SDL_KEYUP);
}
SDL_Window *display_img(SDL_Surface *image)
{
if (SDL_VideoInit(NULL) < 0) // Initialize SDL
{
printf("Error of initializing SDL : %s", SDL_GetError());
}
// Create window
SDL_Window *fenetre;
int w = image->w; // width of the bmp
int h = image->h; // height of the bmp
fenetre =
SDL_CreateWindow("OCR", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
w, h, SDL_WINDOW_RESIZABLE);
if (fenetre == NULL) // if problem return error
{
printf("Error of creating window : %s", SDL_GetError());
}
SDL_BlitSurface(image, NULL, SDL_GetWindowSurface(fenetre), 0);
SDL_UpdateWindowSurface(fenetre);
return fenetre;
}

4
ImageTreatment/display.h Normal file
View File

@@ -0,0 +1,4 @@
#include <SDL2/SDL.h>
SDL_Window *display_img(SDL_Surface *image);
void wait_for_keypressed();

View File

@@ -0,0 +1,159 @@
#include "extractchar.h"
#include <string.h>
#include "../display.h"
/*
Return the number of word in the current image
*/
int countwc(SDL_Surface *img)
{
int w = img->w;
Uint32 pixel = 0;
Uint8 r, g, b;
int count = 0;
for (int i = 0; i < w; i++)
{
pixel = getpixel(img, i, 1);
SDL_GetRGB(pixel, img->format, &r, &g, &b);
if ((r == 1 && g == 100 && b == 100))
{
count++;
}
}
return count;
}
/*
Return an array of the position of words in the current image
*/
void ReturnPoswc(SDL_Surface *img, int *tab)
{
int w = img->w;
Uint32 pixel = 0;
Uint8 r, g, b;
int count = 0;
for (int i = 0; i < w; i++)
{
pixel = getpixel(img, i, 1);
SDL_GetRGB(pixel, img->format, &r, &g, &b);
if ((r == 1 && g == 100 && b == 100))
{
tab[count] = i;
count++;
}
}
}
/*
Create a new surface and extract the word for charactere segmentation
*/
void extractword(SDL_Surface *img, int x, int y, Neural_Network *network,
char *str)
{
SDL_Surface *new = CreateWhiteSurface(y - x + 1, img->h, img);
Uint32 pixel = 0;
for (int i = x + 1; i < y; i++)
{
for (int j = 0; j < img->h; j++)
{
pixel = getpixel(img, i, j);
putpixel(new, i - x, j, pixel);
}
}
SDL_SaveBMP(new, "final12.bmp");
__extractchar(new, network, str);
SDL_FreeSurface(new);
}
/*
Create a new surface and extract the caracters for neural network
*/
void __extractword(SDL_Surface *img, Neural_Network *network, char *str)
{
SDL_Surface *loadedImage = resize(img, 1218, 41);
cutword(loadedImage);
int count = countwc(loadedImage);
int *tab = malloc(sizeof(int) * count);
ReturnPoswc(loadedImage, tab);
for (int i = 0; i < count - 1; i += 1)
{
extractword(loadedImage, tab[i], tab[i + 1], network, str);
char a[] = " ";
strcat(str, a);
}
SDL_FreeSurface(loadedImage);
free(tab);
}
int fullofwhite(SDL_Surface *img)
{
Uint32 pixel = 0;
Uint8 r, g, b;
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 == 0 && g == 0 && b == 0)
{
return 1;
}
}
}
return 0;
}
void extractchar(SDL_Surface *img, int x, int y, Neural_Network *network,
char *str)
{
SDL_Surface *new = CreateWhiteSurface(y - x + 1, img->h, img);
Uint32 pixel = 0;
for (int i = x + 1; i < y; i++)
{
for (int j = 0; j < img->h; j++)
{
pixel = getpixel(img, i, j);
putpixel(new, i - x, j, pixel);
}
}
if (fullofwhite(new))
{
double *letter = segmentationtomatrix(new, 20);
ForwardPass(letter, network);
free(letter);
char a[2];
a[0] = indiceToChar(network->output);
a[1] = '\0';
strcat(str, a);
}
}
void __extractchar(SDL_Surface *img, Neural_Network *network, char *str)
{
SDL_Surface *loadedImage = copy_image(img);
CutColumn(loadedImage, 0, img->h);
int count = countwc(loadedImage);
int *tab = malloc(sizeof(int) * count);
ReturnPoswc(loadedImage, tab);
for (int i = 0; i < count - 1; i += 1)
{
extractchar(loadedImage, tab[i], tab[i + 1], network, str);
}
SDL_FreeSurface(loadedImage);
free(tab);
}

View File

@@ -0,0 +1,18 @@
#ifndef _EXTRACTIONCHAR_H
#define _EXTRACTIONCHAR_H
#include "../../NeuralNetwork/structure.h"
#include "../../NeuralNetwork/toolsnetworks.h"
#include "../../NeuralNetwork/traitement.h"
#include "../Segmentation/segmentation.h"
void extractword(SDL_Surface *img, int x, int y, Neural_Network *network,
char *str);
int countwc(SDL_Surface *img);
void ReturnPoswc(SDL_Surface *img, int *tab);
void __extractword(SDL_Surface *img, Neural_Network *network, char *str);
void __extractchar(SDL_Surface *img, Neural_Network *network, char *str);
void extractchar(SDL_Surface *img, int x, int y, Neural_Network *network,
char *str);
#endif

View File

@@ -0,0 +1,142 @@
#include "extraction.h"
#include <string.h>
#include "../Segmentation/segmentation.h"
#include "../display.h"
#include "extractchar.h"
/*
Count the number of line and paragraph in the current image
*/
int countlinepar(SDL_Surface *img)
{
int h = img->h;
Uint32 pixel = 0;
Uint8 r, g, b;
int count = 0;
for (int i = 0; i < h; i++)
{
pixel = getpixel(img, 1, i);
SDL_GetRGB(pixel, img->format, &r, &g, &b);
if ((r == 0 && g == 0 && b == 255)
|| (r == 255 && g == 150 && b == 255))
{
count++;
}
}
return count;
}
/*
Fill an array with the position of line and paragraph
*/
void ReturnPosPar(SDL_Surface *img, int *tab)
{
int h = img->h;
Uint32 pixel = 0;
Uint8 r, g, b;
int count = 0;
for (int i = 0; i < h; i++)
{
pixel = getpixel(img, 1, i);
SDL_GetRGB(pixel, img->format, &r, &g, &b);
if ((r == 0 && g == 0 && b == 255)
|| (r == 255 && g == 150 && b == 255))
{
tab[count] = i;
count++;
}
}
}
/*
Create a new surface and paragraph for line segmentation
*/
void extractpar(SDL_Surface *img, int x, int y, Neural_Network *network,
char *str)
{
SDL_Surface *new = CreateWhiteSurface(img->w, y - x + 1, img);
Uint32 pixel = 0;
for (int i = 0; i < img->w; i++)
{
for (int j = x + 1; j < y; j++)
{
pixel = getpixel(img, i, j);
putpixel(new, i, j - x, pixel);
}
}
__extractline(new, network, str);
SDL_FreeSurface(new);
}
void __extractpar(SDL_Surface *img, Neural_Network *network, char *str)
{
SDL_Surface *imagev = copy_image(img);
SDL_Surface *imagerlsa = copy_image(img);
SDL_Surface *copy_image1 = copy_image(img);
blockDetection_vertical(imagev);
drawBlocks(imagerlsa, imagev);
drawBlocksLines(copy_image1, imagerlsa);
int count = countlinepar(copy_image1);
int *tab = malloc(sizeof(int) * count);
ReturnPosPar(copy_image1, tab);
for (int i = 0; i < count - 1; i += 2)
{
extractpar(copy_image1, tab[i], tab[i + 1], network, str);
char a[] = "\n\n\n";
strcat(str, a);
}
SDL_FreeSurface(imagerlsa);
SDL_FreeSurface(imagev);
SDL_FreeSurface(copy_image1);
free(tab);
}
/*
Create a new surface and extract the line for word segmentation
*/
void extractline(SDL_Surface *img, int x, int y, Neural_Network *network,
char *str)
{
SDL_Surface *new = CreateWhiteSurface(img->w, y - x + 1, img);
Uint32 pixel = 0;
for (int i = 0; i < img->w; i++)
{
for (int j = x + 1; j < y; j++)
{
pixel = getpixel(img, i, j);
putpixel(new, i, j - x, pixel);
}
}
__extractword(new, network, str);
SDL_FreeSurface(new);
}
void __extractline(SDL_Surface *img, Neural_Network *network, char *str)
{
SDL_Surface *copy = copy_image(img);
CutLines(copy, 0);
int count = countlinepar(copy);
int *tab = malloc(sizeof(int) * count);
ReturnPosPar(copy, tab);
for (int i = 0; i < count - 1; i += 2)
{
extractline(copy, tab[i], tab[i + 1], network, str);
char a[] = "\n";
strcat(str, a);
}
SDL_FreeSurface(copy);
free(tab);
}

View File

@@ -0,0 +1,16 @@
#ifndef _EXTRACTION_H
#define _EXTRACTION_H
#include "../../NeuralNetwork/structure.h"
#include "../Segmentation/segmentation.h"
void extractpar(SDL_Surface *img, int x, int y, Neural_Network *network,
char *str);
int countlinepar(SDL_Surface *img);
void ReturnPosPar(SDL_Surface *img, int *tab);
void __extractpar(SDL_Surface *img, Neural_Network *network, char *str);
void __extractline(SDL_Surface *img, Neural_Network *network, char *str);
void extractline(SDL_Surface *img, int x, int y, Neural_Network *network,
char *str);
#endif