def solve_image(fp): try: img = resize_keep_aspect(cv2.imread(fp, cv2.IMREAD_COLOR)) processed = process(img) corners = get_corners(processed) warped = transform(corners, processed) mask = extract_lines(warped) numbers = cv2.bitwise_and(warped, mask) digits_unsorted = extract_digits(numbers) digits_subd = subdivide(numbers) digits_sorted = sort_digits(digits_subd, digits_unsorted, img_dims) digits_border = add_border(digits_sorted) puzzle = img_to_array(digits_border, img_dims) solved = solve(puzzle.copy().tolist() ) # Solve function modifies original puzzle var warped_img = transform(corners, img) subd = subdivide(warped_img) subd_soln = put_solution(subd, solved, puzzle) warped_soln = stitch_img(subd_soln, (warped_img.shape[0], warped_img.shape[1])) warped_inverse = inverse_perspective(warped_soln, img, np.array(corners)) show(warped_inverse) except Exception as e: print(f'Image not solvable: {e}')
def solve_image(fp, font_color, font_path): if font_color is None: font_color = (0, 127, 255) if font_path is None: font_path = './python/assets/FreeMono.ttf' try: img = resize_keep_aspect(cv2.imread(fp, cv2.IMREAD_COLOR)) except AttributeError: sys.stderr.write('Error: Image path not valid') sys.exit() processed = process(img) corners = get_corners(processed) warped = transform(corners, processed) vertical_lines, horizontal_lines = get_grid_lines(warped) mask = create_grid_mask(vertical_lines, horizontal_lines) numbers = cv2.bitwise_and(warped, mask) digits_sorted = extract_digits(numbers) digits_border = add_border(digits_sorted) digits_subd = subdivide(numbers) try: digits_with_zeros = add_zeros(digits_border, digits_subd) except IndexError: sys.stderr.write('Error: Image too warped') sys.exit() try: puzzle = img_to_array(digits_with_zeros, img_dims) except AttributeError: sys.stderr.write('Error: OCR predictions failed') sys.exit() solved = solve( puzzle.copy().tolist()) # Solve function modifies original puzzle var if not solved: raise ValueError('Error: Puzzle not solvable') warped_img = transform(corners, img) subd = subdivide(warped_img) subd_soln = put_solution(subd, solved, puzzle, font_color, font_path) warped_soln = stitch_img(subd_soln, (warped_img.shape[0], warped_img.shape[1])) warped_inverse = inverse_perspective(warped_soln, img.copy(), np.array(corners)) return warped_inverse
def solve_webcam(font_color, font_path, debug=False): if font_color is None: font_color = (0, 127, 255) if font_path is None: font_path = 'assets/FreeMono.ttf' cap = cv2.VideoCapture(0) stored_soln = [] stored_puzzle = [] # Creating placeholder grid to match against until one is taken from the sudoku puzzle cells = [np.pad(np.ones((7, 7), np.uint8) * 255, (1, 1), 'constant', constant_values=(0, 0)) for _ in range(81)] grid = stitch_img(cells, (81, 81)) while True: ret, frame = cap.read() img = resize_keep_aspect(frame) try: processed = process(img) corners = get_corners(processed) warped = transform(corners, processed) vertical_lines, horizontal_lines = get_grid_lines(warped) mask = create_grid_mask(vertical_lines, horizontal_lines) # Checks to see if the mask matches a grid-like structure template = cv2.resize(grid, (warped.shape[0],) * 2, interpolation=cv2.INTER_NEAREST) res = cv2.matchTemplate(mask, template, cv2.TM_CCORR_NORMED) threshold = .55 loc = np.array(np.where(res >= threshold)) if loc.size == 0: raise ValueError('Grid template not matched') if stored_soln and stored_puzzle: warped_img = transform(corners, img) subd = subdivide(warped_img) subd_soln = put_solution(subd, stored_soln, stored_puzzle, font_color, font_path) warped_soln = stitch_img(subd_soln, (warped_img.shape[0], warped_img.shape[1])) warped_inverse = inverse_perspective(warped_soln, img, np.array(corners)) cv2.imshow('frame', warped_inverse) if cv2.waitKey(1) & 0xFF == ord('q'): break continue numbers = cv2.bitwise_and(warped, mask) digits_sorted = extract_digits(numbers) digits_border = add_border(digits_sorted) digits_subd = subdivide(numbers) digits_with_zeros = add_zeros(digits_border, digits_subd) puzzle = img_to_array(digits_with_zeros, img_dims) if np.sum(puzzle) == 0: raise ValueError('False positive') if not check_if_solvable(puzzle): raise ValueError('OCR Prediction wrong') solved = solve(puzzle.copy().tolist()) if not solved: raise ValueError('Puzzle not solvable') if verify(solved): stored_puzzle = puzzle.tolist() stored_soln = solved grid = mask warped_img = transform(corners, img) subd = subdivide(warped_img) subd_soln = put_solution(subd, solved, puzzle, font_color, font_path) warped_soln = stitch_img(subd_soln, (warped_img.shape[0], warped_img.shape[1])) warped_inverse = inverse_perspective(warped_soln, img, np.array(corners)) cv2.imshow('frame', warped_inverse) if cv2.waitKey(1) & 0xFF == ord('q'): break except Exception as e: cv2.imshow('frame', img) if cv2.waitKey(1) & 0xFF == ord('q'): break if debug: print(e) continue
def video_opener(debug=True): filename = filedialog.askopenfilename(filetypes=( ("All files", "*.*") # ,("Template files", "*.tplate") , ("HTML files", "*.html;*.htm"))) cap = cv2.VideoCapture(filename) stored_soln = [] stored_puzzle = [] # print(path) # Creating placeholder grid to match against until one is taken from the sudoku puzzle cells = [ np.pad(np.ones((7, 7), np.uint8) * 255, (1, 1), 'constant', constant_values=(0, 0)) for _ in range(81) ] grid = stitch_img(cells, (81, 81)) while True: _, img = cap.read() try: processed = process(img) corners, contour = get_corners(processed) for i in corners: i = tuple(i) cv2.circle(img, i, 4, (0, 0, 255), 2) # this is to mark circle at the corners # cv2.drawContours(img, [contour], 0, (0, 255, 0), # 2) # this is to make boundry outline the max area square found in corner function warped = transform(corners, processed) vertical_lines, horizontal_lines = get_grid_lines(warped) mask = create_grid_mask(vertical_lines, horizontal_lines) # cv2.imshow("Mask",mask) # cv2.imshow("Grid",grid) # Checks to see if the mask matches a grid-like structure template = cv2.resize(grid, (warped.shape[0], ) * 2, interpolation=cv2.INTER_NEAREST) res = cv2.matchTemplate(mask, template, cv2.TM_CCORR_NORMED) threshold = .55 loc = np.array(np.where(res >= threshold)) if loc.size == 0: raise ValueError('Grid template not matched') if stored_soln and stored_puzzle: warped_img = transform(corners, img) subd = subdivide(warped_img) subd_soln = put_solution(subd, stored_soln, stored_puzzle) warped_soln = stitch_img( subd_soln, (warped_img.shape[0], warped_img.shape[1])) warped_inverse = inverse_perspective(warped_soln, img, np.array(corners)) cv2.imshow('frame', warped_inverse) # print("Continuing to next frame from image") if cv2.waitKey(1) & 0xFF == ord('q'): break print("here doing continue") continue numbers = cv2.bitwise_and(warped, mask) cv2.imshow("numbers", numbers) digits_sorted = extract_digits(numbers) digits_border = add_border(digits_sorted) digits_subd = subdivide(numbers) digits_with_zeros = add_zeros(digits_border, digits_subd) puzzle = img_to_array(digits_with_zeros, 32) print(puzzle) if np.sum(puzzle) == 0: raise ValueError('False positive') if not check_if_solvable(puzzle): raise ValueError('OCR Prediction wrong') solved = solve(puzzle.copy().tolist()) if not solved: raise ValueError('Puzzle not solvable') if verify(solved): stored_puzzle = puzzle.tolist() stored_soln = solved # grid = mask warped_img = transform(corners, img) subd = subdivide(warped_img) subd_soln = put_solution(subd, solved, puzzle) warped_soln = stitch_img( subd_soln, (warped_img.shape[0], warped_img.shape[1])) cv2.imshow("warped sol", warped_soln) warped_inverse = inverse_perspective(warped_soln, img, np.array(corners)) cv2.imshow('frame', warped_inverse) print("hello sir ") if cv2.waitKey(1) & 0xFF == ord('q'): break except Exception as e: cv2.imshow('frame', img) if cv2.waitKey(1) & 0xFF == ord('q'): break if debug: print(e) print("Its error continue") continue cv2.destroyAllWindows()
def solve_photo(img_path, debug=0): while True: img = cv2.imread(img_path) processed_image = process(img) corners, contour = get_corners(processed_image) warped = transform(corners, processed_image) vertical_lines, horizontal_lines = get_grid_lines(warped) # print("v.s",vertical_lines.shape) mask = create_grid_mask(vertical_lines, horizontal_lines) # print("Mask shape",mask.shape) # print("warped shape",warped.shape) numbers = cv2.bitwise_and(warped, mask) cv2.imshow("number", numbers) digits_sorted_array = extract_digits( numbers) # it store the number rowise in ascending order digits_border_array = add_border( digits_sorted_array ) # it is the array of the digits sorted with increased border. digits_subd_array = subdivide( numbers) # it store the each number box (inner box) try: digits_with_zeros = add_zeros( digits_border_array, digits_subd_array ) # it will make the box black i.e 0 full to the box , that doesn't have the no. # print(digits_with_zeros.shape) except IndexError: sys.stderr.write('ERROR: Image too warped') sys.exit() try: puzzle = img_to_array( digits_with_zeros, 32 ) # as we have trained the model on the image of 32 * 32 pixel print(puzzle) except AttributeError: sys.stderr.write('ERROR: OCR predictions failed') sys.exit() solved = solve(puzzle.copy().tolist() ) # Solve function modifies original puzzle var if not solved: raise ValueError('ERROR: Puzzle not solvable') warped_img = transform(corners, img) subd = subdivide(warped_img) subd_soln = put_solution(subd, solved, puzzle) # for i in subd_soln: # this is only for debugging purpose # plt.imshow(i) # plt.show() warped_soln = stitch_img(subd_soln, (warped_img.shape[0], warped_img.shape[1])) plt.imshow(warped_soln) plt.show() warped_inverse = inverse_perspective(warped_soln, img.copy(), np.array(corners)) cv2.imshow("Solved Soduku ", warped_inverse) if (debug): cv2.imshow("O", processed_image) for i in corners: i = tuple(i) cv2.circle(img, i, 4, (0, 0, 255), 2) # this is to mark circle at the corners cv2.drawContours( img, [contour], 0, (0, 255, 0), 2 ) # this is to make boundry outline the max area square found in corner function create_grid_mask1(vertical_lines, horizontal_lines) cv2.imshow("Warped image", warped) cv2.imshow("Horizontal", horizontal_lines) cv2.imshow("Vertical", vertical_lines) cv2.imshow("Original image", img) cv2.imshow("Numbers image", numbers) if (cv2.waitKey(0) == 13): break cv2.destroyAllWindows()
def solve_webcam(): cap = cv2.VideoCapture(0) stored_soln = [] stored_puzzle = [] while True: ret, frame = cap.read() img = resize_keep_aspect(frame) try: processed = process(img) corners = get_corners(processed) warped = transform(corners, processed) mask = extract_lines(warped) # Checks to see if the mask matches a grid-like structure cells = [ np.pad(np.ones((7, 7), np.uint8) * 255, (1, 1), 'constant', constant_values=(0, 0)) for _ in range(81) ] grid = stitch_img(cells, (81, 81)) template = cv2.resize(grid, (warped.shape[0], ) * 2, interpolation=cv2.INTER_NEAREST) res = cv2.matchTemplate(mask, template, cv2.TM_CCORR_NORMED) loc = np.array(np.where(res >= .6)) if loc.size == 0: raise ValueError('Grid template not matched') if stored_soln and stored_puzzle: warped_img = transform(corners, img) subd = subdivide(warped_img) subd_soln = put_solution(subd, stored_soln, stored_puzzle) warped_soln = stitch_img( subd_soln, (warped_img.shape[0], warped_img.shape[1])) warped_inverse = inverse_perspective(warped_soln, img, np.array(corners)) cv2.imshow('frame', warped_inverse) if cv2.waitKey(1) & 0xFF == ord('q'): break continue numbers = cv2.bitwise_and(warped, mask) digits_unsorted = extract_digits(numbers) digits_subd = subdivide(numbers) digits_sorted = sort_digits(digits_subd, digits_unsorted, img_dims) digits_border = add_border(digits_sorted) puzzle = img_to_array(digits_border, img_dims) if not check_if_solvable(puzzle): raise ValueError('Puzzle not solvable') solved = solve(puzzle.copy().tolist()) if not solved: raise ValueError('Puzzle not solvable') if verify(solved): stored_puzzle = puzzle.tolist() stored_soln = solved warped_img = transform(corners, img) subd = subdivide(warped_img) subd_soln = put_solution(subd, solved, puzzle) warped_soln = stitch_img( subd_soln, (warped_img.shape[0], warped_img.shape[1])) warped_inverse = inverse_perspective(warped_soln, img, np.array(corners)) cv2.imshow('frame', warped_inverse) if cv2.waitKey(1) & 0xFF == ord('q'): break except (ValueError, cv2.error): cv2.imshow('frame', img) if cv2.waitKey(1) & 0xFF == ord('q'): break continue