Esempio n. 1
0
def extract_efd_features(image, n=10):
    contours = get_contours(image)
    if len(contours) == 0:
        return np.zeros((4 * n))[3:]
    efd = elliptic_fourier_descriptors(contours[0], order=n, normalize=True)

    return efd.flatten()[3:]
Esempio n. 2
0
def extract_efd_features(image, n=10):
    contours = get_contours(image)
    if len(contours) == 0:
        return np.zeros((4*n))[3:]
    efd = elliptic_fourier_descriptors(contours[0], order=n, normalize=True)

    return efd.flatten()[3:]
Esempio n. 3
0
def iter_blob_extremes(image, n=5):
    original_shape = image.shape[::-1]
    if max(original_shape) < 2000:
        size = (500, 500)
        y_scale = original_shape[0] / 500
        x_scale = original_shape[1] / 500
    else:
        size = (1000, 1000)
        y_scale = original_shape[0] / 1000
        x_scale = original_shape[1] / 1000

    img = resize(image, size)
    bimg = gaussian_filter(img, sigma=1.0)
    bimg = threshold_adaptive(bimg, 20, offset=2 / 255)
    bimg = -bimg
    bimg = ndi.binary_fill_holes(bimg)
    label_image = label(bimg, background=False)
    label_image += 1

    regions = regionprops(label_image)
    regions.sort(key=attrgetter('area'), reverse=True)
    iter_n = 0

    for region in regions:
        try:
            iter_n += 1
            if iter_n > n:
                break

            # Skip small images
            if region.area < int(np.prod(size) * 0.05):
                continue
            coords = get_contours(
                add_border(label_image == region.label,
                           size=label_image.shape,
                           border_size=1,
                           background_value=False))[0]
            coords = np.fliplr(coords)

            top_left = sorted(coords,
                              key=lambda x: np.linalg.norm(np.array(x)))[0]
            top_right = sorted(coords,
                               key=lambda x: np.linalg.norm(
                                   np.array(x) - [img.shape[1], 0]))[0]
            bottom_left = sorted(coords,
                                 key=lambda x: np.linalg.norm(
                                     np.array(x) - [0, img.shape[0]]))[0]
            bottom_right = sorted(
                coords,
                key=lambda x: np.linalg.norm(
                    np.array(x) - [img.shape[1], img.shape[0]]))[0]
            scaled_extremes = [(int(x[0] * y_scale), int(x[1] * x_scale))
                               for x in (top_left, top_right, bottom_left,
                                         bottom_right)]

            yield scaled_extremes
        except Exception:
            pass
    raise SudokuExtractError("No suitable blob could be found.")
Esempio n. 4
0
def iter_blob_extremes(image, n=5):
    original_shape = image.shape[::-1]
    if max(original_shape) < 2000:
        size = (500, 500)
        y_scale = original_shape[0] / 500
        x_scale = original_shape[1] / 500
    else:
        size = (1000, 1000)
        y_scale = original_shape[0] / 1000
        x_scale = original_shape[1] / 1000

    img = resize(image, size)
    bimg = gaussian_filter(img, sigma=1.0)
    bimg = threshold_adaptive(bimg, 20, offset=2/255)
    bimg = -bimg
    bimg = ndi.binary_fill_holes(bimg)
    label_image = label(bimg, background=False)
    label_image += 1

    regions = regionprops(label_image)
    regions.sort(key=attrgetter('area'), reverse=True)
    iter_n = 0

    for region in regions:
        try:
            iter_n += 1
            if iter_n > n:
                break

            # Skip small images
            if region.area < int(np.prod(size) * 0.05):
                continue
            coords = get_contours(add_border(label_image == region.label,
                                             size=label_image.shape,
                                             border_size=1,
                                             background_value=False))[0]
            coords = np.fliplr(coords)

            top_left = sorted(coords, key=lambda x: np.linalg.norm(np.array(x)))[0]
            top_right = sorted(coords, key=lambda x: np.linalg.norm(np.array(x) - [img.shape[1], 0]))[0]
            bottom_left = sorted(coords, key=lambda x: np.linalg.norm(np.array(x) - [0, img.shape[0]]))[0]
            bottom_right = sorted(coords, key=lambda x: np.linalg.norm(np.array(x) - [img.shape[1], img.shape[0]]))[0]
            scaled_extremes = [(int(x[0] * y_scale), int(x[1]*x_scale)) for x in (top_left, top_right, bottom_left, bottom_right)]

            yield scaled_extremes
        except Exception:
            pass
    raise SudokuExtractError("No suitable blob could be found.")
Esempio n. 5
0
def iter_blob_contours(image, n=5):
    original_shape = image.shape[::-1]
    if max(original_shape) < 2000:
        size = (500, 500)
        y_scale = original_shape[0] / 500
        x_scale = original_shape[1] / 500
    else:
        size = (1000, 1000)
        y_scale = original_shape[0] / 1000
        x_scale = original_shape[1] / 1000

    img = resize(image, size)
    bimg = gaussian_filter(img, sigma=1.0)
    bimg = threshold_adaptive(bimg, 20, offset=2 / 255)
    bimg = (~binary_erosion(bimg))
    label_image = label(bimg, background=False)
    label_image += 1

    regions = regionprops(label_image)
    regions.sort(key=attrgetter('area'), reverse=True)
    iter_n = 0

    for region in regions:
        iter_n += 1
        if iter_n > n:
            break
        try:
            coords = get_contours(
                add_border(label_image == region.label,
                           size=label_image.shape,
                           border_size=1,
                           background_value=False))[0]
            if np.linalg.norm(coords[0, :] - coords[-1, :]) > 1e-10:
                raise SudokuExtractError("Not a closed contour.")
            else:
                coords = np.fliplr(coords[:-1, :])

            top_left = sorted(coords,
                              key=lambda x: np.linalg.norm(np.array(x)))[0]
            top_right = sorted(coords,
                               key=lambda x: np.linalg.norm(
                                   np.array(x) - [img.shape[1], 0]))[0]
            bottom_left = sorted(coords,
                                 key=lambda x: np.linalg.norm(
                                     np.array(x) - [0, img.shape[0]]))[0]
            bottom_right = sorted(
                coords,
                key=lambda x: np.linalg.norm(
                    np.array(x) - [img.shape[1], img.shape[0]]))[0]

            tl_i = np.argmax((coords == top_left).sum(axis=1))
            tr_i = np.argmax((coords == top_right).sum(axis=1))
            bl_i = np.argmax((coords == bottom_left).sum(axis=1))
            br_i = np.argmax((coords == bottom_right).sum(axis=1))

            coords[:, 0] *= y_scale
            coords[:, 1] *= x_scale

            if tl_i > bl_i:
                left_edge = coords[bl_i:tl_i + 1, :]
            else:
                coords_end_of_array = coords[bl_i:, :]
                coords_start_of_array = coords[:tl_i + 1]
                left_edge = np.concatenate(
                    [coords_end_of_array, coords_start_of_array], axis=0)

            if tr_i > tl_i:
                top_edge = coords[tl_i:tr_i + 1, :]
            else:
                coords_end_of_array = coords[tl_i:, :]
                coords_start_of_array = coords[:tr_i + 1]
                top_edge = np.concatenate(
                    [coords_end_of_array, coords_start_of_array], axis=0)

            if br_i > tr_i:
                right_edge = coords[tr_i:br_i + 1, :]
            else:
                coords_end_of_array = coords[tr_i:, :]
                coords_start_of_array = coords[:br_i + 1]
                right_edge = np.concatenate(
                    [coords_end_of_array, coords_start_of_array], axis=0)

            if bl_i > br_i:
                bottom_edge = coords[br_i:bl_i + 1, :]
            else:
                coords_end_of_array = coords[br_i:, :]
                coords_start_of_array = coords[:bl_i + 1]
                bottom_edge = np.concatenate(
                    [coords_end_of_array, coords_start_of_array], axis=0)

            yield left_edge, top_edge, right_edge, bottom_edge
        except Exception:
            pass
    raise SudokuExtractError("No suitable blob could be found.")
Esempio n. 6
0
def iter_blob_contours(image, n=5):
    original_shape = image.shape[::-1]
    if max(original_shape) < 2000:
        size = (500, 500)
        y_scale = original_shape[0] / 500
        x_scale = original_shape[1] / 500
    else:
        size = (1000, 1000)
        y_scale = original_shape[0] / 1000
        x_scale = original_shape[1] / 1000

    img = resize(image, size)
    bimg = gaussian_filter(img, sigma=1.0)
    bimg = threshold_adaptive(bimg, 20, offset=2/255)
    bimg = (-binary_erosion(bimg))
    label_image = label(bimg, background=False)
    label_image += 1

    regions = regionprops(label_image)
    regions.sort(key=attrgetter('area'), reverse=True)
    iter_n = 0

    for region in regions:
        iter_n += 1
        if iter_n > n:
            break
        try:
            coords = get_contours(add_border(label_image == region.label,
                                             size=label_image.shape,
                                             border_size=1,
                                             background_value=False))[0]
            if np.linalg.norm(coords[0, :] - coords[-1, :]) > 1e-10:
                raise SudokuExtractError("Not a closed contour.")
            else:
                coords = np.fliplr(coords[:-1, :])

            top_left = sorted(coords, key=lambda x: np.linalg.norm(np.array(x)))[0]
            top_right = sorted(coords, key=lambda x: np.linalg.norm(np.array(x) - [img.shape[1], 0]))[0]
            bottom_left = sorted(coords, key=lambda x: np.linalg.norm(np.array(x) - [0, img.shape[0]]))[0]
            bottom_right = sorted(coords, key=lambda x: np.linalg.norm(np.array(x) - [img.shape[1], img.shape[0]]))[0]

            tl_i = np.argmax((coords == top_left).sum(axis=1))
            tr_i = np.argmax((coords == top_right).sum(axis=1))
            bl_i = np.argmax((coords == bottom_left).sum(axis=1))
            br_i = np.argmax((coords == bottom_right).sum(axis=1))

            coords[:, 0] *= y_scale
            coords[:, 1] *= x_scale

            if tl_i > bl_i:
                left_edge = coords[bl_i:tl_i + 1, :]
            else:
                coords_end_of_array = coords[bl_i:, :]
                coords_start_of_array = coords[:tl_i + 1]
                left_edge = np.concatenate([coords_end_of_array, coords_start_of_array], axis=0)

            if tr_i > tl_i:
                top_edge = coords[tl_i:tr_i + 1, :]
            else:
                coords_end_of_array = coords[tl_i:, :]
                coords_start_of_array = coords[:tr_i + 1]
                top_edge = np.concatenate([coords_end_of_array, coords_start_of_array], axis=0)

            if br_i > tr_i:
                right_edge = coords[tr_i:br_i + 1, :]
            else:
                coords_end_of_array = coords[tr_i:, :]
                coords_start_of_array = coords[:br_i + 1]
                right_edge = np.concatenate([coords_end_of_array, coords_start_of_array], axis=0)

            if bl_i > br_i:
                bottom_edge = coords[br_i:bl_i + 1, :]
            else:
                coords_end_of_array = coords[br_i:, :]
                coords_start_of_array = coords[:bl_i + 1]
                bottom_edge = np.concatenate([coords_end_of_array, coords_start_of_array], axis=0)

            yield left_edge, top_edge, right_edge, bottom_edge
        except Exception:
            pass
    raise SudokuExtractError("No suitable blob could be found.")