OCR/ImageTreatment/Segmentation/segmentation.c

572 lines
14 KiB
C
Raw Normal View History

2022-02-08 18:16:25 +00:00
#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);
}