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