OCR/ImageTreatment/Tools/tools.c

265 lines
6.0 KiB
C

#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;
}