1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 from opencv.highgui import *
23 from opencv.cv import *
24 from opencv import *
25
26 from tablero import Tablero
27 from check_stone import check_stone
28 from cte import *
29 from notation import notation
30
31
32
34 cont = 0
35 for l in lista:
36 if l[indice] == num:
37 cont += 1
38 return cont
39
40
41
43 """ Contiene todos los datos de las intersecciones de un tablero y las
44 funciones necesarias para encontrarlas.
45 Parámetros necesarios:
46 *image: la imagen del tablero que queremos tratar.
47 *template: el template que vamos a pasarle a la imagen.
48 *size: el tamaño del tablero para saber cuantas intersecciones buscar.
49 """
50
51 - def __init__(self, image, template = "images/tplPoint.png", size = SIZE):
52 """Inicializamos la imágen, el template y algunas variables.
53 @param image: imagen donde se buscarán las intersecciones del tablero o
54 cadena con el directorio donde se encuentra la imagen.
55 @type image: L{IplImage} or C{str}
56 @keyword template: imagen de la plantilla que buscaremos en la imagen.
57 @type template: C{str}
58 @keyword size: el tamaño del tablero
59 @type size: C{int}
60 @return: None
61 @rtype: None
62 """
63
64 if type(image) == str:
65 self.img = cvLoadImageM(image, CV_LOAD_IMAGE_GRAYSCALE)
66 else:
67 self.img =cvCreateImage((image.width,image.height), IPL_DEPTH_8U, 1)
68 cvCvtColor(image, self.img, CV_BGR2GRAY)
69
70 self.tpl = cvLoadImageM(template, CV_LOAD_IMAGE_GRAYSCALE)
71 self.size = size
72 self.intersections = []
73 self.tpl_size = [self.tpl.height, self.tpl.width]
74 self.tablero = Tablero(self.size)
75 self.num_jugada = 1
76 self.color = BLACK
77 self.player_pass = 0
78
80 """ Función recursiva que detecta las intersecciones del tablero usando
81 un template y un valor umbral, el cual iremos variando para
82 hasta obtener el resultado deseado.
83 @keyword threshold: Umbral para usar la búsqueda del template.
84 @type threshold: float.
85 """
86 i = self.intersections
87
88
89 img_aux = cvCreateImage((self.img.width, self.img.height), \
90 self.img.depth, self.img.nChannels)
91 img_aux_2 = cvCreateImage((self.img.width, self.img.height), \
92 self.img.depth, self.img.nChannels)
93
94 tpl_aux = cvCreateImage((self.tpl.width, self.tpl.height), \
95 self.tpl.depth, self.tpl.nChannels)
96 tpl_aux_2 = cvCreateImage((self.tpl.width, self.tpl.height), \
97 self.tpl.depth, self.tpl.nChannels)
98
99
100 cvCanny(self.img, img_aux_2, 50,55,3)
101 cvSmooth(img_aux_2, img_aux, 3)
102 cvCanny(self.tpl, tpl_aux_2, 50,55,3)
103 cvSmooth(tpl_aux_2, tpl_aux, 3)
104
105
106 w = self.img.width - self.tpl.width + 1
107 h = self.img.height - self.tpl.height + 1
108 res = cvCreateImage( cvSize(w,h), IPL_DEPTH_32F, 1)
109
110
111 cvMatchTemplate(img_aux, tpl_aux, res, CV_TM_SQDIFF_NORMED)
112
113
114 for y in range(res.height - 1) :
115 for x in range(res.width - 1):
116
117 s = cvGet2D(res, y, x)
118 if s[0] < threshold:
119 i.append(((x + x + self.tpl.width)/2, \
120 (y + y + self.tpl.height)/2))
121
122
123 repeated = []
124 for u in range(len(i)-1):
125 for v in range(len(i)-1):
126
127
128 if (u < v and abs(i[u][0] - i[v][0]) < self.tpl.width/2 \
129 and abs(i[u][1] - i[v][1]) < self.tpl.height/2 \
130 and repeated.count(i[v]) != 1):
131 repeated.append(i[v])
132
133 for d in repeated:
134 i.remove(d)
135
136 if self.size**2 >= len(i) >= (self.size**2)*(2/3.0):
137 print "el numero de intersecciones es ", len(i)
138 self.i = i
139 return i
140 elif len(i) > self.size**2:
141 threshold = threshold - 0.05
142 elif len(i) < (self.size**2)*(2/3.0):
143 threshold = threshold + 0.05
144
145 if threshold >= 1.0 or threshold < 0.3:
146 print "Inténtalo de nuevo, haz otra foto"
147 mal = True
148 return -1
149
150 return self.detect_intersections(threshold)
151
152
154 """Función que pinta y guarda las intersecciones para chequeos."""
155 for p in self.i:
156 cvCircle(self.img, cvPoint(p[0],p[1]), 5, cvScalar(255,0,0,0), 1, 8, 0)
157
158
159 return self.img
160
161
163 """ Hallamos la media de todas las filas y columnas. """
164
165
166 x_min = [self.img.width for x in xrange(self.size)]
167 x_min.append(0)
168 x_media = [0 for x in xrange(self.size + 1)]
169 verticales = [[] for x in xrange(self.size)]
170
171
172 y_min = [self.img.height for x in xrange(self.size)]
173 y_min.append(0)
174 y_media = [0 for x in xrange(self.size + 1)]
175 horizontales = [[] for x in xrange(self.size)]
176
177 for tam in range(self.size):
178
179 for i in self.intersections:
180 if i[0] < x_min[tam] and i[0] > x_min[tam-1]:
181 x_min[tam] = i[0]
182 if i[1] < y_min[tam] and i[1] > y_min[tam-1]:
183 y_min[tam] = i[1]
184
185
186 for i in self.intersections:
187 if (i[0] >= x_min[tam] and i[0] < x_min[tam] + self.tpl.width/2.0):
188 verticales[tam].append(i)
189 if x_media[tam] < i[0]:
190 x_media[tam] = i[0]
191
192 if (i[1] >= y_min[tam] and \
193 i[1] < y_min[tam] + self.tpl.height/2.0):
194 horizontales[tam].append(i)
195 if y_media[tam] < i[1]:
196 y_media[tam] = i[1]
197 x_min[tam] = x_media[tam]
198 y_min[tam] = y_media[tam]
199
200
201 for x in range(len(x_media)-1):
202 for y in range(len(y_media)-1):
203 self.tablero.matriz[x][y][0] = x_media[x]
204 self.tablero.matriz[x][y][1] = y_media[y]
205
206 cvCircle(self.img, cvPoint(x_media[x], y_media[y]), 2, \
207 cvScalar(255,0,0,0), 1, 8, 0)
208 return self.img
209
210
212 """Busca el punto donde se encuentra la piedra para añadirlo al archivo
213 sgf.
214 @param points: intersecciones donde puede encontrarse la piedra.
215 @type points: C{list(tuples*)}
216 @return: Tupla que contiene:
217 Cadena con la intersección donde se encuentra la piedra.
218 Color de la piedra.
219 Boleano para saber si hemos terminado la partida.
220 @rtype: C{tuple(str, int, bool} # Los candidatos los hemos dividido en dos, los que estaban en
221 # intersecciones libres, y los que estaban en ocupadas.
222 """
223
224 candidates = []
225 self.tablero.get_square()
226 sgf_stone = ""
227 ocupadas = []
228 libres = []
229
230
231
232 if len(points) != 0:
233 for point in points:
234 candidate = [-1, -1]
235 for diagonal in range(19):
236 point_diagonal = self.tablero.matriz[diagonal][diagonal]
237 if abs(point_diagonal[0]-point[0]) < self.tablero.square[0]/2:
238 candidate[0] = diagonal
239 if abs(point_diagonal[1]-point[1]) < self.tablero.square[1]/2:
240 candidate[1] = diagonal
241
242 if (candidate[0] != -1 and candidate[1] != -1):
243 candidates.append((candidate[0], candidate[1]))
244 else:
245 print "Punto", point, "eliminado"
246 print "Hay ", len(candidates), "piedras candidatas"
247
248
249
250
251
252
253 for cand in candidates:
254 ocupado = (self.tablero.matriz[cand[0]][cand[1]][2].values()[-1] != SPACE)
255 if ocupado:
256 ocupadas.append(cand)
257 print "OCUPADA", cand[0]+1, cand[1]+1
258 else:
259 libres.append(cand)
260 print "LIBRE", cand[0]+1, cand[1]+1
261
262
263 if len(libres) == 1:
264 self.tablero.matriz[libres[0][0]][libres[0][1]][2].update({self.num_jugada:self.color})
265 sgf_stone = notation((libres[0][0], libres[0][1]))
266
267
268 elif len(libres) == 0:
269 self.player_pass += 1
270 print "El jugador ha pasado o la piedra no se ha encontrado. \
271 No existian piedras libres"
272
273
274
275
276 else:
277 if self.player_pass == 1:
278 print "La piedra anterior no se había pasado"
279 else:
280 print "Demasiados huecos libres: ", len(libres)
281 exit(0)
282
283
284
285
286 for o in ocupadas:
287 if check_stone(self.tablero, o, self.color):
288 print "Piedra capturada", o
289 self.tablero.matriz[cand[0]][cand[1]][2].update({self.num_jugada:SPACE})
290 else:
291 print "Hemos comprobado que era Falsa la piedra que podia ser capturada ^^ ", o
292
293 else:
294 self.player_pass += 1
295 print "El jugador ha pasado o la piedra no se ha encontrado.\
296 No existian cincunferencias donde buscar."
297
298
299
300 if self.player_pass == 2:
301 r_tupla = (sgf_stone, self.color, True)
302 else:
303 r_tupla = (sgf_stone, self.color, False)
304
305 self.num_jugada += 1
306
307 if self.color == BLACK: self.color = WHITE
308 elif self.color == WHITE: self.color = BLACK
309
310 return r_tupla
311