Beispiel #1
0
 def test_corner_points(self):
     result = self.field._get_corner_points()
     self.assertEqual(len(result), 4)
     self.assertEqual(type(result), tuple)
     self.assertEqual(Validator.is_positive_number(list(result[0])), True)
     self.assertEqual(Validator.is_positive_number(list(result[1])), True)
     self.assertEqual(Validator.is_positive_number(list(result[2])), True)
     self.assertEqual(Validator.is_positive_number(list(result[3])), True)
     self.assertEqual(result, ((74, 84), (492, 70), (37, 512), (520, 520)))
Beispiel #2
0
 def _get_cropped_tl_br_point(self, x1, y1, x2, y2):
     if Validator.is_positive_number([x1, y1, x2, y2]):
         return (x1 + self.cut_border,
                 y1 + self.cut_border), (x2 - self.cut_border,
                                         y2 - self.cut_border)
     raise InappropriateArgsError(
         "getting cropped top-left bottom-right point")
Beispiel #3
0
 def _get_image_from_coords(self, x_error, x, y_error, y, padding):
     if Validator.is_positive_number([x_error, x, y_error, y, y_error, padding]) and \
             Validator.is_type([x, y, x_error, y_error, padding], int):
         x1, y1, x2, y2 = self._get_tr_bl_corners_of_little_square(
             x_error, x, y_error, y, padding)
         return self._extract_field_square_with_number_image(x1, y1, x2, y2)
     raise InappropriateArgsError("getting image from coors!")
Beispiel #4
0
 def display_message(self, text, after_error_text, color, error_duration=1):
     if Validator.is_type([text, after_error_text, color], str) and Validator.is_positive_number(error_duration):
         self.info_label.config(fg=color)
         self.info_label["text"] = text
         return self.after(error_duration * 1000, self.set_info_label, after_error_text)
     else:
         raise InappropriateArgsError("setting info label text!")
Beispiel #5
0
 def _create_white_picture(self, width, height):
     if Validator.is_positive_number([width, height]) and Validator.is_type(
         [width, height], int):
         img = np.zeros((height, width), dtype=np.uint8)
         img.fill(255)  # must be white
         return img
     raise InappropriateArgsError("creating white picture")
Beispiel #6
0
 def __init__(self, parent, height=10, width=10, **kwargs):
     if Validator.is_positive_number([height, width]) and \
             (Validator.is_type(parent, tkinter.Tk) or Validator.is_type(parent, Frame)):
         super().__init__(master=parent, height=height, width=width)
         self.grid(kwargs)
     else:
         raise InappropriateArgsError("creating a frame!")
Beispiel #7
0
 def _extract_field_square_with_number_image(self, x1, y1, x2, y2):
     if Validator.is_positive_number(
         [x1, y1, x2, y2]) and Validator.is_type([x1, y1, x2, y2], int):
         p1, p4 = self._get_cropped_tl_br_point(x1, y1, x2, y2)
         r = cv2.boundingRect(np.array([[p1[0], p1[1]], [p4[0], p4[1]]]))
         return self.img[r[1]:r[1] + r[3], r[0]:r[0] + r[2]]
     raise InappropriateArgsError(
         "extracting field square with number image")
Beispiel #8
0
 def _get_higher_lower_diff(self, width, height):
     if Validator.is_positive_number([width, height]):
         higher, lower = max(width, height), min(width, height)
         diff = lower * 100
         if higher > 0:
             diff = (lower / higher) * 100
         return higher, lower, diff
     raise InappropriateArgsError("getting higher lower difference")
Beispiel #9
0
 def _prepare_original_for_recognition(self, img, height, width, x, y,
                                       kernel):
     # thicker the number and extract it (hopefully)
     if Validator.is_type([img, kernel],
                          np.ndarray) and Validator.is_positive_number(
                              [height, width, x, y]):
         original = cv2.erode(img, kernel)
         return original[y:y + height, x:x + width]
     raise InappropriateArgsError("preparing image for recognition!")
Beispiel #10
0
 def _get_tr_bl_corners_of_little_square(self, x_error, x, y_error, y,
                                         padding):
     if Validator.is_positive_number([x, y, x_error, y_error, padding]):
         x_error = self._update_error(x, x_error)
         x1, y1 = self._calculate_x_y(x, y, x_error, y_error, padding)
         next_point_error = self._update_error(x + 1, x_error)
         return x1, y1, x1 + padding + next_point_error, y1 + padding + y_error
     raise InappropriateArgsError(
         "getting top-right and bottom-left corners of little square")
Beispiel #11
0
 def _draw_lines_if_true(self, y, padding, y_error, draw):
     if not (Validator.is_positive_number([y, padding, y_error])
             and Validator.is_type(draw, bool)):
         raise InappropriateArgsError("drawing lines")
     if draw:
         self._draw_line(0, padding * y + y_error, self.width,
                         padding * y + y_error)
         self._draw_line(padding * y + y_error, 0, padding * y + y_error,
                         self.height)
         return True
     return False
 def _hide_smaller_blobs(self, max_point):
     if Validator.is_type(max_point,
                          tuple) and Validator.is_positive_number(
                              [max_point[0], max_point[1]]):
         for y in range(self.height):
             row = self.changing_img[y]
             for x in range(self.width):
                 if row[x] == 64 and max_point[0] != x and max_point[
                         1] != y:  # fills gray parts with black
                     cv2.floodFill(self.changing_img, None, (x, y), 0)
         return True
     raise InappropriateArgsError("hiding smaller blobs with point: " +
                                  str(max_point))
Beispiel #13
0
 def _change_image_like_training_images(self, image, width, height):
     # this function adds white corners around the digit. The image is then more similar to the training set images!
     if Validator.is_positive_number([width, height]) and Validator.is_type([width, height], int) and \
             Validator.is_type(image, np.ndarray) and width >= image.shape[1] and height >= image.shape[0]:
         new_img = self._create_white_picture(width,
                                              height)  # completely white
         smaller_height, smaller_width = self._get_height_width(image)
         x_offset, y_offset = self._get_offset(width, height,
                                               smaller_height,
                                               smaller_width)
         new_img[y_offset:y_offset + smaller_height,
                 x_offset:x_offset + smaller_width] = image
         return new_img
     raise InappropriateArgsError("changing image like training images!")
 def _run_kmeans_on_coords(self, lines, k, **kwargs):
     if Validator.is_type(lines,
                          np.ndarray) and Validator.is_positive_number(
                              k) and Validator.is_type(k, int):
         # Define criteria = (type, max_iter, epsilon)
         criteria, flags, attempts = self._get_criteria_flags_attempts(
             **kwargs)
         pts = self._get_coords_of_angle(lines)
         # run k-means on the coordinates
         labels, centers = cv2.kmeans(pts, k, None, criteria, attempts,
                                      flags)[1:]
         return labels.reshape(-1)  # transpose to row vector
     raise InappropriateArgsError("running k-means on coordinates: " +
                                  str(lines))
Beispiel #15
0
 def __init__(self, parent, number, readonly=False, **kwargs):
     if Validator.is_positive_number(number) and Validator.is_type(number, int) and number <= 9 and\
             (Validator.is_type(parent, tkinter.Tk) or Validator.is_type(parent, Frame)) and \
             Validator.is_type(readonly, bool):
         self.value = tkinter.StringVar()
         self.value.trace('w', self._limit_size)
         super().__init__(master=parent, textvariable=self.value)
         self.grid(kwargs)
         self.config(justify='center', width=var.SUDOKU_SQUARE_SIZE, font=(var.NUMBERS_FONT, var.NUMBERS_SIZE))
         if number > 0:  # 0 is empty
             self.value.set(str(number))
         if readonly:
             self.config(state='readonly')
     else:
         raise InappropriateArgsError("creating an entry!")
 def _seperate_lines(self, lines, k=2, **kwargs):
     """
     Groups lines based on angle with k-means.
     Uses k-means on the coordinates of the angle on the unit circle
     to segment `k` angles inside `lines`.
     The result is separation of vertical and horizontal lines.
     """
     if Validator.is_type(lines,
                          np.ndarray) and Validator.is_positive_number(
                              k) and Validator.is_type(k, int):
         labels = self._run_kmeans_on_coords(lines, k, **kwargs)
         # separate lines based on their k-means label
         separated = defaultdict(list)
         for i, line in zip(range(len(lines)), lines):
             separated[labels[i]].append(line)
         return list(separated.values())
     raise InappropriateArgsError(
         "seperating vertical and horizontal lines")
 def _update_corners(self, x, y, tl_point, tr_point, bl_point, br_point):
     if Validator.is_positive_number([x, y]) and Validator.is_type(
         [tl_point, tr_point, bl_point, br_point], tuple):
         color = self.changing_img[y][
             x]  # color of that pixel, if it is white (255) we are on the blob
         if x + y < tl_point[0] + tl_point[
                 1] and color == 255:  # point is more upper-left than the current one
             tl_point = x, y
         if y - x > bl_point[1] - bl_point[
                 0] and color == 255:  # point is more bottom-left than the current one
             bl_point = x, y
         if x - y > tr_point[0] - tr_point[
                 1] and color == 255:  # point is more top-right than the current one
             tr_point = x, y
         if x + y > br_point[0] + br_point[
                 1] and color == 255:  # point is more bottom-right than the current one
             br_point = x, y
         return tl_point, tr_point, bl_point, br_point
     raise InappropriateArgsError("updating corner points with x: " +
                                  str(x) + " and y: " + str(y))
Beispiel #18
0
 def _is_safe(matrix, n, r, c):
     if Validator.is_9x9_integers_field(matrix) and \
             Validator.is_positive_number([n, r, c]) and Validator.is_type([n, r, c], int):  # positive integers
         #  checking in row
         for i in range(0, SIZE):
             #  there is a cell with same value
             if matrix[r][i] == n:
                 return False
         #  checking in column
         for i in range(0, SIZE):
             #  there is a cell with same value
             if matrix[i][c] == n:
                 return False
         row_start = (r // 3) * 3
         col_start = (c // 3) * 3
         #  checking submatrix
         for i in range(row_start, row_start + 3):
             for j in range(col_start, col_start + 3):
                 if matrix[i][j] == n:
                     return False
         return True
     raise InappropriateArgsError("checking if sudoku is save")
Beispiel #19
0
 def test_correct_is_positive_number(self):
     self.assertEqual(Validator.is_positive_number(1), True)
     self.assertEqual(Validator.is_positive_number(1.0), True)
     self.assertEqual(Validator.is_positive_number(0.0), True)
     self.assertEqual(Validator.is_positive_number(-0.0), True)
     self.assertEqual(Validator.is_positive_number([1.0, 2, 3]), True)
Beispiel #20
0
 def test_incorrect_is_positive_number(self):
     self.assertEqual(Validator.is_positive_number(-1), False)
     self.assertEqual(Validator.is_positive_number(-1.0), False)
     self.assertEqual(Validator.is_positive_number("wrong"), False)
     self.assertEqual(Validator.is_positive_number([-1.0, -2, 3, "wrong"]),
                      False)
Beispiel #21
0
 def _calculate_middle(self, width, height):
     if Validator.is_positive_number([width, height]):
         return (self.winfo_screenwidth() // 2) - (width // 2), (self.winfo_screenheight() // 2) - (height // 2)
     raise InappropriateArgsError("calculating center of the screen!")
Beispiel #22
0
 def _get_offset(self, width, height, smaller_height, smaller_width):
     if Validator.is_positive_number(
         [width, height, smaller_width, smaller_height]):
         return (width - smaller_width) // 2, (height - smaller_height) // 2
     raise InappropriateArgsError("getting the offset")
Beispiel #23
0
 def _update_error(self, line, error):
     if not Validator.is_positive_number([line, error]):
         raise InappropriateArgsError("updating error")
     if line != 0 and self.sudoku_size % line == 0:  # increase err when there is a thicker line (3, 6 for 9x9 field)
         return error + self.error
     return error
Beispiel #24
0
 def _draw_line(self, x1, y1, x2, y2):
     if Validator.is_positive_number([x1, y1, x2, y2]):
         return cv2.line(self.img, (x1, y1), (x2, y2), (255, 255, 255))
     raise InappropriateArgsError("drawing the line")
Beispiel #25
0
 def _get_kernel(self, height, width):
     if Validator.is_positive_number([height, width]) and Validator.is_type(
         [height, width], int):
         return np.ones((height, width), np.uint8)
     raise InappropriateArgsError("getting kernel")
Beispiel #26
0
 def _calculate_x_y(self, x, y, x_error, y_error, padding):
     if Validator.is_positive_number([x, y, x_error, y_error, padding]):
         return x * padding + x_error, y * padding + y_error
     raise InappropriateArgsError("calculating x and y")