feat: finished auto detection and splitting
This commit is contained in:
60
src/main.c
60
src/main.c
@ -9,6 +9,7 @@
|
|||||||
#include "utils/EZ_UI/EZ_utils.h"
|
#include "utils/EZ_UI/EZ_utils.h"
|
||||||
#include "utils/EZ_UI/EZ_manager.h"
|
#include "utils/EZ_UI/EZ_manager.h"
|
||||||
#include "utils/Rendering/RenderingUtils.h"
|
#include "utils/Rendering/RenderingUtils.h"
|
||||||
|
#include "utils/Spliting/Spliting.h"
|
||||||
#include "utils/Image/ImageUtils.h"
|
#include "utils/Image/ImageUtils.h"
|
||||||
#include "utils/Application/ApplicationUtils.h"
|
#include "utils/Application/ApplicationUtils.h"
|
||||||
|
|
||||||
@ -25,63 +26,8 @@ int main(int argc, char *argv[])
|
|||||||
{
|
{
|
||||||
application_directory = path_get_directory(argv[0]);
|
application_directory = path_get_directory(argv[0]);
|
||||||
|
|
||||||
SDL_Surface* img = IMG_Load(combine_path(application_directory, "image.png"));
|
|
||||||
|
|
||||||
/*image_to_black_white(img);
|
|
||||||
|
|
||||||
IMG_SavePNG(img, "/mnt/e/Programmation/C/OCRudoku/build/image.png");*/
|
|
||||||
|
|
||||||
/*int x = 4;
|
|
||||||
int y = 2;
|
|
||||||
int w = 1;
|
|
||||||
int h = 1;
|
|
||||||
|
|
||||||
int visited[img->w][img->h];
|
|
||||||
|
|
||||||
for (int x = 0; x < img->w; x++)
|
|
||||||
{
|
|
||||||
for (int y = 0; y < img->h; y++)
|
|
||||||
{
|
|
||||||
visited[x][y] = 0;
|
|
||||||
}
|
|
||||||
}*/
|
|
||||||
|
|
||||||
size_t nb_clusters;
|
|
||||||
|
|
||||||
pixel_cluster* clusters = get_clusters(img, &nb_clusters);
|
|
||||||
|
|
||||||
size_t nb_filtered;
|
|
||||||
|
|
||||||
pixel_cluster* filtered = filter_primary_clusters(clusters, nb_clusters, &nb_filtered);
|
|
||||||
|
|
||||||
size_t nb_linkages;
|
|
||||||
|
|
||||||
size_t* linkages_len;
|
|
||||||
|
|
||||||
pixel_cluster** linkages = get_clusters_linkages(filtered, nb_filtered, &nb_linkages, &linkages_len);
|
|
||||||
|
|
||||||
for (size_t i = 0; i < nb_linkages; i++)
|
|
||||||
{
|
|
||||||
printf("%li: %li\n", i, linkages_len[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
(void)linkages;
|
|
||||||
|
|
||||||
/*for (size_t i = 0; i < nb_filtered; i++)
|
|
||||||
{
|
|
||||||
SDL_Surface* surf = copy_cluster(img, filtered[i]);
|
|
||||||
|
|
||||||
char* path;
|
|
||||||
|
|
||||||
asprintf(&path, "/mnt/e/Programmation/C/OCRudoku/build/res/cluster_%li.png", i);
|
|
||||||
|
|
||||||
IMG_SavePNG(surf, path);
|
|
||||||
|
|
||||||
SDL_FreeSurface(surf);
|
|
||||||
}*/
|
|
||||||
|
|
||||||
//SDL Init
|
//SDL Init
|
||||||
/*SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTS);
|
SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTS);
|
||||||
SDL_Window* window = SDL_CreateWindow("OCRudoku", 0, 0, 1280, 720, SDL_WINDOW_RESIZABLE);
|
SDL_Window* window = SDL_CreateWindow("OCRudoku", 0, 0, 1280, 720, SDL_WINDOW_RESIZABLE);
|
||||||
|
|
||||||
if (window == NULL)
|
if (window == NULL)
|
||||||
@ -135,7 +81,7 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
SDL_DestroyRenderer(renderer);
|
SDL_DestroyRenderer(renderer);
|
||||||
SDL_DestroyWindow(window);
|
SDL_DestroyWindow(window);
|
||||||
SDL_Quit();*/
|
SDL_Quit();
|
||||||
|
|
||||||
(void)argc, (void) argv;
|
(void)argc, (void) argv;
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
#define _GNU_SOURCE
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <err.h>
|
#include <err.h>
|
||||||
@ -407,430 +406,6 @@ SDL_Surface* rotate_pixels(SDL_Surface* surface, double angle) {
|
|||||||
return rotated_surface;
|
return rotated_surface;
|
||||||
}
|
}
|
||||||
|
|
||||||
int get_bin_pixel(SDL_Surface* surface, int x, int y)
|
|
||||||
{
|
|
||||||
Uint8 r,g,b;
|
|
||||||
SDL_GetRGB(get_pixel_val(get_pixel_pt(surface, x, y), surface->format), surface->format, &r, &g, &b);
|
|
||||||
|
|
||||||
int bright = (r + g + b) / 3;
|
|
||||||
|
|
||||||
return bright < 127;
|
|
||||||
}
|
|
||||||
|
|
||||||
void get_cluster_size(SDL_Surface* surface, int* x, int* y, int* w, int* h, int currx, int curry, int visited[surface->w][surface->h])
|
|
||||||
{
|
|
||||||
visited[currx][curry] = 1;
|
|
||||||
|
|
||||||
for (int i = 0; i < 9; i++)
|
|
||||||
{
|
|
||||||
if (i == 4)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
int dx = (i%3) - 1;
|
|
||||||
int dy = (i/3) - 1;
|
|
||||||
|
|
||||||
if (dx < 0 && currx <= 0)
|
|
||||||
continue;
|
|
||||||
if (dx > 0 && currx >= surface->w - 1)
|
|
||||||
continue;
|
|
||||||
if (dy < 0 && curry <= 0)
|
|
||||||
continue;
|
|
||||||
if (dy > 0 && curry >= surface->h - 1)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (visited[currx + dx][curry + dy])
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (get_bin_pixel(surface, currx + dx, curry + dy))
|
|
||||||
{
|
|
||||||
if (currx + dx < *x)
|
|
||||||
{
|
|
||||||
(*x)--;
|
|
||||||
(*w)++;
|
|
||||||
}
|
|
||||||
if (curry + dy < *y)
|
|
||||||
{
|
|
||||||
(*y)--;
|
|
||||||
(*h)++;
|
|
||||||
}
|
|
||||||
if (currx + dx >= (*x) + (*w))
|
|
||||||
(*w)++;
|
|
||||||
if (curry + dy >= (*y) + (*h))
|
|
||||||
(*h)++;
|
|
||||||
|
|
||||||
get_cluster_size(surface, x, y, w, h, currx + dx, curry + dy, visited);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void copy_cluster_aux(SDL_Surface* surface, SDL_Surface* new_surface, int x, int y, int sx, int sy, int visited[])
|
|
||||||
{
|
|
||||||
visited[((y - sy) * new_surface->w) + (x - sx)] = 1;
|
|
||||||
|
|
||||||
set_pixel_val(get_pixel_pt(new_surface, x - sx, y - sy), new_surface->format, SDL_MapRGB(new_surface->format, 0, 0, 0));
|
|
||||||
|
|
||||||
for (int i = 0; i < 9; i++)
|
|
||||||
{
|
|
||||||
if (i == 4)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
int dx = (i%3) - 1;
|
|
||||||
int dy = (i/3) - 1;
|
|
||||||
|
|
||||||
if (dx < 0 && x - sx <= 0)
|
|
||||||
continue;
|
|
||||||
if (dx > 0 && x - sx >= new_surface->w - 1)
|
|
||||||
continue;
|
|
||||||
if (dy < 0 && y - sy <= 0)
|
|
||||||
continue;
|
|
||||||
if (dy > 0 && y - sy >= new_surface->h - 1)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (visited[(((y - sy) + dy) * new_surface->w) + (x - sx) + dx])
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (get_bin_pixel(surface, x + dx, y + dy))
|
|
||||||
{
|
|
||||||
copy_cluster_aux(surface, new_surface, x + dx, y + dy, sx, sy, visited);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
SDL_Surface* copy_cluster(SDL_Surface* surface, pixel_cluster cluster_rect)
|
|
||||||
{
|
|
||||||
int visited[cluster_rect.w * cluster_rect.h];
|
|
||||||
|
|
||||||
SDL_Surface* new_surface = SDL_CreateRGBSurface(0, cluster_rect.w, cluster_rect.h, 32, 0, 0, 0, 0);
|
|
||||||
|
|
||||||
if (new_surface == NULL)
|
|
||||||
errx(EXIT_FAILURE, "copy_cluster: failed to create surface!");
|
|
||||||
|
|
||||||
for (int i = 0; i < cluster_rect.w; i++)
|
|
||||||
{
|
|
||||||
for (int j = 0; j < cluster_rect.h; j++)
|
|
||||||
{
|
|
||||||
visited[(j * cluster_rect.w) + i] = 0;
|
|
||||||
set_pixel_val(get_pixel_pt(new_surface, i, j), new_surface->format, SDL_MapRGB(new_surface->format, 255, 255, 255));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
copy_cluster_aux(surface, new_surface, cluster_rect.start_x, cluster_rect.start_y, cluster_rect.origin_x, cluster_rect.origin_y, visited);
|
|
||||||
|
|
||||||
return new_surface;
|
|
||||||
}
|
|
||||||
|
|
||||||
pixel_cluster* get_clusters(SDL_Surface* surface, size_t* cluster_nb)
|
|
||||||
{
|
|
||||||
*cluster_nb = 0;
|
|
||||||
|
|
||||||
int visited[surface->w][surface->h];
|
|
||||||
|
|
||||||
for (int y = 0; y < surface->h; y++)
|
|
||||||
{
|
|
||||||
for (int x = 0; x < surface->w; x++)
|
|
||||||
{
|
|
||||||
visited[x][y] = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int y = 0; y < surface->h; y++)
|
|
||||||
{
|
|
||||||
for (int x = 0; x < surface->w; x++)
|
|
||||||
{
|
|
||||||
if (visited[x][y])
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (!get_bin_pixel(surface, x, y))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
int nx = x;
|
|
||||||
int ny = y;
|
|
||||||
int w = 1;
|
|
||||||
int h = 1;
|
|
||||||
|
|
||||||
get_cluster_size(surface, &nx, &ny, &w, &h, nx, ny, visited);
|
|
||||||
|
|
||||||
(*cluster_nb)++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int y = 0; y < surface->h; y++)
|
|
||||||
{
|
|
||||||
for (int x = 0; x < surface->w; x++)
|
|
||||||
{
|
|
||||||
visited[x][y] = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pixel_cluster* result = calloc(*cluster_nb, sizeof(pixel_cluster));
|
|
||||||
|
|
||||||
size_t i = 0;
|
|
||||||
|
|
||||||
for (int y = 0; y < surface->h; y++)
|
|
||||||
{
|
|
||||||
for (int x = 0; x < surface->w; x++)
|
|
||||||
{
|
|
||||||
if (visited[x][y])
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (!get_bin_pixel(surface, x, y))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
int nx = x;
|
|
||||||
int ny = y;
|
|
||||||
int w = 1;
|
|
||||||
int h = 1;
|
|
||||||
|
|
||||||
get_cluster_size(surface, &nx, &ny, &w, &h, nx, ny, visited);
|
|
||||||
|
|
||||||
result[i] = (pixel_cluster){
|
|
||||||
nx,
|
|
||||||
ny,
|
|
||||||
w,
|
|
||||||
h,
|
|
||||||
x,
|
|
||||||
y
|
|
||||||
};
|
|
||||||
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
pixel_cluster* filter_primary_clusters(pixel_cluster* clusters, size_t nb_clusters, size_t* filtered_nb)
|
|
||||||
{
|
|
||||||
*filtered_nb = 0;
|
|
||||||
|
|
||||||
for (size_t i = 0; i < nb_clusters; i++)
|
|
||||||
{
|
|
||||||
pixel_cluster curr = clusters[i];
|
|
||||||
|
|
||||||
int found = 0;
|
|
||||||
|
|
||||||
for (size_t j = 0; j < nb_clusters; j++)
|
|
||||||
{
|
|
||||||
if (i == j)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
pixel_cluster target = clusters[j];
|
|
||||||
|
|
||||||
if (curr.origin_x <= target.origin_x && curr.origin_x + curr.w >= target.origin_x + target.w) //target contained in curr of x
|
|
||||||
{
|
|
||||||
if (curr.origin_y <= target.origin_y && curr.origin_y + curr.h >= target.origin_y + target.h) //target contained in curr of y
|
|
||||||
{
|
|
||||||
found = 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (found)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
(*filtered_nb)++;
|
|
||||||
}
|
|
||||||
|
|
||||||
pixel_cluster* filtered = calloc(*filtered_nb, sizeof(pixel_cluster));
|
|
||||||
|
|
||||||
size_t filtered_count = 0;
|
|
||||||
|
|
||||||
for (size_t i = 0; i < nb_clusters; i++)
|
|
||||||
{
|
|
||||||
pixel_cluster curr = clusters[i];
|
|
||||||
|
|
||||||
int found = 0;
|
|
||||||
|
|
||||||
for (size_t j = 0; j < nb_clusters; j++)
|
|
||||||
{
|
|
||||||
if (i == j)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
pixel_cluster target = clusters[j];
|
|
||||||
|
|
||||||
if (curr.origin_x <= target.origin_x && curr.origin_x + curr.w >= target.origin_x + target.w) //target contained in curr of x
|
|
||||||
{
|
|
||||||
if (curr.origin_y <= target.origin_y && curr.origin_y + curr.h >= target.origin_y + target.h) //target contained in curr of y
|
|
||||||
{
|
|
||||||
found = 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (found)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
filtered[filtered_count] = curr;
|
|
||||||
filtered_count++;
|
|
||||||
}
|
|
||||||
|
|
||||||
return filtered;
|
|
||||||
}
|
|
||||||
|
|
||||||
void get_cluster_center(pixel_cluster cluster, int* x, int* y)
|
|
||||||
{
|
|
||||||
*x = cluster.origin_x + (cluster.w / 2);
|
|
||||||
*y = cluster.origin_y + (cluster.h / 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
double distance_between(int x1, int y1, int x2, int y2)
|
|
||||||
{
|
|
||||||
int dx = x2 - x1;
|
|
||||||
int dy = y2 - y1;
|
|
||||||
|
|
||||||
return sqrt((double)(dx * dx) + (double)(dy * dy));
|
|
||||||
}
|
|
||||||
|
|
||||||
void get_cluster_linkage_count_aux(pixel_cluster* clusters, size_t start, size_t cluster_nb, size_t* linkage_nb, double distance, double margin, int visited[cluster_nb])
|
|
||||||
{
|
|
||||||
int center_x, center_y;
|
|
||||||
|
|
||||||
get_cluster_center(clusters[start], ¢er_x, ¢er_y);
|
|
||||||
|
|
||||||
for (size_t i = 0; i < cluster_nb; i++)
|
|
||||||
{
|
|
||||||
if (visited[i])
|
|
||||||
continue;
|
|
||||||
|
|
||||||
int other_x, other_y;
|
|
||||||
|
|
||||||
get_cluster_center(clusters[i], &other_x, &other_y);
|
|
||||||
|
|
||||||
double dist = distance_between(center_x, center_y, other_x, other_y);
|
|
||||||
|
|
||||||
if (dist > distance - (distance * margin) && dist < distance + (distance * margin))
|
|
||||||
{
|
|
||||||
visited[i] = 1;
|
|
||||||
(*linkage_nb)++;
|
|
||||||
get_cluster_linkage_count_aux(clusters, i, cluster_nb, linkage_nb, distance, margin, visited);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void get_cluster_linkage_aux(pixel_cluster* clusters, size_t start, size_t cluster_nb, size_t* current_linkage, pixel_cluster* arr, double distance, double margin, int visited[cluster_nb])
|
|
||||||
{
|
|
||||||
int center_x, center_y;
|
|
||||||
|
|
||||||
get_cluster_center(clusters[start], ¢er_x, ¢er_y);
|
|
||||||
|
|
||||||
for (size_t i = 0; i < cluster_nb; i++)
|
|
||||||
{
|
|
||||||
if (visited[i])
|
|
||||||
continue;
|
|
||||||
|
|
||||||
int other_x, other_y;
|
|
||||||
|
|
||||||
get_cluster_center(clusters[i], &other_x, &other_y);
|
|
||||||
|
|
||||||
double dist = distance_between(center_x, center_y, other_x, other_y);
|
|
||||||
|
|
||||||
if (dist > distance - (distance * margin) && dist < distance + (distance * margin))
|
|
||||||
{
|
|
||||||
visited[i] = 1;
|
|
||||||
arr[*current_linkage] = clusters[i];
|
|
||||||
(*current_linkage)++;
|
|
||||||
get_cluster_linkage_aux(clusters, i, cluster_nb, current_linkage, arr, distance, margin, visited);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pixel_cluster* get_cluster_linkage(pixel_cluster* clusters, size_t start, size_t cluster_nb, size_t* linkage_nb, int visited[cluster_nb])
|
|
||||||
{
|
|
||||||
double margin = 0.2;
|
|
||||||
|
|
||||||
int center_x, center_y;
|
|
||||||
|
|
||||||
get_cluster_center(clusters[start], ¢er_x, ¢er_y);
|
|
||||||
|
|
||||||
double min_distance = -1;
|
|
||||||
|
|
||||||
for (size_t i = 0; i < cluster_nb; i++)
|
|
||||||
{
|
|
||||||
if (i == start)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
int other_x, other_y;
|
|
||||||
|
|
||||||
get_cluster_center(clusters[i], &other_x, &other_y);
|
|
||||||
|
|
||||||
double dist = distance_between(center_x, center_y, other_x, other_y);
|
|
||||||
|
|
||||||
if (min_distance < 0 || dist < min_distance)
|
|
||||||
{
|
|
||||||
min_distance = dist;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
*linkage_nb = 1;
|
|
||||||
|
|
||||||
visited[start] = 1;
|
|
||||||
|
|
||||||
int visited_copy[cluster_nb];
|
|
||||||
|
|
||||||
for (size_t i = 0; i < cluster_nb; i++)
|
|
||||||
{
|
|
||||||
visited_copy[i] = visited[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
get_cluster_linkage_count_aux(clusters, start, cluster_nb, linkage_nb, min_distance, margin, visited_copy);
|
|
||||||
|
|
||||||
pixel_cluster* linkage = calloc(*linkage_nb, sizeof(pixel_cluster));
|
|
||||||
|
|
||||||
linkage[0] = clusters[start];
|
|
||||||
|
|
||||||
size_t linkage_count = 1;
|
|
||||||
|
|
||||||
get_cluster_linkage_aux(clusters, start, cluster_nb, &linkage_count, linkage, min_distance, margin, visited);
|
|
||||||
|
|
||||||
return linkage;
|
|
||||||
}
|
|
||||||
|
|
||||||
pixel_cluster** get_clusters_linkages(pixel_cluster* clusters, size_t cluster_nb, size_t* nb_linkages, size_t** linkage_len)
|
|
||||||
{
|
|
||||||
int visited[cluster_nb];
|
|
||||||
|
|
||||||
for (size_t i = 0; i < cluster_nb; i++)
|
|
||||||
{
|
|
||||||
visited[i] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
*nb_linkages = 0;
|
|
||||||
|
|
||||||
for (size_t i = 0; i < cluster_nb; i++)
|
|
||||||
{
|
|
||||||
if (visited[i])
|
|
||||||
continue;
|
|
||||||
|
|
||||||
size_t nb;
|
|
||||||
|
|
||||||
get_cluster_linkage(clusters, i, cluster_nb, &nb, visited);
|
|
||||||
(*nb_linkages)++;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (size_t i = 0; i < cluster_nb; i++)
|
|
||||||
{
|
|
||||||
visited[i] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
pixel_cluster** linkages = calloc(*nb_linkages, sizeof(pixel_cluster*));
|
|
||||||
*linkage_len = calloc(*nb_linkages, sizeof(size_t));
|
|
||||||
|
|
||||||
size_t current_pos = 0;
|
|
||||||
|
|
||||||
for (size_t i = 0; i < cluster_nb; i++)
|
|
||||||
{
|
|
||||||
if (visited[i])
|
|
||||||
continue;
|
|
||||||
|
|
||||||
linkages[current_pos] = get_cluster_linkage(clusters, i, cluster_nb, &((*linkage_len)[current_pos]), visited);
|
|
||||||
current_pos++;
|
|
||||||
}
|
|
||||||
|
|
||||||
return linkages;
|
|
||||||
}
|
|
||||||
|
|
||||||
// int testsupercool(void) {
|
// int testsupercool(void) {
|
||||||
// if (SDL_Init(SDL_INIT_VIDEO) != 0) {
|
// if (SDL_Init(SDL_INIT_VIDEO) != 0) {
|
||||||
// errx(1, "SDL_Init Error: %s", SDL_GetError());
|
// errx(1, "SDL_Init Error: %s", SDL_GetError());
|
||||||
|
@ -9,15 +9,6 @@
|
|||||||
#ifndef IMAGE_UTILS_H
|
#ifndef IMAGE_UTILS_H
|
||||||
#define IMAGE_UTILS_H
|
#define IMAGE_UTILS_H
|
||||||
|
|
||||||
typedef struct{
|
|
||||||
int origin_x;
|
|
||||||
int origin_y;
|
|
||||||
int w;
|
|
||||||
int h;
|
|
||||||
int start_x;
|
|
||||||
int start_y;
|
|
||||||
}pixel_cluster;
|
|
||||||
|
|
||||||
void render_image_file(const char* file, SDL_Renderer* renderer, const SDL_Rect* srcrect, const SDL_Rect* dstrect);
|
void render_image_file(const char* file, SDL_Renderer* renderer, const SDL_Rect* srcrect, const SDL_Rect* dstrect);
|
||||||
|
|
||||||
void render_full_image_file(const char* file, SDL_Renderer* renderer, const SDL_Rect* dstrect);
|
void render_full_image_file(const char* file, SDL_Renderer* renderer, const SDL_Rect* dstrect);
|
||||||
@ -42,14 +33,6 @@ SDL_Surface* create_sub_surface(SDL_Surface* surface, SDL_Rect rect);
|
|||||||
|
|
||||||
SDL_Surface* rotate_pixels(SDL_Surface* surface, double angle);
|
SDL_Surface* rotate_pixels(SDL_Surface* surface, double angle);
|
||||||
|
|
||||||
SDL_Surface* copy_cluster(SDL_Surface* surface, pixel_cluster cluster_rect);
|
|
||||||
|
|
||||||
pixel_cluster* get_clusters(SDL_Surface* surface, size_t* cluster_nb);
|
|
||||||
|
|
||||||
pixel_cluster* filter_primary_clusters(pixel_cluster* clusters, size_t nb_clusters, size_t* filtered_nb);
|
|
||||||
|
|
||||||
pixel_cluster** get_clusters_linkages(pixel_cluster* clusters, size_t cluster_nb, size_t* nb_linkages, size_t** linkage_len);
|
|
||||||
|
|
||||||
int testsupercool(void);
|
int testsupercool(void);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
#define _GNU_SOURCE
|
||||||
#include <err.h>
|
#include <err.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@ -481,3 +482,537 @@ void export_split_word_list(SDL_Surface* surface, SDL_Rect rect, const char* sav
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int get_bin_pixel(SDL_Surface* surface, int x, int y)
|
||||||
|
{
|
||||||
|
Uint8 r,g,b;
|
||||||
|
SDL_GetRGB(get_pixel_val(get_pixel_pt(surface, x, y), surface->format), surface->format, &r, &g, &b);
|
||||||
|
|
||||||
|
int bright = (r + g + b) / 3;
|
||||||
|
|
||||||
|
return bright < 127;
|
||||||
|
}
|
||||||
|
|
||||||
|
void get_cluster_size(SDL_Surface* surface, int* x, int* y, int* w, int* h, int currx, int curry, int visited[surface->w][surface->h])
|
||||||
|
{
|
||||||
|
visited[currx][curry] = 1;
|
||||||
|
|
||||||
|
for (int i = 0; i < 9; i++)
|
||||||
|
{
|
||||||
|
if (i == 4)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
int dx = (i%3) - 1;
|
||||||
|
int dy = (i/3) - 1;
|
||||||
|
|
||||||
|
if (dx < 0 && currx <= 0)
|
||||||
|
continue;
|
||||||
|
if (dx > 0 && currx >= surface->w - 1)
|
||||||
|
continue;
|
||||||
|
if (dy < 0 && curry <= 0)
|
||||||
|
continue;
|
||||||
|
if (dy > 0 && curry >= surface->h - 1)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (visited[currx + dx][curry + dy])
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (get_bin_pixel(surface, currx + dx, curry + dy))
|
||||||
|
{
|
||||||
|
if (currx + dx < *x)
|
||||||
|
{
|
||||||
|
(*x)--;
|
||||||
|
(*w)++;
|
||||||
|
}
|
||||||
|
if (curry + dy < *y)
|
||||||
|
{
|
||||||
|
(*y)--;
|
||||||
|
(*h)++;
|
||||||
|
}
|
||||||
|
if (currx + dx >= (*x) + (*w))
|
||||||
|
(*w)++;
|
||||||
|
if (curry + dy >= (*y) + (*h))
|
||||||
|
(*h)++;
|
||||||
|
|
||||||
|
get_cluster_size(surface, x, y, w, h, currx + dx, curry + dy, visited);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void copy_cluster_aux(SDL_Surface* surface, SDL_Surface* new_surface, int x, int y, int sx, int sy, int visited[])
|
||||||
|
{
|
||||||
|
visited[((y - sy) * new_surface->w) + (x - sx)] = 1;
|
||||||
|
|
||||||
|
set_pixel_val(get_pixel_pt(new_surface, x - sx, y - sy), new_surface->format, SDL_MapRGB(new_surface->format, 0, 0, 0));
|
||||||
|
|
||||||
|
for (int i = 0; i < 9; i++)
|
||||||
|
{
|
||||||
|
if (i == 4)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
int dx = (i%3) - 1;
|
||||||
|
int dy = (i/3) - 1;
|
||||||
|
|
||||||
|
if (dx < 0 && x - sx <= 0)
|
||||||
|
continue;
|
||||||
|
if (dx > 0 && x - sx >= new_surface->w - 1)
|
||||||
|
continue;
|
||||||
|
if (dy < 0 && y - sy <= 0)
|
||||||
|
continue;
|
||||||
|
if (dy > 0 && y - sy >= new_surface->h - 1)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (visited[(((y - sy) + dy) * new_surface->w) + (x - sx) + dx])
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (get_bin_pixel(surface, x + dx, y + dy))
|
||||||
|
{
|
||||||
|
copy_cluster_aux(surface, new_surface, x + dx, y + dy, sx, sy, visited);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SDL_Surface* copy_cluster(SDL_Surface* surface, pixel_cluster cluster_rect)
|
||||||
|
{
|
||||||
|
int visited[cluster_rect.w * cluster_rect.h];
|
||||||
|
|
||||||
|
SDL_Surface* new_surface = SDL_CreateRGBSurface(0, cluster_rect.w, cluster_rect.h, 32, 0, 0, 0, 0);
|
||||||
|
|
||||||
|
if (new_surface == NULL)
|
||||||
|
errx(EXIT_FAILURE, "copy_cluster: failed to create surface!");
|
||||||
|
|
||||||
|
for (int i = 0; i < cluster_rect.w; i++)
|
||||||
|
{
|
||||||
|
for (int j = 0; j < cluster_rect.h; j++)
|
||||||
|
{
|
||||||
|
visited[(j * cluster_rect.w) + i] = 0;
|
||||||
|
set_pixel_val(get_pixel_pt(new_surface, i, j), new_surface->format, SDL_MapRGB(new_surface->format, 255, 255, 255));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
copy_cluster_aux(surface, new_surface, cluster_rect.start_x, cluster_rect.start_y, cluster_rect.origin_x, cluster_rect.origin_y, visited);
|
||||||
|
|
||||||
|
return new_surface;
|
||||||
|
}
|
||||||
|
|
||||||
|
pixel_cluster* get_clusters(SDL_Surface* surface, size_t* cluster_nb)
|
||||||
|
{
|
||||||
|
*cluster_nb = 0;
|
||||||
|
|
||||||
|
int visited[surface->w][surface->h];
|
||||||
|
|
||||||
|
for (int y = 0; y < surface->h; y++)
|
||||||
|
{
|
||||||
|
for (int x = 0; x < surface->w; x++)
|
||||||
|
{
|
||||||
|
visited[x][y] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int y = 0; y < surface->h; y++)
|
||||||
|
{
|
||||||
|
for (int x = 0; x < surface->w; x++)
|
||||||
|
{
|
||||||
|
if (visited[x][y])
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (!get_bin_pixel(surface, x, y))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
int nx = x;
|
||||||
|
int ny = y;
|
||||||
|
int w = 1;
|
||||||
|
int h = 1;
|
||||||
|
|
||||||
|
get_cluster_size(surface, &nx, &ny, &w, &h, nx, ny, visited);
|
||||||
|
|
||||||
|
(*cluster_nb)++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int y = 0; y < surface->h; y++)
|
||||||
|
{
|
||||||
|
for (int x = 0; x < surface->w; x++)
|
||||||
|
{
|
||||||
|
visited[x][y] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pixel_cluster* result = calloc(*cluster_nb, sizeof(pixel_cluster));
|
||||||
|
|
||||||
|
size_t i = 0;
|
||||||
|
|
||||||
|
for (int y = 0; y < surface->h; y++)
|
||||||
|
{
|
||||||
|
for (int x = 0; x < surface->w; x++)
|
||||||
|
{
|
||||||
|
if (visited[x][y])
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (!get_bin_pixel(surface, x, y))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
int nx = x;
|
||||||
|
int ny = y;
|
||||||
|
int w = 1;
|
||||||
|
int h = 1;
|
||||||
|
|
||||||
|
get_cluster_size(surface, &nx, &ny, &w, &h, nx, ny, visited);
|
||||||
|
|
||||||
|
result[i] = (pixel_cluster){
|
||||||
|
nx,
|
||||||
|
ny,
|
||||||
|
w,
|
||||||
|
h,
|
||||||
|
x,
|
||||||
|
y
|
||||||
|
};
|
||||||
|
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
pixel_cluster* filter_primary_clusters(pixel_cluster* clusters, size_t nb_clusters, size_t* filtered_nb)
|
||||||
|
{
|
||||||
|
*filtered_nb = 0;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < nb_clusters; i++)
|
||||||
|
{
|
||||||
|
pixel_cluster curr = clusters[i];
|
||||||
|
|
||||||
|
int found = 0;
|
||||||
|
|
||||||
|
for (size_t j = 0; j < nb_clusters; j++)
|
||||||
|
{
|
||||||
|
if (i == j)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
pixel_cluster target = clusters[j];
|
||||||
|
|
||||||
|
if (curr.origin_x <= target.origin_x && curr.origin_x + curr.w >= target.origin_x + target.w) //target contained in curr of x
|
||||||
|
{
|
||||||
|
if (curr.origin_y <= target.origin_y && curr.origin_y + curr.h >= target.origin_y + target.h) //target contained in curr of y
|
||||||
|
{
|
||||||
|
found = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (found)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
(*filtered_nb)++;
|
||||||
|
}
|
||||||
|
|
||||||
|
pixel_cluster* filtered = calloc(*filtered_nb, sizeof(pixel_cluster));
|
||||||
|
|
||||||
|
size_t filtered_count = 0;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < nb_clusters; i++)
|
||||||
|
{
|
||||||
|
pixel_cluster curr = clusters[i];
|
||||||
|
|
||||||
|
int found = 0;
|
||||||
|
|
||||||
|
for (size_t j = 0; j < nb_clusters; j++)
|
||||||
|
{
|
||||||
|
if (i == j)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
pixel_cluster target = clusters[j];
|
||||||
|
|
||||||
|
if (curr.origin_x <= target.origin_x && curr.origin_x + curr.w >= target.origin_x + target.w) //target contained in curr of x
|
||||||
|
{
|
||||||
|
if (curr.origin_y <= target.origin_y && curr.origin_y + curr.h >= target.origin_y + target.h) //target contained in curr of y
|
||||||
|
{
|
||||||
|
found = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (found)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
filtered[filtered_count] = curr;
|
||||||
|
filtered_count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return filtered;
|
||||||
|
}
|
||||||
|
|
||||||
|
void get_cluster_center(pixel_cluster cluster, int* x, int* y)
|
||||||
|
{
|
||||||
|
*x = cluster.origin_x + (cluster.w / 2);
|
||||||
|
*y = cluster.origin_y + (cluster.h / 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
double distance_between(int x1, int y1, int x2, int y2)
|
||||||
|
{
|
||||||
|
int dx = x2 - x1;
|
||||||
|
int dy = y2 - y1;
|
||||||
|
|
||||||
|
return sqrt((double)(dx * dx) + (double)(dy * dy));
|
||||||
|
}
|
||||||
|
|
||||||
|
void get_cluster_linkage_count_aux(pixel_cluster* clusters, size_t start, size_t cluster_nb, size_t* linkage_nb, double distance, double margin, int visited[cluster_nb])
|
||||||
|
{
|
||||||
|
int center_x, center_y;
|
||||||
|
|
||||||
|
get_cluster_center(clusters[start], ¢er_x, ¢er_y);
|
||||||
|
|
||||||
|
for (size_t i = 0; i < cluster_nb; i++)
|
||||||
|
{
|
||||||
|
if (visited[i])
|
||||||
|
continue;
|
||||||
|
|
||||||
|
int other_x, other_y;
|
||||||
|
|
||||||
|
get_cluster_center(clusters[i], &other_x, &other_y);
|
||||||
|
|
||||||
|
double dist = distance_between(center_x, center_y, other_x, other_y);
|
||||||
|
|
||||||
|
if (dist > distance - (distance * margin) && dist < distance + (distance * margin))
|
||||||
|
{
|
||||||
|
visited[i] = 1;
|
||||||
|
(*linkage_nb)++;
|
||||||
|
get_cluster_linkage_count_aux(clusters, i, cluster_nb, linkage_nb, distance, margin, visited);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void get_cluster_linkage_aux(pixel_cluster* clusters, size_t start, size_t cluster_nb, size_t* current_linkage, pixel_cluster* arr, double distance, double margin, int visited[cluster_nb])
|
||||||
|
{
|
||||||
|
int center_x, center_y;
|
||||||
|
|
||||||
|
get_cluster_center(clusters[start], ¢er_x, ¢er_y);
|
||||||
|
|
||||||
|
for (size_t i = 0; i < cluster_nb; i++)
|
||||||
|
{
|
||||||
|
if (visited[i])
|
||||||
|
continue;
|
||||||
|
|
||||||
|
int other_x, other_y;
|
||||||
|
|
||||||
|
get_cluster_center(clusters[i], &other_x, &other_y);
|
||||||
|
|
||||||
|
double dist = distance_between(center_x, center_y, other_x, other_y);
|
||||||
|
|
||||||
|
if (dist > distance - (distance * margin) && dist < distance + (distance * margin))
|
||||||
|
{
|
||||||
|
visited[i] = 1;
|
||||||
|
arr[*current_linkage] = clusters[i];
|
||||||
|
(*current_linkage)++;
|
||||||
|
get_cluster_linkage_aux(clusters, i, cluster_nb, current_linkage, arr, distance, margin, visited);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pixel_cluster* get_cluster_linkage(pixel_cluster* clusters, size_t start, size_t cluster_nb, size_t* linkage_nb, int visited[cluster_nb])
|
||||||
|
{
|
||||||
|
double margin = 0.2;
|
||||||
|
|
||||||
|
int center_x, center_y;
|
||||||
|
|
||||||
|
get_cluster_center(clusters[start], ¢er_x, ¢er_y);
|
||||||
|
|
||||||
|
double min_distance = -1;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < cluster_nb; i++)
|
||||||
|
{
|
||||||
|
if (i == start)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
int other_x, other_y;
|
||||||
|
|
||||||
|
get_cluster_center(clusters[i], &other_x, &other_y);
|
||||||
|
|
||||||
|
double dist = distance_between(center_x, center_y, other_x, other_y);
|
||||||
|
|
||||||
|
if (min_distance < 0 || dist < min_distance)
|
||||||
|
{
|
||||||
|
min_distance = dist;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*linkage_nb = 1;
|
||||||
|
|
||||||
|
visited[start] = 1;
|
||||||
|
|
||||||
|
int visited_copy[cluster_nb];
|
||||||
|
|
||||||
|
for (size_t i = 0; i < cluster_nb; i++)
|
||||||
|
{
|
||||||
|
visited_copy[i] = visited[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
get_cluster_linkage_count_aux(clusters, start, cluster_nb, linkage_nb, min_distance, margin, visited_copy);
|
||||||
|
|
||||||
|
pixel_cluster* linkage = calloc(*linkage_nb, sizeof(pixel_cluster));
|
||||||
|
|
||||||
|
linkage[0] = clusters[start];
|
||||||
|
|
||||||
|
size_t linkage_count = 1;
|
||||||
|
|
||||||
|
get_cluster_linkage_aux(clusters, start, cluster_nb, &linkage_count, linkage, min_distance, margin, visited);
|
||||||
|
|
||||||
|
return linkage;
|
||||||
|
}
|
||||||
|
|
||||||
|
pixel_cluster** get_clusters_linkages(pixel_cluster* clusters, size_t cluster_nb, size_t* nb_linkages, size_t** linkage_len)
|
||||||
|
{
|
||||||
|
int visited[cluster_nb];
|
||||||
|
|
||||||
|
for (size_t i = 0; i < cluster_nb; i++)
|
||||||
|
{
|
||||||
|
visited[i] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
*nb_linkages = 0;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < cluster_nb; i++)
|
||||||
|
{
|
||||||
|
if (visited[i])
|
||||||
|
continue;
|
||||||
|
|
||||||
|
size_t nb;
|
||||||
|
|
||||||
|
get_cluster_linkage(clusters, i, cluster_nb, &nb, visited);
|
||||||
|
(*nb_linkages)++;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (size_t i = 0; i < cluster_nb; i++)
|
||||||
|
{
|
||||||
|
visited[i] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
pixel_cluster** linkages = calloc(*nb_linkages, sizeof(pixel_cluster*));
|
||||||
|
*linkage_len = calloc(*nb_linkages, sizeof(size_t));
|
||||||
|
|
||||||
|
size_t current_pos = 0;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < cluster_nb; i++)
|
||||||
|
{
|
||||||
|
if (visited[i])
|
||||||
|
continue;
|
||||||
|
|
||||||
|
linkages[current_pos] = get_cluster_linkage(clusters, i, cluster_nb, &((*linkage_len)[current_pos]), visited);
|
||||||
|
current_pos++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return linkages;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t get_grid_cluster(size_t nb_linkages, size_t* linkage_len)
|
||||||
|
{
|
||||||
|
size_t max_len = 0;
|
||||||
|
size_t max_index = -1;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < nb_linkages; i++)
|
||||||
|
{
|
||||||
|
if (linkage_len[i] > max_len)
|
||||||
|
{
|
||||||
|
max_len = linkage_len[i];
|
||||||
|
max_index = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return max_index;
|
||||||
|
}
|
||||||
|
|
||||||
|
void export_word_cluster(SDL_Surface* surface, pixel_cluster* clusters, size_t cluster_nb, size_t word_nb, char* word_dir)
|
||||||
|
{
|
||||||
|
for (size_t i = 0; i < cluster_nb; i++)
|
||||||
|
{
|
||||||
|
char* path;
|
||||||
|
asprintf(&path, "%s/word_%li_letter_%li.png", word_dir, word_nb, i);
|
||||||
|
|
||||||
|
SDL_Surface* letter_surf = copy_cluster(surface, clusters[i]);
|
||||||
|
|
||||||
|
IMG_SavePNG(letter_surf, path);
|
||||||
|
|
||||||
|
SDL_FreeSurface(letter_surf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int same_pos(int pos1, int pos2, int margin)
|
||||||
|
{
|
||||||
|
return pos1 >= pos2-margin && pos1 <= pos2+margin;
|
||||||
|
}
|
||||||
|
|
||||||
|
void export_grid_cluster(SDL_Surface* surface, pixel_cluster* clusters, size_t cluster_nb, char* grid_dir)
|
||||||
|
{
|
||||||
|
|
||||||
|
for (size_t i = 0; i < cluster_nb; i++)
|
||||||
|
{
|
||||||
|
int x = 0;
|
||||||
|
int y = 0;
|
||||||
|
|
||||||
|
int curr_x = 0;
|
||||||
|
int curr_y = 0;
|
||||||
|
|
||||||
|
for (size_t j = 0; j < cluster_nb; j++)
|
||||||
|
{
|
||||||
|
if (clusters[j].origin_x > curr_x + 4 && clusters[j].origin_x <= clusters[i].origin_x + 4)
|
||||||
|
{
|
||||||
|
x++;
|
||||||
|
curr_x = clusters[j].origin_x;
|
||||||
|
}
|
||||||
|
if (clusters[j].origin_y > curr_y + 4 && clusters[j].origin_y <= clusters[i].origin_y + 4)
|
||||||
|
{
|
||||||
|
y++;
|
||||||
|
curr_y = clusters[j].origin_y;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (same_pos(clusters[i].origin_x, curr_x, 4) && same_pos(clusters[i].origin_y, curr_y, 4))
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
char* path;
|
||||||
|
asprintf(&path, "%s/grid_%i_%i.png", grid_dir, x, y);
|
||||||
|
|
||||||
|
SDL_Surface* letter_surf = copy_cluster(surface, clusters[i]);
|
||||||
|
|
||||||
|
IMG_SavePNG(letter_surf, path);
|
||||||
|
|
||||||
|
SDL_FreeSurface(letter_surf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pixel_cluster** get_main_linkages(SDL_Surface* surface, size_t* nb_linkages, size_t** linkages_len)
|
||||||
|
{
|
||||||
|
size_t nb_clusters;
|
||||||
|
|
||||||
|
pixel_cluster* clusters = get_clusters(surface, &nb_clusters);
|
||||||
|
|
||||||
|
size_t nb_filtered;
|
||||||
|
|
||||||
|
pixel_cluster* filtered = filter_primary_clusters(clusters, nb_clusters, &nb_filtered);
|
||||||
|
|
||||||
|
pixel_cluster** linkages = get_clusters_linkages(filtered, nb_filtered, nb_linkages, linkages_len);
|
||||||
|
|
||||||
|
return linkages;
|
||||||
|
}
|
||||||
|
|
||||||
|
void export_main_linkages(SDL_Surface* surface, pixel_cluster** linkages, size_t nb_linkages, size_t* linkages_len)
|
||||||
|
{
|
||||||
|
size_t grid = get_grid_cluster(nb_linkages, linkages_len);
|
||||||
|
|
||||||
|
for (size_t i = 0; i < nb_linkages; i++)
|
||||||
|
{
|
||||||
|
if (i == grid)
|
||||||
|
{
|
||||||
|
export_grid_cluster(surface, linkages[i], linkages_len[i], "/mnt/d/DataDocuments/Dev/C/OCRudoku/build/res/grid");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
export_word_cluster(surface, linkages[i], linkages_len[i], i, "/mnt/d/DataDocuments/Dev/C/OCRudoku/build/res/words");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -3,6 +3,15 @@
|
|||||||
#ifndef SPLITING_H
|
#ifndef SPLITING_H
|
||||||
#define SPLITING_H
|
#define SPLITING_H
|
||||||
|
|
||||||
|
typedef struct{
|
||||||
|
int origin_x;
|
||||||
|
int origin_y;
|
||||||
|
int w;
|
||||||
|
int h;
|
||||||
|
int start_x;
|
||||||
|
int start_y;
|
||||||
|
}pixel_cluster;
|
||||||
|
|
||||||
void spilt_grid_vertical(SDL_Surface* surface, SDL_Rect rect);
|
void spilt_grid_vertical(SDL_Surface* surface, SDL_Rect rect);
|
||||||
|
|
||||||
int* get_grid_vertical_split(SDL_Surface* surface, SDL_Rect rect, int* nb_splits);
|
int* get_grid_vertical_split(SDL_Surface* surface, SDL_Rect rect, int* nb_splits);
|
||||||
@ -17,4 +26,12 @@ void export_split_word_list(SDL_Surface* surface, SDL_Rect rect, const char* sav
|
|||||||
|
|
||||||
void export_split_grid(SDL_Surface* surface, SDL_Rect rect, const char* save_dir);
|
void export_split_grid(SDL_Surface* surface, SDL_Rect rect, const char* save_dir);
|
||||||
|
|
||||||
|
void export_word_cluster(SDL_Surface* surface, pixel_cluster* clusters, size_t cluster_nb, size_t word_nb, char* word_dir);
|
||||||
|
|
||||||
|
void export_grid_cluster(SDL_Surface* surface, pixel_cluster* clusters, size_t cluster_nb, char* grid_dir);
|
||||||
|
|
||||||
|
pixel_cluster** get_main_linkages(SDL_Surface* surface, size_t* nb_linkages, size_t** linkages_len);
|
||||||
|
|
||||||
|
void export_main_linkages(SDL_Surface* surface, pixel_cluster** linkages, size_t nb_linkages, size_t* linkages_len);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Reference in New Issue
Block a user