-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathgetSudoku.m
109 lines (85 loc) · 3.92 KB
/
getSudoku.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
function sudoku = getSudoku(img)
%Corregimos la perspectiva
img = CorrectPerspective(img);
%Obtemos las casillas
s = getSquares(img);
%Si no hemos encontrado 81 casillas exactemente vamos a tener problemas
%al clasificar los números así que en el caso de que no la pillemos
%bien devolvemos 0 para volver a intentarlo.
if length(s) == 81
%Obtenemos los recuadros ordenados por sus coordenadas
roi = sortByCoordinates(s);
umbral = graythresh(img);
Igray = rgb2gray(img);
binary = imbinarize(Igray,'adaptive','ForegroundPolarity','dark');
% A partir de ahora eliminamos todo lo que no es un número,
% es decir, las casillas
BWComplement = ~binary;
ele = strel('square',4);
%BWComplement = imdilate(BWComplement,ele);
BWComplement = imclose(BWComplement,ele);
%Buscamos todas las componentes conexas de la imagen (Conjuntos de
%píxeles conectados de color blanco)
% CC = bwconncomp(BWComplement);
%Las componentes conexas más grandes, con más pixeles, será el recuadro y
%los bordes en el caso de que la imagen esté rotada (se quedan bordes
%negros)
% numberPixels = cellfun(@numel, CC.PixelIdxList);
% idx = find(numberPixels > 5000);
% for i=1: length(idx)
% BWComplement(CC.PixelIdxList{idx(i)}) = 0;
% end
% %Por la iluminación a veces detecta pequeñas zonas pintadas
% % dónde no hay nada así que también los eliminamos para no tener
% % problema al clasificar números
% idx = find(numberPixels < 400);
% for i=1: length(idx)
% BWComplement(CC.PixelIdxList{idx(i)}) = 0;
% end
%Le indicamos donde tiene que buscar los numeros, es decir,
%en las casillas que ya hemos calculado
% roi = vertcat(s(:).BoundingBox);
%Moldeamos los números de la siguiente imagen para que no haya
% Problema por si un número es demasiado gordo(Sin esqueleto)
BWComplement = imclose(BWComplement, ele);
ele = strel('square',3);
BWComplement = imerode(BWComplement, ele);
BWComplement = imerode(BWComplement, ele);
%Esqueleto y dilatar, así pillaba mejor los 8 pero empezaba a
%fallar con los 6
% ele = strel('square',4);
% BWComplement=bwmorph(BWComplement,'thin',Inf);
% BWComplement = imclose(BWComplement,ele);
% BWComplement = imdilate(BWComplement,ele);
%Obtenemos los numeros de la siguiente imagen
%figure, imshow(BWComplement);
results = ocr(BWComplement, roi, 'TextLayout', 'Character','CharacterSet','0':'9');
% % Eliminamos los espacios en blanco de los resultados
ce = cell(1,numel(results));
for i = 1:numel(results)
ce{i} = deblank(results(i).Text);
end
%Imprimir los numeros detectados en la imagen
% final = insertObjectAnnotation(im2uint8(binary), 'Rectangle', roi, ce);
% figure
% imshow(final)
%como tenemos problemas al pillar los 8 entonces cuando estemos en
%una casilla sin detectar número pero no esté vacía vamos a decir
%que es un 8
sudoku = zeros(9,9);
for i = 1: length(ce)
if strcmp(ce{i}, '')
r = uint16(roi(i, :));
img = binary(r(2): r(2)+r(4), r(1):r(1)+r(3));
if(length(find(img == 0)) > 0.2 * numel(img))
sudoku((ind2sub([9 9],i))) = 8;
end
else
sudoku((ind2sub([9 9],i))) = str2num(ce{i});
end
end
sudoku = sudoku';
else
sudoku = 0;
end
end