OCR project
|
@ -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')
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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
|
|
@ -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);
|
||||
}
|
|
@ -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
|
|
@ -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;
|
||||
}
|
|
@ -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
|
|
@ -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;
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
#include <SDL2/SDL.h>
|
||||
|
||||
SDL_Window *display_img(SDL_Surface *image);
|
||||
void wait_for_keypressed();
|
|
@ -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);
|
||||
}
|
|
@ -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
|
|
@ -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);
|
||||
}
|
|
@ -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
|
|
@ -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
|
||||
|
||||
|
||||
|
|
@ -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;
|
||||
}
|
|
@ -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
|
|
@ -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;
|
||||
}
|
|
@ -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
|
|
@ -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;
|
||||
}
|
|
@ -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
|
|
@ -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);
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
#ifndef TRAINING_H
|
||||
#define TRAINING_H
|
||||
|
||||
#include "structure.h"
|
||||
|
||||
void training(Neural_Network *network, int nb_repetition);
|
||||
|
||||
#endif
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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
|
|
@ -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
|
|
@ -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"
|
After Width: | Height: | Size: 908 KiB |
|
@ -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();
|
||||
}
|
|
@ -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>
|
After Width: | Height: | Size: 3.1 KiB |
After Width: | Height: | Size: 3.1 KiB |
After Width: | Height: | Size: 3.1 KiB |
After Width: | Height: | Size: 3.1 KiB |
After Width: | Height: | Size: 3.1 KiB |
After Width: | Height: | Size: 3.1 KiB |
After Width: | Height: | Size: 3.1 KiB |
After Width: | Height: | Size: 3.1 KiB |
After Width: | Height: | Size: 3.1 KiB |
After Width: | Height: | Size: 3.1 KiB |
After Width: | Height: | Size: 3.1 KiB |
After Width: | Height: | Size: 3.1 KiB |
After Width: | Height: | Size: 3.1 KiB |
After Width: | Height: | Size: 3.1 KiB |
After Width: | Height: | Size: 3.1 KiB |
After Width: | Height: | Size: 3.1 KiB |
After Width: | Height: | Size: 3.1 KiB |
After Width: | Height: | Size: 3.1 KiB |
After Width: | Height: | Size: 3.1 KiB |
After Width: | Height: | Size: 3.1 KiB |
After Width: | Height: | Size: 3.1 KiB |
After Width: | Height: | Size: 3.1 KiB |
After Width: | Height: | Size: 3.1 KiB |
After Width: | Height: | Size: 3.1 KiB |
After Width: | Height: | Size: 3.1 KiB |
After Width: | Height: | Size: 3.1 KiB |
After Width: | Height: | Size: 3.1 KiB |
After Width: | Height: | Size: 3.1 KiB |
After Width: | Height: | Size: 3.1 KiB |
After Width: | Height: | Size: 3.1 KiB |
After Width: | Height: | Size: 3.1 KiB |
After Width: | Height: | Size: 3.1 KiB |
After Width: | Height: | Size: 3.1 KiB |
After Width: | Height: | Size: 3.1 KiB |
After Width: | Height: | Size: 3.1 KiB |
After Width: | Height: | Size: 3.1 KiB |
After Width: | Height: | Size: 3.1 KiB |
After Width: | Height: | Size: 3.1 KiB |
After Width: | Height: | Size: 3.1 KiB |
After Width: | Height: | Size: 3.1 KiB |
After Width: | Height: | Size: 3.1 KiB |
After Width: | Height: | Size: 3.1 KiB |
After Width: | Height: | Size: 3.1 KiB |
After Width: | Height: | Size: 3.1 KiB |
After Width: | Height: | Size: 3.1 KiB |
After Width: | Height: | Size: 3.1 KiB |
After Width: | Height: | Size: 3.1 KiB |
After Width: | Height: | Size: 3.1 KiB |
After Width: | Height: | Size: 3.1 KiB |
After Width: | Height: | Size: 3.1 KiB |
After Width: | Height: | Size: 3.1 KiB |
After Width: | Height: | Size: 3.1 KiB |
After Width: | Height: | Size: 3.1 KiB |
After Width: | Height: | Size: 3.1 KiB |
After Width: | Height: | Size: 3.1 KiB |
After Width: | Height: | Size: 3.1 KiB |
After Width: | Height: | Size: 3.1 KiB |
After Width: | Height: | Size: 3.1 KiB |
After Width: | Height: | Size: 3.1 KiB |
After Width: | Height: | Size: 3.1 KiB |
After Width: | Height: | Size: 3.1 KiB |
After Width: | Height: | Size: 3.1 KiB |
After Width: | Height: | Size: 3.1 KiB |
After Width: | Height: | Size: 3.1 KiB |
After Width: | Height: | Size: 3.1 KiB |
After Width: | Height: | Size: 3.1 KiB |
After Width: | Height: | Size: 3.1 KiB |
After Width: | Height: | Size: 3.1 KiB |
After Width: | Height: | Size: 3.1 KiB |
After Width: | Height: | Size: 3.1 KiB |
After Width: | Height: | Size: 3.1 KiB |