Exemplo n.º 1
0
def find_crosses(image_data, cross_size = 7, nms_threshold_high = 30, nms_threshold_low = 10, nms_threshold_axis_deletion = 2):
    """
    :param image_data:
    :return: (x axis cross, y axis cross), [list of detected plot points]
    """

    height = image_data.shape[0]
    width = image_data.shape[1]
    nms_mask_visited = numpy.zeros((height, width), dtype=bool)

    if utils_general.is_debug:
        find_crosses.counter += 1
        image_dump = Image.new("L", (width, height))

    x_axis_cross, y_axis_cross = find_axes(image_data, width, height)
    if x_axis_cross == -1 or y_axis_cross == -1:
        raise ValueError("Axis not found")

    if utils_general.is_debug:
        print("Detected axes cross: ", x_axis_cross, y_axis_cross)
        map_to_image_and_save(image_dump, image_data, "debug/", str(find_crosses.counter), "_before_cross_filter.png", mode = "user-wise")

    #Convolving image data with kernel detecting crosses
    cross_center = cross_size//2
    negative_normalizer = 2*cross_size-1
    positive_normalizer = cross_size*cross_size - (4*cross_size - 8) - negative_normalizer
    cross_kernel = numpy.array([[-1.0/negative_normalizer if xxx == cross_center or yyy == cross_center else
                                 (0 if abs(xxx - cross_center) == 1 or abs(yyy - cross_center) == 1 else 1.0/positive_normalizer)
                                 for xxx in range(cross_size)]
                                for yyy in range(cross_size)])
    data_cross = convolve2d(image_data, cross_kernel, mode='same')

    #Fixup in case if there're holes in axes' lines
    for i in range(-6, 7):
        if 0 <= y_axis_cross + i < height:
            if 0 <= x_axis_cross - 1:
                data_cross[y_axis_cross + i, x_axis_cross - 1] = 255
            data_cross[y_axis_cross + i, x_axis_cross] = 255
            if x_axis_cross + 1 < width:
                data_cross[y_axis_cross + i, x_axis_cross + 1] = 255
        if 0 <= x_axis_cross + i < width:
            if 0 <= y_axis_cross - 1:
                data_cross[y_axis_cross - 1, x_axis_cross + i] = 255
            data_cross[y_axis_cross, x_axis_cross + i] = 255
            if y_axis_cross + 1 < height:
                data_cross[y_axis_cross + 1, x_axis_cross + i] = 255
    data_cross = convolve2d(data_cross, get_gaussian_kernel(3, 2, True))

    if utils_general.is_debug:
        map_to_image_and_save(image_dump, data_cross, "debug/", str(find_crosses.counter), "_before_nms.png", mode = "user-wise")

    x_low, x_high, y_low, y_high = find_plot_box([(x_axis_cross, y_axis_cross)], data_cross, nms_mask_visited, nms_threshold_axis_deletion, width, height)
    box = ((y_low, y_high), (x_low, x_high))

    if utils_general.is_debug:
        print("Graph box: ", box)

    data_cross = apply_recursive_nms(box, data_cross, nms_mask_visited, nms_threshold_low, nms_threshold_high)

    if utils_general.is_debug:
        map_to_image_and_save(image_dump, data_cross, "debug/", str(find_crosses.counter), "_after_nms.png", mode = "user-wise")

    #Lising points passed through non-maximal suppression
    crosses_result_pt_list = []
    crosses_result_val_list = []
    for y in range(box[0][0], box[0][1]):
        for x in range(box[1][0], box[1][1]):
            if data_cross[y, x] > 0:
                crosses_result_pt_list.append((x - cross_center/2, y - cross_center/2, data_cross[y, x]))
                crosses_result_val_list.append(data_cross[y, x])

    if not crosses_result_val_list:
        raise ValueError("Axis is found, but not plot points detected")

    #Filtering weak fitting points
    threshold_cross_value = median(crosses_result_val_list)/2
    crosses_result_pt_list = [(item[0], item[1]) for item in crosses_result_pt_list if item[2] > threshold_cross_value]

    return x_axis_cross, y_axis_cross, crosses_result_pt_list
Exemplo n.º 2
0
        height = image.size[1]
        pix = image.load()

        if utils_general.is_debug:
            image.save(join(debug_dir, filename + "_image+median.png"), "PNG")

        # Creates image for gradient then processing it
        image_gradient, gradient_abs = compute_gradient(pix, width, height, gradient_threshold)
        if utils_general.is_debug:
            image_gradient.save(join(debug_dir, filename + "_gradient.png"), "PNG")

        external_borders_map = np.zeros((width, height)) #[[0]*height for x in range(width)]
        external_borders_map = mark_external_borders(external_borders_map, gradient_abs, 0, height, 0, width, 25, 1, False)

        if utils_general.is_debug:
            map_to_image_and_save(image_gradient, external_borders_map, debug_dir, filename, "_processed_gradient.png", mode="data-wise")

        # Performs quick window search. Thus we obtain approximate location of document.

        processed_gradient_ii = compute_integral_image_buffer(external_borders_map, height, width, mode="buffer")
        x_pt, y_pt, x_window_size, y_window_size = integral_image_window_detect(processed_gradient_ii, width, height)

        if utils_general.is_debug:
            if x_window_size != y_window_size:
                print("WARNING: quick window search unsuccessful, performing search on whole image")
            draw.rectangle((x_pt, y_pt, x_pt + x_window_size, y_pt + y_window_size), fill=None)
            image.save(join(debug_dir, filename + "_window_detected.png"), "PNG")

        external_borders_map = mark_external_borders(external_borders_map, gradient_abs, y_pt, y_pt + y_window_size, x_pt, x_pt + x_window_size, 1000, 0, True)

        if utils_general.is_debug: