Exemple #1
0
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}')
Exemple #2
0
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
Exemple #3
0
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()
Exemple #6
0
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