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,24 @@
from PIL import Image
from PIL import ImageFont
from PIL import ImageDraw
import os
L = ['ACaslonPro-Regular.otf','AdobeArabic-Regular.otf','AdobeDevanagari-Regular.otf', 'AdobeFangsongStd-Regular.otf','AdobeHebrew-Regular.otf', 'AdobeHeitiStd-Regular.otf', 'AdobeKaitiStd-Regular.otf', 'AdobeMyungjoStd-Medium.otf', 'AdobeNaskh-Medium.otf','AGaramondPro-Regular.otf', 'arial.ttf', 'arialbd.ttf', 'bahnschrift.ttf', 'calibri.ttf', 'calibrib.ttf', 'cambria.ttc', 'cambriab.ttf', 'Candara.ttf', 'Candarab.ttf', 'ChaparralPro-Bold.otf', 'ChaparralPro-Regular.otf', 'consola.ttf', 'consolab.ttf', 'CooperBlackStd.otf', 'corbel.ttf', 'corbelb.ttf', 'ebrima.ttf', 'ebrimabd.ttf', 'framdit.ttf', 'Gabriola.ttf', 'georgia.ttf', 'georgiab.ttf',
'himalaya.ttf', 'HoboStd.otf',
'Nirmala.ttf', 'NirmalaB.ttf','ntailu.ttf', 'ntailub.ttf', 'NuevaStd-Bold.otf',
'pala.ttf', 'palab.ttf', 'phagspa.ttf', 'phagspab.ttf',
'tahoma.ttf', 'tahomabd.ttf', 'taile.ttf', 'taileb.ttf', 'times.ttf', 'timesbd.ttf', 'trebuc.ttf', 'trebucbd.ttf', 'verdana.ttf', 'verdanab.ttf']
letter = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.,'"
os.chdir (os.path.dirname(os.path.dirname(__file__)) + '/src/Dataset')
lon_font = len(L)
lon_char = len(letter)
for j in range(lon_char):
for i in range(lon_font):
font = ImageFont.truetype(L[i], 24)
img = Image.new('RGB', (32, 32), color = 'white')
draw = ImageDraw.Draw(img)
draw.text((0, 0),letter[j],(0,0,0),font=font)
img.save('image-' + str(j) + "-" + str(i + 1) + '.bmp', 'bmp')

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

62
Makefile Normal file
View File

@ -0,0 +1,62 @@
CC=gcc
CPPFLAGS= -MMD `pkg-config --cflags gtk+-3.0`
CFLAGS= -Wall -Wextra -std=c99 -g -D_XOPEN_SOURCE=600
LDLIBS= `pkg-config --libs gtk+-3.0` -lSDL2 -lm -rdynamic
EXEC= OCR
all: $(EXEC)
OCR: main.o segmentation.o cleanerimage.o tools.o display.o extraction.o extractchar.o structure.o training.o toolsnetworks.o traitement.o Load.o
$(CC) -o OCR main.o segmentation.o cleanerimage.o tools.o display.o extraction.o extractchar.o structure.o training.o toolsnetworks.o Load.o traitement.o $(LDLIBS)
rm -rf *.o *.d
main.o: main.c
$(CC) -o main.o -c main.c $(CFLAGS) $(CPPFLAGS)
segmentation.o: ImageTreatment/Segmentation/segmentation.c
$(CC) -o segmentation.o -c ImageTreatment/Segmentation/segmentation.c $(CFLAGS) $(CPPFLAGS)
cleanerimage.o: ImageTreatment/Filter/cleanerimage.c
$(CC) -o cleanerimage.o -c ImageTreatment/Filter/cleanerimage.c $(CFLAGS) $(CPPFLAGS)
tools.o: ImageTreatment/Tools/tools.c
$(CC) -o tools.o -c ImageTreatment/Tools/tools.c $(CFLAGS) $(CPPFLAGS) -lm
display.o: ImageTreatment/display.c
$(CC) -o display.o -c ImageTreatment/display.c $(CFLAGS) $(CPPFLAGS)
extraction.o: ImageTreatment/extraction/extraction.c
$(CC) -o extraction.o -c ImageTreatment/extraction/extraction.c $(CFLAGS) $(CPPFLAGS)
extractchar.o: ImageTreatment/extraction/extractchar.c
$(CC) -o extractchar.o -c ImageTreatment/extraction/extractchar.c $(CFLAGS) $(CPPFLAGS)
structure.o: NeuralNetwork/structure.c
$(CC) -o structure.o -c NeuralNetwork/structure.c $(CFLAGS) $(CPPFLAGS)
training.o: NeuralNetwork/training.c
$(CC) -o training.o -c NeuralNetwork/training.c $(CFLAGS) $(CPPFLAGS)
toolsnetworks.o: NeuralNetwork/toolsnetworks.c
$(CC) -o toolsnetworks.o -c NeuralNetwork/toolsnetworks.c $(CFLAGS) $(CPPFLAGS)
traitement.o: NeuralNetwork/traitement.c
$(CC) -o traitement.o -c NeuralNetwork/traitement.c $(CFLAGS) $(CPPFLAGS)
Load.o: NeuralNetwork/Load.c
$(CC) -o Load.o -c NeuralNetwork/Load.c $(CFLAGS) $(CPPFLAGS)
Test: main.c
$(CC) -o main.o -c main.c $(CFLAGS) $(CPPFLAGS)
clean:
rm -rf *.o *.d OCR

171
NeuralNetwork/Load.c Normal file
View File

@ -0,0 +1,171 @@
#include "Load.h"
double *resizearray(double *img, int w, int h, int x, int y)
{
double *image = (double *)calloc(x * y, sizeof(double));
float ratioX = (float)w / x;
float ratioY = (float)h / y;
for (int i = 0; i < x; ++i)
{
for (int j = 0; j < y; ++j)
{
image[i * x + j] =
img[((int)(i * ratioY)) * w + ((int)(j * ratioX))];
}
}
return image;
}
int FindBlackPixelrow(double *img, int w, int x)
{
int bool = 0;
/*A boolean that memorize if the line contain black pixel or not*/
double pixel;
for (int i = 0; i < w; i++)
{
pixel = img[x * w + i];
if (pixel == 1)
{
bool = 1;
break;
}
}
return bool;
}
int FindBlackPixelcol(double *img, int w, int h, int x)
{
int bool = 0;
/*A boolean that memorize if the line contain black pixel or not*/
double pixel;
for (int i = 0; i < h; i++)
{
pixel = img[i * w + x];
if (pixel == 1)
{
bool = 1;
break;
}
}
return bool;
}
void get_binerize_matrix(SDL_Surface *img, double *image)
{
/* Variables */
Uint32 pixel;
Uint8 r;
Uint8 g;
Uint8 b;
int w = img->w;
int h = img->h;
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);
Uint32 average = (r + b + g) / 3;
if (average > 150) /*we can make an average here*/
image[i * w + j] = 0.0;
else
image[i * w + j] = 1.0;
}
}
}
double *resizechar(SDL_Surface *img, int size)
{
int startcol = 0;
int endcol = 0;
int startrow = 0;
int endrow = 0;
int img_w = img->w;
int img_h = img->h;
double *img_array = (double *)malloc(img_h * img_w * sizeof(double));
get_binerize_matrix(img, img_array);
for (int i = 0; i < img_w; i++)
{
if (FindBlackPixelcol(img_array, img_w, img_h, i))
{
startcol = i;
break;
}
}
for (int i = img_w - 1; i >= 0; i--)
{
if (FindBlackPixelcol(img_array, img_w, img_h, i))
{
endcol = i + 1;
break;
}
}
for (int i = 0; i < img_h; i++)
{
if (FindBlackPixelrow(img_array, img_w, i))
{
startrow = i;
break;
}
}
for (int i = img_h - 1; i >= 0; i--)
{
if (FindBlackPixelrow(img_array, img_w, i))
{
endrow = i + 1;
break;
}
}
double *img_carre;
int img_carre_size;
int lencol = endcol - startcol;
int lenrow = endrow - startrow;
if (lencol > lenrow)
{
img_carre_size = lencol;
img_carre = (double *)calloc(lencol * lencol, sizeof(double));
int start = lencol / 2 - lenrow / 2;
for (int k = startrow; k < endrow; k++)
{
for (int z = startcol; z < endcol; z++)
{
img_carre[(k - startrow + start) * lencol + z - startcol] =
img_array[k * img_w + z];
}
}
}
else
{
img_carre_size = lenrow;
img_carre = (double *)calloc(lenrow * lenrow, sizeof(double));
int start = lenrow / 2 - lencol / 2;
for (int k = startrow; k < endrow; k++)
{
for (int z = startcol; z < endcol; z++)
{
img_carre[(k - startrow) * lenrow + z - startcol + start] =
img_array[k * img_w + z];
}
}
}
double *image;
image = resizearray(img_carre, img_carre_size, img_carre_size, size, size);
SDL_FreeSurface(img);
free(img_array);
free(img_carre);
return image;
}

21
NeuralNetwork/Load.h Normal file
View File

@ -0,0 +1,21 @@
#ifndef LOAD_H
#define LOAD_H
#include <SDL2/SDL.h>
#include <err.h>
#include <stdio.h>
#include <stdlib.h>
#include "../ImageTreatment/Tools/tools.h"
int FindBlackPixelrow(double *img, int w, int x);
int FindBlackPixelcol(double *img, int w, int h, int x);
double *resizechar(SDL_Surface *img, int size);
double *resizearray(double *img, int w, int h, int x, int y);
void get_binerize_matrix(SDL_Surface *img, double *image);
#endif

135
NeuralNetwork/structure.c Normal file
View File

@ -0,0 +1,135 @@
#include "structure.h"
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "toolsnetworks.h"
#include "training.h"
#include "traitement.h"
// Definition des structure du reseau de neurone
Neural_Network_Cell Create_Cell(int nb_weight)
{
Neural_Network_Cell cell;
cell.nb_weight = nb_weight;
cell.biais = 0;
cell.output = 0;
cell.weights = (double *)malloc(nb_weight * sizeof(double));
cell.previous_dError = (double *)malloc(nb_weight * sizeof(double));
return cell;
}
Neural_Network_Layer Create_Layer(int nb_cell, int nb_weight)
{
Neural_Network_Layer layer;
layer.nb_cells = nb_cell;
layer.cells =
(Neural_Network_Cell *)malloc(nb_cell * sizeof(Neural_Network_Cell));
for (int i = 0; i < nb_cell; i++)
{
*(layer.cells + i) = Create_Cell(nb_weight);
}
return layer;
}
void Free_Network(Neural_Network *network)
{
for (int i = 0; i < network->nb_layers; i++)
{
for (int j = 0; j < network->layers[i].nb_cells; j++)
{
free(network->layers[i].cells[j].weights);
free(network->layers[i].cells[j].previous_dError);
}
free(network->layers[i].cells);
}
free(network->layers);
free(network);
}
int getIndiceMax(Neural_Network *network)
{
Neural_Network_Layer layer = network->layers[network->nb_layers - 1];
int i_max = 0;
for (int i = 0; i < layer.nb_cells; i++)
{
if (layer.cells[i].output > layer.cells[i_max].output)
i_max = i;
}
return i_max;
}
int Save_Network(Neural_Network *network, char *filename)
{
FILE *file;
char path[100];
sprintf(path, "src/SaveNeuralNetwork/%s", filename);
file = fopen(path, "w");
if (!file)
return 0;
for (int i = 0; i < network->nb_layers; i++)
{
int nb_c = network->layers[i].nb_cells;
for (int j = 0; j < nb_c; j++)
{
int nb_w = network->layers[i].cells[j].nb_weight;
for (int k = 0; k < nb_w; k++)
{
fprintf(file, "%f\n", network->layers[i].cells[j].weights[k]);
}
fprintf(file, "%f\n", network->layers[i].cells[j].biais);
}
}
fclose(file);
return 1;
}
int Load_Network(Neural_Network *network, char *filename)
{
FILE *file;
char path[100];
sprintf(path, "src/SaveNeuralNetwork/%s", filename);
file = fopen(path, "r");
if (!file)
return 0;
char *cvalue = calloc(128, sizeof(char));
double value;
char *ptr;
for (int i = 0; i < network->nb_layers; i++)
{
int nb_c = network->layers[i].nb_cells;
for (int j = 0; j < nb_c; j++)
{
int nb_w = network->layers[i].cells[j].nb_weight;
for (int k = 0; k < nb_w; k++)
{
fgets(cvalue, 128, file);
value = strtod(cvalue, &ptr);
network->layers[i].cells[j].weights[k] = value;
}
fgets(cvalue, 128, file);
value = strtod(cvalue, &ptr);
network->layers[i].cells[j].biais = value;
}
}
free(cvalue);
return 1;
}

36
NeuralNetwork/structure.h Normal file
View File

@ -0,0 +1,36 @@
#ifndef STRUCTURE_H
#define STRUCTURE_H
typedef struct
{
int nb_weight;
double *weights;
double *previous_dError;
double biais;
double output;
} Neural_Network_Cell;
typedef struct
{
int nb_cells;
Neural_Network_Cell *cells;
} Neural_Network_Layer;
typedef struct
{
int nboutput;
int nb_layers;
Neural_Network_Layer *layers;
double output;
} Neural_Network;
Neural_Network_Cell Create_Cell(int nb_weight);
Neural_Network_Layer Create_Layer(int nb_cell, int nb_weight);
void Free_Network(Neural_Network *network);
int getIndiceMax(Neural_Network *network);
int Save_Network(Neural_Network *network, char *filename);
int Load_Network(Neural_Network *network, char *filename);
#endif

View File

@ -0,0 +1,98 @@
#include "toolsnetworks.h"
#include <SDL2/SDL_image.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <time.h>
#include "Load.h"
#include "structure.h"
#include "training.h"
#include "traitement.h"
// Definition des fonctions de type outils et fonctions mathématiques
float my_rand(void)
{
return ((float)(rand() % 10000) / 5000) - 1;
}
double sigmoid(double val)
{
return (1.0 / (1.0 + exp(-1.0 * val)));
}
void softmax(Neural_Network_Layer *layer)
{
double min = 0;
for (int i = 0; i < layer->nb_cells; i++)
{
if (layer->cells[i].output < min)
min = layer->cells[i].output;
}
double somme = 0;
for (int i = 0; i < layer->nb_cells; i++)
{
layer->cells[i].output -= min;
somme += exp(layer->cells[i].output);
}
for (int i = 0; i < layer->nb_cells; i++)
{
layer->cells[i].output = (exp(layer->cells[i].output) / somme);
}
}
char indiceToChar(int indice)
{
if (indice < 26)
return indice + 97;
else if (indice < 52)
return indice + 39;
else if (indice < 62)
return indice - 4;
else
{
if (indice == 62)
return 46;
else if (indice == 63)
return 44;
else
return 39;
}
}
double *imagetomatrix(char *str, int size)
{
SDL_Surface *loadedImage = 0;
loadedImage = SDL_LoadBMP(str);
double *img = NULL;
if (!loadedImage)
{
printf("Can't find the bmp file, %s\n", str);
return img;
}
img = resizechar(loadedImage, size);
return img;
}
double *segmentationtomatrix(SDL_Surface *loadedImage, int size)
{
double *img = NULL;
if (!loadedImage)
{
printf("Can't find the bmp file\n");
return img;
}
img = resizechar(loadedImage, size);
return img;
}

View File

@ -0,0 +1,19 @@
#ifndef TOOLS__NETWORKS_H
#define TOOLS__NETWORKS_H
#include <SDL2/SDL.h>
#include "structure.h"
float my_rand(void);
void softmax(Neural_Network_Layer *layer);
char indiceToChar(int indice);
double sigmoid(double val);
double *imagetomatrix(char *str, int size);
double *segmentationtomatrix(SDL_Surface *loadedImage, int size);
#endif

87
NeuralNetwork/training.c Normal file
View File

@ -0,0 +1,87 @@
#include "training.h"
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "structure.h"
#include "toolsnetworks.h"
#include "traitement.h"
#define NB_OUTPUT 65
void training(Neural_Network *network, int nb_repetition)
{
int nbchar = 65;
int nbimageschar = 53;
int datasetsize = nbchar * nbimageschar;
// On construit les tableaux input de taille nbrepetition, et on initialise
// en même temps le coût attendu à 0 pour toutres les répétitions (on a
// nbrépétition tableaux de taille 63 initialisés à 0).
double **input = (double **)malloc(datasetsize * sizeof(double *));
double **cost = (double **)malloc(datasetsize * sizeof(double));
char str[100];
for (int i = 0; i < datasetsize; i++)
{
cost[i] = (double *)calloc(NB_OUTPUT, sizeof(double));
}
for (int i = 0; i < nbimageschar; i++)
{
for (int j = 0; j < nbchar; j++)
{
sprintf(str, "src/Dataset/image-%d-%d.bmp", j, i + 1);
input[i * nbchar + j] = imagetomatrix(str, 20);
cost[i * nbchar + j][j] = 1;
}
}
double err = 1.0;
for (int i = 0; i < nb_repetition; i++)
{
err = 0;
for (int j = 0; j < datasetsize; j++)
{
// On fait ensuite appel au ForwardPass sur cette itération <=> on
// voit ce que renvoie notre réseau pour la matrice de pixel
// correspondant à l'image récupérée.
ForwardPass(input[j], network);
double tmp_err = 0.0;
for (int k = 0; k < NB_OUTPUT; k++)
{
tmp_err += (cost[j][k] - network->layers[1].cells[k].output)
* (cost[j][k] - network->layers[1].cells[k].output);
}
tmp_err /= NB_OUTPUT;
err += tmp_err;
BackwardPass(cost[j], input[j], network);
}
err /= datasetsize;
printf("Erreur : %f\n", err);
}
for (int i = 0; i < datasetsize; i++)
{
free(input[i]);
}
for (int i = 0; i < datasetsize; i++)
{
free(cost[i]);
}
free(input);
free(cost);
}

8
NeuralNetwork/training.h Normal file
View File

@ -0,0 +1,8 @@
#ifndef TRAINING_H
#define TRAINING_H
#include "structure.h"
void training(Neural_Network *network, int nb_repetition);
#endif

129
NeuralNetwork/traitement.c Normal file
View File

@ -0,0 +1,129 @@
#include "traitement.h"
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include "structure.h"
#include "toolsnetworks.h"
#include "training.h"
#define NB_PIXEL 400
#define NB_OUTPUT 65
#define DELTA 0.2
// Fonctions de traitement du reseau de neurone : Initialisation, Forwardpass
// et backpropagation.
void Initialisation(Neural_Network *network)
{
network->nb_layers = 2;
network->layers = (Neural_Network_Layer *)malloc(
network->nb_layers * sizeof(Neural_Network_Layer));
network->layers[0] = Create_Layer((int)NB_PIXEL * 2 / 3, NB_PIXEL);
network->layers[1] = Create_Layer(NB_OUTPUT, (int)NB_PIXEL * 2 / 3);
network->output = 0.0;
network->nboutput = NB_OUTPUT;
for (int i = 0; i < network->nb_layers; i++)
{
for (int j = 0; j < network->layers[i].nb_cells; j++)
{
network->layers[i].cells[j].biais = my_rand();
for (int k = 0; k < network->layers[i].cells[j].nb_weight; k++)
{
network->layers[i].cells[j].weights[k] = my_rand();
}
}
}
}
void ForwardPass(double entries[], Neural_Network *network)
{
// Le passage de Xor à OCR est similaire pour le traitement du premier
// layer.
Neural_Network_Layer layer, previous_layer;
// First Layer treatment
layer = (*network).layers[0];
for (int i = 0; i < layer.nb_cells; i++)
{
Neural_Network_Cell cell = layer.cells[i];
double tmp = cell.biais;
for (int j = 0; j < cell.nb_weight; j++)
{
tmp += cell.weights[j] * entries[j];
}
(*network).layers[0].cells[i].output = sigmoid(tmp);
}
// Cette fois, on a plus qu'un noeud en output, donc plus de network.output
// en int, mais on peut mettre un char à la place pour accéder au résultat
// renvoyé par notre réseau.
// Output Layer treatment
layer = (*network).layers[(*network).nb_layers - 1];
previous_layer = (*network).layers[0];
for (int i = 0; i < layer.nb_cells; i++)
{
Neural_Network_Cell cell = layer.cells[i];
double tmp = cell.biais;
for (int k = 0; k < cell.nb_weight; k++)
{
tmp += cell.weights[k] * previous_layer.cells[k].output;
}
(*network).layers[1].cells[i].output = tmp;
}
softmax(&layer);
(*network).output = getIndiceMax(network);
}
void BackwardPass(double *expected, double *entries, Neural_Network *network)
{
for (int i = 0; i < network->nboutput; i++)
{
double cell_output = (*network).layers[1].cells[i].output;
double dCell_output = cell_output * (1 - cell_output);
double dError = (expected[i] - cell_output);
for (int j = 0; j < (*network).layers[1].cells[i].nb_weight; j++)
{
double f = (*network).layers[0].cells[j].output;
(*network).layers[1].cells[i].previous_dError[j] =
(*network).layers[1].cells[i].weights[j] * dCell_output
* dError;
(*network).layers[1].cells[i].weights[j] +=
DELTA * f * dCell_output * dError;
}
(*network).layers[1].cells[i].biais += DELTA * dCell_output * dError;
}
for (int i = 0; i < (*network).layers[0].nb_cells; i++)
{
double cell_output = (*network).layers[0].cells[i].output;
double dg = cell_output * (1 - cell_output);
double dError = 0;
for (int j = 0; j < (*network).layers[1].nb_cells; j++)
{
dError += (*network).layers[1].cells[j].previous_dError[i];
}
for (int j = 0; j < (*network).layers[0].cells[i].nb_weight; j++)
{
double f = entries[j];
(*network).layers[0].cells[i].weights[j] += DELTA * f * dg * dError;
}
(*network).layers[0].cells[i].biais += DELTA * dg * dError;
}
}

View File

@ -0,0 +1,11 @@
#ifndef TRAITEMENT_H
#define TRAITEMENT_H
#include "structure.h"
void Initialisation(Neural_Network *network);
void ForwardPass(double entries[], Neural_Network *network);
void BackwardPass(double *expected, double *entries, Neural_Network *network);
#endif

20
README.md Normal file
View File

@ -0,0 +1,20 @@
# OCR
This project implement an OCR in C. The OCR use a one layer neural network to reconise charactere.
## Compile
You can use this program with this command
```
make
./OCR
```
When the program run you should first load an image in BitMap format
Then you can upgrade the quality of your image with our different options. When you are ready simply press ```play```
## Clean
Use ```make clean``` to delete all trash files

10
all.h Normal file
View File

@ -0,0 +1,10 @@
#include "ImageTreatment/Filter/cleanerimage.h"
#include "ImageTreatment/Segmentation/segmentation.h"
#include "ImageTreatment/Tools/tools.h"
#include "ImageTreatment/display.h"
#include "ImageTreatment/extraction/extractchar.h"
#include "ImageTreatment/extraction/extraction.h"
#include "NeuralNetwork/structure.h"
#include "NeuralNetwork/toolsnetworks.h"
#include "NeuralNetwork/training.h"
#include "NeuralNetwork/traitement.h"

BIN
images/temp.bmp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 908 KiB

230
main.c Normal file
View File

@ -0,0 +1,230 @@
#include <SDL2/SDL.h>
#include <err.h>
#include <gtk/gtk.h>
#include <stdio.h>
#include <stdlib.h>
#include "all.h"
GtkWidget *window;
GtkWidget *wimage;
GtkWidget *image;
GtkWidget *textBox;
GtkWidget *final;
GtkWidget *ninety;
GtkWidget *oneeighty;
GtkWidget *segm;
GtkWidget *grays;
GtkWidget *contra;
GtkWidget *biner;
GtkWidget *play;
GtkWidget *noise;
GtkWidget *rotation;
GtkWidget *nette;
SDL_Surface *surf;
int main(int argc, char *argv[])
{
SDL_Init(SDL_INIT_VIDEO);
GtkBuilder *builder;
gtk_init(&argc, &argv);
builder = gtk_builder_new();
gtk_builder_add_from_file(builder, "main.glade", NULL);
window = GTK_WIDGET(gtk_builder_get_object(builder, "window"));
gtk_builder_connect_signals(builder, NULL);
final = GTK_WIDGET(gtk_builder_get_object(builder, "final"));
textBox = GTK_WIDGET(gtk_builder_get_object(builder, "textBox"));
ninety = GTK_WIDGET(gtk_builder_get_object(builder, "ninety"));
oneeighty = GTK_WIDGET(gtk_builder_get_object(builder, "oneeighty"));
segm = GTK_WIDGET(gtk_builder_get_object(builder, "segmentation"));
grays = GTK_WIDGET(gtk_builder_get_object(builder, "grayscale"));
contra = GTK_WIDGET(gtk_builder_get_object(builder, "contrastes"));
biner = GTK_WIDGET(gtk_builder_get_object(builder, "binarisation"));
play = GTK_WIDGET(gtk_builder_get_object(builder, "lanceTout"));
noise = GTK_WIDGET(gtk_builder_get_object(builder, "noise"));
rotation = GTK_WIDGET(gtk_builder_get_object(builder, "rotation"));
nette = GTK_WIDGET(gtk_builder_get_object(builder, "nettete"));
g_object_unref(builder);
gtk_widget_show(window);
g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);
gtk_main();
return 0;
}
SDL_Surface *load_image(char *path)
{
SDL_Surface *img;
img = SDL_LoadBMP(path);
if (!img)
errx(3, "Can't load %s: %s", path, SDL_GetError());
return img;
}
void choose_image(char *file)
{
gtk_widget_set_sensitive(ninety, TRUE);
gtk_widget_set_sensitive(segm, TRUE);
gtk_widget_set_sensitive(play, TRUE);
gtk_widget_set_sensitive(grays, TRUE);
gtk_widget_set_sensitive(contra, TRUE);
gtk_widget_set_sensitive(biner, TRUE);
gtk_widget_set_sensitive(noise, TRUE);
gtk_widget_set_sensitive(rotation, TRUE);
gtk_widget_set_sensitive(oneeighty, TRUE);
gtk_widget_set_sensitive(nette, TRUE);
surf = load_image(file);
SDL_SaveBMP(surf, "images/temp.bmp");
SDL_FreeSurface(surf);
}
void file_selected(GtkWidget *filechooserbutton)
{
char *filename =
gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(filechooserbutton));
printf("%s\n", filename);
choose_image(filename);
}
// Il faut juste que tu mettes tes fonctions à la place des commentaires. Si
// jamais tu as pas certaines fonctions par exemple pour recup le resultat du
// reseau de neurones dis le moi et je les demanderai à Axelle ou Brice.
// Pour les fonctions, l'image à modifier est sauvegardée dans le fichier
// images/temp.bmp
void play_button()
{
GtkTextBuffer *buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(textBox));
GtkTextIter iter;
gtk_text_buffer_get_iter_at_offset(buffer, &iter, 0);
char *result = calloc(sizeof(char), 10000);
// result sera le texte final
// traitement de l'image (dans le fichier images/temp.bmp)
// segmentation de l'image
// envoi au reseau de neurones
// stockage du resultat du reseau de neurones dans la variable result
SDL_Surface *loadedImage = SDL_LoadBMP("images/temp.bmp");
binerize(loadedImage);
Neural_Network *network = (Neural_Network *)malloc(sizeof(Neural_Network));
Initialisation(network);
Load_Network(network, "SaveNetwork.txt");
__extractpar(loadedImage, network, result);
Free_Network(network);
SDL_FreeSurface(loadedImage);
gtk_text_buffer_insert(buffer, &iter, result, -1);
free(result);
gtk_widget_show(final);
gtk_widget_hide(window);
}
void nettete()
{
static float SharpenMatrix[3][3] = { { 0.0, -1.0, 0.0 },
{ -1.0, 5.0, -1.0 },
{ 0.0, -1.0, 0.0 } };
SDL_Surface *loadedImage = SDL_LoadBMP("images/temp.bmp");
SDL_Window *window = display_img(loadedImage);
wait_for_keypressed();
SDL_DestroyWindow(window);
loadedImage = Convolute(loadedImage, SharpenMatrix);
window = display_img(loadedImage);
SDL_SaveBMP(loadedImage, "images/temp.bmp");
wait_for_keypressed();
SDL_DestroyWindow(window);
SDL_FreeSurface(loadedImage);
}
void plus_oneeighty()
{
SDL_Surface *loadedImage = SDL_LoadBMP("images/temp.bmp");
SDL_Window *window = display_img(loadedImage);
wait_for_keypressed();
SDL_DestroyWindow(window);
grayscale(loadedImage);
binerize(loadedImage);
loadedImage = rotate(180, loadedImage);
window = display_img(loadedImage);
SDL_SaveBMP(loadedImage, "images/temp.bmp");
wait_for_keypressed();
SDL_DestroyWindow(window);
SDL_FreeSurface(loadedImage);
}
void plus_ninety()
{
SDL_Surface *loadedImage = SDL_LoadBMP("images/temp.bmp");
SDL_Window *window = display_img(loadedImage);
wait_for_keypressed();
SDL_DestroyWindow(window);
grayscale(loadedImage);
binerize(loadedImage);
loadedImage = rotate(90, loadedImage);
window = display_img(loadedImage);
SDL_SaveBMP(loadedImage, "images/temp.bmp");
wait_for_keypressed();
SDL_DestroyWindow(window);
SDL_FreeSurface(loadedImage);
}
void gray()
{
// grayscale
}
void bine()
{
// binarisation
}
void seg()
{}
void cont()
{
SDL_Surface *loadedImage = SDL_LoadBMP("images/temp.bmp");
SDL_Window *window = display_img(loadedImage);
wait_for_keypressed();
SDL_DestroyWindow(window);
ConstrastRenforcement(loadedImage, 100);
window = display_img(loadedImage);
wait_for_keypressed();
SDL_DestroyWindow(window);
SDL_FreeSurface(loadedImage);
}
void rot()
{
SDL_Surface *loadedImage = SDL_LoadBMP("images/temp.bmp");
SDL_Window *window = display_img(loadedImage);
wait_for_keypressed();
SDL_DestroyWindow(window);
binerize(loadedImage);
grayscale(loadedImage);
double teta = houghtrasformy(loadedImage);
teta -= 90;
loadedImage = rotate(teta, loadedImage);
window = display_img(loadedImage);
SDL_SaveBMP(loadedImage, "images/temp.bmp");
wait_for_keypressed();
SDL_DestroyWindow(window);
SDL_FreeSurface(loadedImage);
}
void noise_reduction()
{
SDL_Surface *loadedImage = SDL_LoadBMP("images/temp.bmp");
SDL_Window *window = display_img(loadedImage);
wait_for_keypressed();
SDL_DestroyWindow(window);
noiseReduction(loadedImage);
window = display_img(loadedImage);
wait_for_keypressed();
SDL_DestroyWindow(window);
}
void on_quit_clicked()
{
gtk_main_quit();
}

320
main.glade Normal file
View File

@ -0,0 +1,320 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.38.1 -->
<interface>
<requires lib="gtk+" version="3.24"/>
<object class="GtkFileFilter" id="filefilter1">
<patterns>
<pattern>*.bmp</pattern>
</patterns>
</object>
<object class="GtkWindow" id="window">
<property name="name">window</property>
<property name="can-focus">False</property>
<property name="opacity">0.9</property>
<property name="title" translatable="yes">window</property>
<property name="window-position">center</property>
<property name="type-hint">utility</property>
<property name="has-resize-grip">True</property>
<signal name="destroy" handler="destroy" swapped="no"/>
<child>
<object class="GtkFixed" id="fixed1">
<property name="visible">True</property>
<property name="can-focus">False</property>
<child>
<object class="GtkButton" id="lanceTout">
<property name="label">Play</property>
<property name="name">play</property>
<property name="width-request">100</property>
<property name="height-request">80</property>
<property name="visible">True</property>
<property name="sensitive">False</property>
<property name="can-focus">True</property>
<property name="receives-default">True</property>
<property name="resize-mode">immediate</property>
<signal name="clicked" handler="play_button" swapped="no"/>
</object>
<packing>
<property name="x">400</property>
<property name="y">55</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label2">
<property name="width-request">100</property>
<property name="height-request">30</property>
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="label" translatable="yes">Choose a file</property>
<property name="angle">0.06</property>
</object>
<packing>
<property name="x">50</property>
<property name="y">20</property>
</packing>
</child>
<child>
<object class="GtkButton" id="ninety">
<property name="label" translatable="yes">+90°</property>
<property name="name">ninety</property>
<property name="width-request">100</property>
<property name="height-request">80</property>
<property name="visible">True</property>
<property name="sensitive">False</property>
<property name="can-focus">True</property>
<property name="receives-default">True</property>
<property name="resize-mode">immediate</property>
<signal name="clicked" handler="plus_ninety" swapped="no"/>
</object>
<packing>
<property name="x">410</property>
<property name="y">250</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label3">
<property name="width-request">150</property>
<property name="height-request">80</property>
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="label" translatable="yes">OCRigolo</property>
<property name="justify">center</property>
<property name="ellipsize">middle</property>
<attributes>
<attribute name="style" value="normal"/>
<attribute name="weight" value="heavy"/>
<attribute name="variant" value="small-caps"/>
<attribute name="scale" value="1"/>
<attribute name="strikethrough-color" value="#ffffffffffff"/>
</attributes>
</object>
<packing>
<property name="x">200</property>
<property name="y">40</property>
</packing>
</child>
<child>
<object class="GtkButton" id="quit">
<property name="label">gtk-quit</property>
<property name="width-request">500</property>
<property name="height-request">28</property>
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">True</property>
<property name="halign">start</property>
<property name="margin-left">5</property>
<property name="margin-right">5</property>
<property name="margin-top">5</property>
<property name="margin-bottom">5</property>
<property name="border-width">5</property>
<property name="use-stock">True</property>
<property name="xalign">0.44999998807907104</property>
<property name="always-show-image">True</property>
<signal name="clicked" handler="on_quit_clicked" swapped="no"/>
</object>
<packing>
<property name="x">25</property>
<property name="y">330</property>
</packing>
</child>
<child>
<object class="GtkFileChooserButton" id="filechooserbutton1">
<property name="name">chooser</property>
<property name="width-request">100</property>
<property name="height-request">80</property>
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="filter">filefilter1</property>
<signal name="file-set" handler="file_selected" swapped="no"/>
</object>
<packing>
<property name="x">50</property>
<property name="y">55</property>
</packing>
</child>
<child>
<object class="GtkButton" id="grayscale">
<property name="label" translatable="yes">grayscale</property>
<property name="name">grays</property>
<property name="width-request">100</property>
<property name="height-request">80</property>
<property name="visible">True</property>
<property name="sensitive">False</property>
<property name="can-focus">True</property>
<property name="receives-default">True</property>
<property name="resize-mode">immediate</property>
<signal name="clicked" handler="gray" swapped="no"/>
</object>
<packing>
<property name="x">40</property>
<property name="y">150</property>
</packing>
</child>
<child>
<object class="GtkButton" id="binarisation">
<property name="label" translatable="yes">binerize</property>
<property name="name">biner</property>
<property name="width-request">100</property>
<property name="height-request">80</property>
<property name="visible">True</property>
<property name="sensitive">False</property>
<property name="can-focus">True</property>
<property name="receives-default">True</property>
<property name="resize-mode">immediate</property>
<signal name="clicked" handler="bine" swapped="no"/>
</object>
<packing>
<property name="x">165</property>
<property name="y">250</property>
</packing>
</child>
<child>
<object class="GtkButton" id="contrastes">
<property name="label" translatable="yes">contrasts</property>
<property name="name">contra</property>
<property name="width-request">100</property>
<property name="height-request">80</property>
<property name="visible">True</property>
<property name="sensitive">False</property>
<property name="can-focus">True</property>
<property name="receives-default">True</property>
<property name="resize-mode">immediate</property>
<signal name="clicked" handler="cont" swapped="no"/>
</object>
<packing>
<property name="x">410</property>
<property name="y">150</property>
</packing>
</child>
<child>
<object class="GtkButton" id="noise">
<property name="label" translatable="yes">noise</property>
<property name="name">noise</property>
<property name="width-request">100</property>
<property name="height-request">80</property>
<property name="visible">True</property>
<property name="sensitive">False</property>
<property name="can-focus">True</property>
<property name="receives-default">True</property>
<property name="resize-mode">immediate</property>
<signal name="clicked" handler="noise_reduction" swapped="no"/>
</object>
<packing>
<property name="x">285</property>
<property name="y">150</property>
</packing>
</child>
<child>
<object class="GtkButton" id="rotation">
<property name="label" translatable="yes">rotation</property>
<property name="name">rotation</property>
<property name="width-request">100</property>
<property name="height-request">80</property>
<property name="visible">True</property>
<property name="sensitive">False</property>
<property name="can-focus">True</property>
<property name="receives-default">True</property>
<property name="resize-mode">immediate</property>
<signal name="clicked" handler="rot" swapped="no"/>
</object>
<packing>
<property name="x">40</property>
<property name="y">250</property>
</packing>
</child>
<child>
<object class="GtkButton" id="nettete">
<property name="label" translatable="yes">sharpness</property>
<property name="name">nette</property>
<property name="width-request">100</property>
<property name="height-request">80</property>
<property name="visible">True</property>
<property name="sensitive">False</property>
<property name="can-focus">True</property>
<property name="receives-default">True</property>
<property name="resize-mode">immediate</property>
<signal name="clicked" handler="nettete" swapped="no"/>
</object>
<packing>
<property name="x">165</property>
<property name="y">150</property>
</packing>
</child>
<child>
<object class="GtkButton" id="oneeighty">
<property name="label" translatable="yes">+180°</property>
<property name="name">oneeighty</property>
<property name="width-request">100</property>
<property name="height-request">80</property>
<property name="visible">True</property>
<property name="sensitive">False</property>
<property name="can-focus">True</property>
<property name="receives-default">True</property>
<property name="resize-mode">immediate</property>
<signal name="clicked" handler="plus_oneeighty" swapped="no"/>
</object>
<packing>
<property name="x">285</property>
<property name="y">250</property>
</packing>
</child>
</object>
</child>
</object>
<object class="GtkWindow" id="final">
<property name="width-request">640</property>
<property name="can-focus">False</property>
<property name="margin-bottom">1</property>
<child>
<object class="GtkFixed" id="fixed2">
<property name="width-request">640</property>
<property name="visible">True</property>
<property name="can-focus">False</property>
<child>
<object class="GtkTextView" id="textBox">
<property name="name">textBox</property>
<property name="width-request">640</property>
<property name="height-request">460</property>
<property name="visible">True</property>
<property name="can-focus">True</property>
</object>
<packing>
<property name="y">67</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label4">
<property name="width-request">100</property>
<property name="height-request">80</property>
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="label" translatable="yes">Result :</property>
</object>
<packing>
<property name="x">265</property>
</packing>
</child>
<child>
<object class="GtkButton" id="quit1">
<property name="label">gtk-quit</property>
<property name="width-request">465</property>
<property name="height-request">28</property>
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">True</property>
<property name="halign">start</property>
<property name="margin-top">5</property>
<property name="margin-bottom">5</property>
<property name="border-width">5</property>
<property name="use-stock">True</property>
<property name="always-show-image">True</property>
<signal name="clicked" handler="on_quit_clicked" swapped="no"/>
</object>
<packing>
<property name="x">33</property>
<property name="y">529</property>
</packing>
</child>
</object>
</child>
</object>
</interface>

BIN
src/Dataset/image-0-1.bmp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

BIN
src/Dataset/image-0-10.bmp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

BIN
src/Dataset/image-0-11.bmp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

BIN
src/Dataset/image-0-12.bmp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

BIN
src/Dataset/image-0-13.bmp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

BIN
src/Dataset/image-0-14.bmp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

BIN
src/Dataset/image-0-15.bmp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

BIN
src/Dataset/image-0-16.bmp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

BIN
src/Dataset/image-0-17.bmp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

BIN
src/Dataset/image-0-18.bmp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

BIN
src/Dataset/image-0-19.bmp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

BIN
src/Dataset/image-0-2.bmp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

BIN
src/Dataset/image-0-20.bmp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

BIN
src/Dataset/image-0-21.bmp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

BIN
src/Dataset/image-0-22.bmp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

BIN
src/Dataset/image-0-23.bmp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

BIN
src/Dataset/image-0-24.bmp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

BIN
src/Dataset/image-0-25.bmp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

BIN
src/Dataset/image-0-26.bmp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

BIN
src/Dataset/image-0-27.bmp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

BIN
src/Dataset/image-0-28.bmp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

BIN
src/Dataset/image-0-29.bmp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

BIN
src/Dataset/image-0-3.bmp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

BIN
src/Dataset/image-0-30.bmp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

BIN
src/Dataset/image-0-31.bmp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

BIN
src/Dataset/image-0-32.bmp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

BIN
src/Dataset/image-0-33.bmp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

BIN
src/Dataset/image-0-34.bmp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

BIN
src/Dataset/image-0-35.bmp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

BIN
src/Dataset/image-0-36.bmp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

BIN
src/Dataset/image-0-37.bmp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

BIN
src/Dataset/image-0-38.bmp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

BIN
src/Dataset/image-0-39.bmp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

BIN
src/Dataset/image-0-4.bmp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

BIN
src/Dataset/image-0-40.bmp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

BIN
src/Dataset/image-0-41.bmp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

BIN
src/Dataset/image-0-42.bmp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

BIN
src/Dataset/image-0-43.bmp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

BIN
src/Dataset/image-0-44.bmp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

BIN
src/Dataset/image-0-45.bmp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

BIN
src/Dataset/image-0-46.bmp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

BIN
src/Dataset/image-0-47.bmp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

BIN
src/Dataset/image-0-48.bmp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

BIN
src/Dataset/image-0-49.bmp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

BIN
src/Dataset/image-0-5.bmp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

BIN
src/Dataset/image-0-50.bmp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

BIN
src/Dataset/image-0-51.bmp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

BIN
src/Dataset/image-0-52.bmp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

BIN
src/Dataset/image-0-53.bmp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

BIN
src/Dataset/image-0-6.bmp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

BIN
src/Dataset/image-0-7.bmp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

BIN
src/Dataset/image-0-8.bmp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

BIN
src/Dataset/image-0-9.bmp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

BIN
src/Dataset/image-1-1.bmp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

BIN
src/Dataset/image-1-10.bmp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

BIN
src/Dataset/image-1-11.bmp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

BIN
src/Dataset/image-1-12.bmp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

BIN
src/Dataset/image-1-13.bmp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

BIN
src/Dataset/image-1-14.bmp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

BIN
src/Dataset/image-1-15.bmp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

BIN
src/Dataset/image-1-16.bmp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

BIN
src/Dataset/image-1-17.bmp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

BIN
src/Dataset/image-1-18.bmp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

BIN
src/Dataset/image-1-19.bmp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

BIN
src/Dataset/image-1-2.bmp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

BIN
src/Dataset/image-1-20.bmp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

BIN
src/Dataset/image-1-21.bmp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

BIN
src/Dataset/image-1-22.bmp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

BIN
src/Dataset/image-1-23.bmp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

BIN
src/Dataset/image-1-24.bmp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

BIN
src/Dataset/image-1-25.bmp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Some files were not shown because too many files have changed in this diff Show More