예제 #1
0
def rearrange(img, old_xs, old_ys, new_xs, new_ys):

    coms, coms_x, coms_y = utils.decompose(img, 8)

    if len(coms) != len(old_xs):
        return np.full_like(img, fill_value=False)

    new_coms = []
    for com, com_x, com_y in zip(coms, coms_x, coms_y):

        closet_dist = np.inf
        closest_ii = -1
        for ii, old_x, old_y in zip(range(len(old_xs)), old_xs, old_ys):
            dist = abs(com_x - old_x) + abs(com_y - old_y)
            if dist < closet_dist:
                closet_dist = dist
                closest_ii = ii

        x = new_xs[closest_ii]
        y = new_ys[closest_ii]
        bg = np.full((300, 300), fill_value=False)
        bg[y:y + com.shape[0], x:x + com.
           shape[1]] = com  # A bug here, but I am too tired to fix it today.
        new_coms.append(bg)

    current = np.full((300, 300), fill_value=False)
    for new_com in new_coms:
        current = np.logical_or(current, new_com)

    return utils.trim_binary_image(current)
예제 #2
0
def asymmetric_jaccard_coef_pos_fixed(A, B, A_to_B_x, A_to_B_y, coord=False):

    A_sum = A.sum()
    B_sum = B.sum()

    if 0 == A_sum:
        if 0 == B_sum:
            j_coef, diff, diff_to_B_x, diff_to_B_y = 0, None, 0, 0
        else:
            j_coef, diff, diff_to_B_x, diff_to_B_y = 1, B, 0, 0
    else:
        if 0 == B_sum:
            j_coef, diff, diff_to_B_x, diff_to_B_y = 0, None, 0, 0
        else:
            A_aligned, B_aligned, aligned_to_B_x, aligned_to_B_y = utils.align(
                A, B, A_to_B_x, A_to_B_y)

            itsc = np.logical_and(A_aligned, B_aligned)
            j_coef = itsc.sum() / A_sum

            diff, diff_to_aligned_x, diff_to_aligned_y = utils.trim_binary_image(
                utils.erase_noise_point(
                    np.logical_and(B_aligned, np.logical_not(itsc)), 4),
                coord=True)  # diff = B - A

            diff_to_B_x = diff_to_aligned_x + aligned_to_B_x
            diff_to_B_y = diff_to_aligned_y + aligned_to_B_y

    if coord:
        return j_coef, diff, diff_to_B_x, diff_to_B_y
    else:
        return j_coef, diff
예제 #3
0
def soft_jaccard(A, B, asymmetric = False):
    A_tr, A_tr_to_A_x, A_tr_to_A_y = utils.trim_binary_image(A, coord = True)
    B_tr, B_tr_to_B_x, B_tr_to_B_y = utils.trim_binary_image(B, coord = True)

    sj, A_tr_to_B_tr_x, A_tr_to_B_tr_y, diff_B_tr = soft_jaccard_naive(A_tr, B_tr, asymmetric)

    if asymmetric:
        diff = utils.erase_noise_point(diff_B_tr, 4)
        diff_to_A_x = -A_tr_to_B_tr_x + A_tr_to_A_x
        diff_to_A_y = -A_tr_to_B_tr_y + A_tr_to_A_y
        diff_to_B_x = B_tr_to_B_x
        diff_to_B_y = B_tr_to_B_y

        return sj, int(diff_to_A_x), int(diff_to_A_y), int(diff_to_B_x), int(diff_to_B_y), diff
    else:
        A_to_B_x = -A_tr_to_A_x + A_tr_to_B_tr_x + B_tr_to_B_x
        A_to_B_y = -A_tr_to_A_y + A_tr_to_B_tr_y + B_tr_to_B_y
        return sj, int(A_to_B_x), int(A_to_B_y)
예제 #4
0
def add_diff(img, diff_to_ref_x, diff_to_ref_y, diff, ref):
    """

    :param img:
    :param diff_to_ref_x:
    :param diff_to_ref_y:
    :param diff:
    :param ref:
    :return:
    """

    if 0 == diff.sum():
        return img

    iimg = img.copy()
    iimg_to_img_x = 0
    iimg_to_img_y = 0
    while True:

        _, ref_to_iimg_x, ref_to_iimg_y = jaccard.jaccard_coef(ref, iimg)
        diff_to_iimg_x = diff_to_ref_x + ref_to_iimg_x
        diff_to_iimg_y = diff_to_ref_y + ref_to_iimg_y

        score, _ = asymmetric_jaccard.asymmetric_jaccard_coef_pos_fixed(
            diff, iimg, diff_to_iimg_x, diff_to_iimg_y)

        if score > 0.9:

            ref_aligned, iimg_aligned, aligned_to_iimg_x, aligned_to_iimg_y = utils.align(
                ref, iimg, ref_to_iimg_x, ref_to_iimg_y)

            iimg_aligned = utils.erase_noise_point(
                np.logical_and(iimg_aligned, np.logical_not(ref_aligned)), 4)

            iimg = iimg_aligned
            iimg_to_img_x = aligned_to_iimg_x + iimg_to_img_x
            iimg_to_img_y = aligned_to_iimg_y + iimg_to_img_y

            if iimg.sum() == 0:
                return img
        else:
            break

    diff_to_img_x = diff_to_iimg_x + iimg_to_img_x
    diff_to_img_y = diff_to_iimg_y + iimg_to_img_x

    diff_aligned, img_aligned, _, _ = utils.align(diff, img, diff_to_img_x,
                                                  diff_to_img_y)

    return utils.trim_binary_image(np.logical_or(img_aligned, diff_aligned))
예제 #5
0
def duplicate(img, copies_to_img_x, copies_to_img_y):
    current = img.copy()
    current_to_img_x = 0
    current_to_img_y = 0
    for copy_to_img_x, copy_to_img_y in zip(copies_to_img_x, copies_to_img_y):
        copy_to_current_x = copy_to_img_x - current_to_img_x
        copy_to_current_y = copy_to_img_y - current_to_img_y
        copy_aligned, current_aligned, aligned_to_current_x, aligned_to_current_y = utils.align(
            img, current, copy_to_current_x, copy_to_current_y)
        current = np.logical_or(copy_aligned, current_aligned)
        current_to_img_x = aligned_to_current_x + current_to_img_x
        current_to_img_y = aligned_to_current_y + current_to_img_y

    return utils.trim_binary_image(current)
예제 #6
0
def inv_unite(A, B, C):
    _, B_to_A_x, B_to_A_y = jaccard.jaccard_coef(B, A)
    _, C_to_A_x, C_to_A_y = jaccard.jaccard_coef(C, A)
    B_to_C_x = B_to_A_x - C_to_A_x
    B_to_C_y = B_to_A_y - C_to_A_y
    B_aligned, C_aligned, aligned_to_C_x, aligned_to_C_y = utils.align(
        B, C, B_to_C_x, B_to_C_y)
    B_new = np.logical_and(B_aligned, np.logical_not(C_aligned))
    aligned_to_A_x = aligned_to_C_x + C_to_A_x
    aligned_to_A_y = aligned_to_C_y + C_to_A_y
    A_aligned, B_aligned, _, _ = utils.align(A, B_new, -aligned_to_A_x,
                                             -aligned_to_A_y)
    C_new = np.logical_and(A_aligned, np.logical_not(B_aligned))
    C_new = utils.trim_binary_image(utils.erase_noise_point(C_new, 8))

    return C_new
예제 #7
0
def shadow_mask_unite(A, B):
    shadow_A = utils.fill_holes(A)
    shadow_B = utils.fill_holes(B)

    score, shadow_A_to_B_x, shadow_A_to_B_y = jaccard.jaccard_coef(A, B)

    shadow_A_aligned, shadow_B_aligned, _, _ = utils.align(
        shadow_A, shadow_B, shadow_A_to_B_x, shadow_A_to_B_y)
    mask = np.logical_and(shadow_A_aligned, shadow_B_aligned)

    A_aligned, B_aligned, _, _ = utils.align(A, B, shadow_A_to_B_x,
                                             shadow_A_to_B_y)
    union = np.logical_or(A_aligned, B_aligned)

    masked_union = np.logical_and(mask, union)

    return utils.trim_binary_image(masked_union)
예제 #8
0
def evaluate_duplicate(u1, u2):
    scores = []
    u1_to_u2_xs = []
    u1_to_u2_ys = []
    current = u2.copy()
    current_to_u2_x = 0
    current_to_u2_y = 0
    u1_tr = utils.trim_binary_image(u1)
    while current.sum():
        old_score_tmp, old_diff_tmp_to_u1_x, old_diff_tmp_to_u1_y, old_diff_tmp_to_current_x, old_diff_tmp_to_current_y, old_diff_tmp = \
            asymmetric_jaccard.asymmetric_jaccard_coef(u1, current)

        score_tmp, diff_tmp_to_u1_x, diff_tmp_to_u1_y, diff_tmp_to_current_x, diff_tmp_to_current_y, diff_tmp = \
            soft_jaccard.soft_jaccard(u1, current, asymmetric = True)

        if score_tmp < 0.9:
            break

        scores.append(score_tmp)
        u1_to_current_x = (-diff_tmp_to_u1_x) - (-diff_tmp_to_current_x)
        u1_to_current_y = (-diff_tmp_to_u1_y) - (-diff_tmp_to_current_y)
        u1_to_u2_x = u1_to_current_x + current_to_u2_x
        u1_to_u2_y = u1_to_current_y + current_to_u2_y
        u1_to_u2_xs.append(u1_to_u2_x)
        u1_to_u2_ys.append(u1_to_u2_y)

        current = diff_tmp
        current_to_u2_x = diff_tmp_to_current_x + current_to_u2_x
        current_to_u2_y = diff_tmp_to_current_y + current_to_u2_y

    if 1 >= len(scores):
        mat_score = 0
        u1_to_u2_locs = []
    else:
        mat_score = np.mean(scores)
        u1_to_u2_xs = ((np.array(u1_to_u2_xs) - min(u1_to_u2_xs)) /
                       u1_tr.shape[1]).tolist()
        u1_to_u2_ys = ((np.array(u1_to_u2_ys) - min(u1_to_u2_ys)) /
                       u1_tr.shape[0]).tolist()
        u1_to_u2_locs = np.array(list(zip(u1_to_u2_xs, u1_to_u2_ys)))

    stub = utils.make_stub(u1_to_u2_locs)

    return mat_score, stub
예제 #9
0
def predict_duplicate_new(prob, anlg, tran, d):
    u3 = prob.matrix[anlg.get("value")[2]]
    u3_tr = utils.trim_binary_image(u3)
    u1_to_u2_locs = d.get("stub").get("u1_to_u2_locs")

    pred_data = []
    for ii, opt in enumerate(prob.options):
        print(prob.name, anlg.get("name"), tran.get("name"), ii)
        if len(u1_to_u2_locs) <= 1:
            score = 0
        else:
            dup_score, stub = transform.evaluate_duplicate(u3, opt)
            u3_to_opt_locs = stub.get("u1_to_u2_locs")

            if len(u1_to_u2_locs) != len(u3_to_opt_locs):
                score = 0
            else:
                # it is actually a location map
                dist = np.array([[
                    np.linalg.norm(u1_to_u2_loc - u3_to_opt_loc)
                    for u3_to_opt_loc in u3_to_opt_locs
                ] for u1_to_u2_loc in u1_to_u2_locs])
                lcm_u2_com_ids, lcm_opt_com_ids, level = map.max_size_injective_mapping(
                    dist, lambda a, b: a <= b)
                if len(lcm_u2_com_ids) != len(u1_to_u2_locs):
                    score = 0
                else:
                    shape_relative_location_score = 1 - level / (
                        (u3.shape[0] / u3_tr.shape[0])**2 +
                        (u3.shape[1] / u3_tr.shape[1])**2)**0.5
                    score = (dup_score + shape_relative_location_score) / 2

        pred_data.append({
            **d, "optn": ii + 1,
            "optn_score": score,
            "mato_score": (d.get("mat_score") + score) / 2,
            "pred": opt
        })

    return pred_data
예제 #10
0
def xor_diff(img, diff_to_ref_x, diff_to_ref_y, diff, ref):
    """

    :param img:
    :param diff_to_ref_x:
    :param diff_to_ref_y:
    :param diff:
    :param ref:
    :return:
    """

    if 0 == diff.sum():
        return img

    _, img_to_ref_x, img_to_ref_y = jaccard.jaccard_coef(img, ref)
    diff_to_img_x = diff_to_ref_x - img_to_ref_x
    diff_to_img_y = diff_to_ref_y - img_to_ref_y

    diff_aligned, img_aligned, _, _ = utils.align(diff, img, diff_to_img_x,
                                                  diff_to_img_y)
    return utils.erase_noise_point(
        utils.trim_binary_image(np.logical_xor(img_aligned, diff_aligned)), 4)
예제 #11
0
def subtract_diff(img, diff_to_ref_x, diff_to_ref_y, diff, ref, coords=False):
    """

    :param img:
    :param diff_to_ref_x:
    :param diff_to_ref_y:
    :param diff:
    :param ref:
    :return:
    """

    if 0 == diff.sum():
        if coords:
            return img, 0, 0
        else:
            return img

    _, img_to_ref_x, img_to_ref_y = jaccard.jaccard_coef(img, ref)
    diff_to_img_x = diff_to_ref_x - img_to_ref_x
    diff_to_img_y = diff_to_ref_y - img_to_ref_y

    diff_aligned, img_aligned, aligned_to_img_x, aligned_to_img_y = utils.align(
        diff, img, diff_to_img_x, diff_to_img_y)

    result, result_to_aligned_x, result_to_aligned_y = utils.trim_binary_image(
        utils.erase_noise_point(
            np.logical_and(img_aligned, np.logical_not(diff_aligned)), 8),
        coord=True)

    if coords:
        diff_to_result_x = (diff_to_img_x -
                            aligned_to_img_x) - result_to_aligned_x
        diff_to_result_y = (diff_to_img_y -
                            aligned_to_img_y) - result_to_aligned_y
        return result, diff_to_result_x, diff_to_result_y
    else:
        return result
예제 #12
0
def load_problems(problem_folder = None, problem_coordinates_file = None, show_me = False):
    global raven_folder
    global raven_coordinates_file

    if problem_folder is None:
        problem_folder = raven_folder

    if problem_coordinates_file is None:
        problem_coordinates_file = raven_coordinates_file

    problem_filenames = natsorted([f for f in listdir(problem_folder) if isfile(join(problem_folder, f))])

    problem_names = [f.split('.')[0] for f in problem_filenames]

    problem_paths = [join(problem_folder, f) for f in problem_filenames]

    raw_images = [plt.imread(path) for path in problem_paths]

    with open(problem_coordinates_file) as f:
        problem_coordinates = []
        coordinates = []
        for line in f:
            rect_coords = [int(x) for x in line.split()]
            if 0 == len(rect_coords):
                problem_coordinates.append(coordinates)
                coordinates = []
            else:
                coordinates.append(rect_coords)

    with open("./problems/stuff.txt", "r") as f:
        answers = []
        for line in f:
            answers.append(int(line))

    problems = []
    for img, coords, problem_name, answer in zip(raw_images, problem_coordinates, problem_names, answers):

        print(problem_name)

        jaccard.load_jaccard_cache(problem_name)

        coms = utils.extract_components(img, coords)

        smaller_coms = [rescale(image = com, scale = (0.5, 0.5)) for com in coms]

        binary_smaller_coms = [utils.grey_to_binary(com, 0.7) for com in smaller_coms]

        binary_smaller_coms = [utils.erase_noise_point(com, 4) for com in binary_smaller_coms]

        # let's try it first. Although somebody doesn't agree on this, but I think it won't hurt the alignment.
        # because even if the alignment is not what it is in the original images, it will still give the correct
        # answer.
        # and it will definitely accelerate the computation.
        binary_smaller_coms = [utils.trim_binary_image(com) for com in binary_smaller_coms]

        binary_smaller_coms, binary_smaller_coms_ref = standardize(binary_smaller_coms)

        if 10 == len(coms):
            matrix = utils.create_object_matrix(binary_smaller_coms[: 4], (2, 2))
            matrix_ref = utils.create_object_matrix(binary_smaller_coms_ref[: 4], (2, 2))
            options = binary_smaller_coms[4:]
            problems.append(RavenProgressiveMatrix(problem_name, matrix, matrix_ref, options, answer))
        elif 17 == len(coms):
            matrix = utils.create_object_matrix(binary_smaller_coms[: 9], (3, 3))
            matrix_ref = utils.create_object_matrix(binary_smaller_coms_ref[: 9], (3, 3))
            options = binary_smaller_coms[9:]
            problems.append(RavenProgressiveMatrix(problem_name, matrix, matrix_ref, options, answer))
        else:
            raise Exception("Crap!")

        jaccard.save_jaccard_cache(problem_name)

    if show_me:
        for prob in problems:
            prob.plot_problem()

    return problems
예제 #13
0
def load_problems(problem_folder=None,
                  problem_coordinates_file=None,
                  show_me=False):
    global raven_folder
    global raven_coordinates_file

    if problem_folder is None:
        problem_folder = raven_folder

    if problem_coordinates_file is None:
        problem_coordinates_file = raven_coordinates_file

    problem_filenames = natsorted([
        f for f in listdir(problem_folder) if isfile(join(problem_folder, f))
    ])

    problem_names = [f.split('.')[0] for f in problem_filenames]

    problem_paths = [join(problem_folder, f) for f in problem_filenames]

    raw_images = [plt.imread(path) for path in problem_paths]

    with open(problem_coordinates_file) as f:
        problem_coordinates = []
        coordinates = []
        for line in f:
            rect_coords = [int(x) for x in line.split()]
            if 0 == len(rect_coords):
                problem_coordinates.append(coordinates)
                coordinates = []
            else:
                coordinates.append(rect_coords)

    with open("./problems/stuff.txt", "r") as f:
        answers = []
        for line in f:
            answers.append(int(line))

    problems = []
    for img, coords, problem_name, answer in zip(raw_images,
                                                 problem_coordinates,
                                                 problem_names, answers):

        print("load problem: " + problem_name)

        jaccard.load_jaccard_cache(problem_name)

        coms = utils.extract_components(img, coords)

        smaller_coms = [rescale(image=com, scale=(0.5, 0.5)) for com in coms]

        binary_smaller_coms = [
            utils.grey_to_binary(com, 0.7) for com in smaller_coms
        ]

        binary_smaller_coms = [
            utils.erase_noise_point(com, 4) for com in binary_smaller_coms
        ]

        binary_smaller_coms = [
            utils.trim_binary_image(com) for com in binary_smaller_coms
        ]

        binary_smaller_coms, binary_smaller_coms_ref = standardize(
            binary_smaller_coms)

        if 10 == len(coms):
            matrix = utils.create_object_matrix(binary_smaller_coms[:4],
                                                (2, 2))
            matrix_ref = utils.create_object_matrix(
                binary_smaller_coms_ref[:4], (2, 2))
            options = binary_smaller_coms[4:]
            problems.append(
                RavenProgressiveMatrix(problem_name, matrix, matrix_ref,
                                       options, answer))
        elif 17 == len(coms):
            matrix = utils.create_object_matrix(binary_smaller_coms[:9],
                                                (3, 3))
            matrix_ref = utils.create_object_matrix(
                binary_smaller_coms_ref[:9], (3, 3))
            options = binary_smaller_coms[9:]
            problems.append(
                RavenProgressiveMatrix(problem_name, matrix, matrix_ref,
                                       options, answer))
        else:
            raise Exception("Crap!")

        jaccard.save_jaccard_cache(problem_name)

    if show_me:
        for prob in problems:
            prob.plot_problem()

    return problems