示例#1
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
示例#2
0
def predict_xor_diff(prob, anlg, tran, d):
    best_diff_to_u1_x = d.get("diff_to_u1_x")
    best_diff_to_u1_y = d.get("diff_to_u1_y")
    best_diff = d.get("diff")
    u3 = prob.matrix[anlg.get("value")[2]]
    u1_ref = prob.matrix_ref[anlg.get("value")[0]]

    prediction = transform.xor_diff(u3, best_diff_to_u1_x, best_diff_to_u1_y,
                                    best_diff, u1_ref)

    pred_data = []
    for ii, opt in enumerate(prob.options):
        print(prob.name, anlg.get("name"), tran.get("name"), ii)

        pred_score, _, _ = jaccard.jaccard_coef(prediction, opt)
        u3_score, u3_to_opt_x, u3_to_opt_y = jaccard.jaccard_coef(u3, opt)
        u3_score = 1 - u3_score
        u1_aligned, u2_aligned, aligned_to_u2_x, aligned_to_u2_y = utils.align(
            u3, opt, u3_to_opt_x, u3_to_opt_y)
        diff = utils.erase_noise_point(np.logical_xor(u1_aligned, u2_aligned),
                                       4)
        diff_score, _, _ = jaccard.jaccard_coef(diff, best_diff)
        score = (diff_score + u3_score + pred_score) / 3
        pred_data.append({
            **d, "optn": ii + 1,
            "optn_score": score,
            "mato_score": (d.get("mat_score") + score) / 2,
            "pred": prediction
        })

    return pred_data
示例#3
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))
示例#4
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
示例#5
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)
示例#6
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)
示例#7
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
示例#8
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
示例#9
0
def xor(imgA, imgB):
    if imgA.shape != imgB.shape:
        raise Exception("Crap!")

    return utils.erase_noise_point(np.logical_xor(imgA, imgB), 4)
示例#10
0
def backward_subtract(imgA, imgB):
    if imgA.shape != imgB.shape:
        raise Exception("Crap!")

    return utils.erase_noise_point(
        np.logical_and(imgB, np.logical_not(np.logical_and(imgB, imgA))), 4)
示例#11
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
示例#12
0
def run_prob_anlg_tran_2x2(prob, anlg, tran):
    u1 = prob.matrix[anlg.get("value")[0]]
    u2 = prob.matrix[anlg.get("value")[1]]

    diff_to_u1_x = None
    diff_to_u1_y = None
    diff_to_u2_x = None
    diff_to_u2_y = None
    diff = None
    copies_to_u1_x = None
    copies_to_u1_y = None
    u1_coms_x = None
    u1_coms_y = None
    u2_coms_x = None
    u2_coms_y = None

    if "add_diff" == tran.get("name"):
        score, diff_to_u1_x, diff_to_u1_y, diff_to_u2_x, diff_to_u2_y, diff = \
            asymmetric_jaccard.asymmetric_jaccard_coef(u1, u2)
    elif "subtract_diff" == tran.get("name"):
        score, diff_to_u2_x, diff_to_u2_y, diff_to_u1_x, diff_to_u1_y, diff = \
            asymmetric_jaccard.asymmetric_jaccard_coef(u2, u1)
    elif "xor_diff" == tran.get("name"):
        score, u1_to_u2_x, u1_to_u2_y = jaccard.jaccard_coef(u1, u2)
        score = 1 - score
        u1_aligned, u2_aligned, aligned_to_u2_x, aligned_to_u2_y = utils.align(
            u1, u2, u1_to_u2_x, u1_to_u2_y)
        diff = utils.erase_noise_point(np.logical_xor(u1_aligned, u2_aligned),
                                       4)
        diff_to_u2_x = int(aligned_to_u2_x)
        diff_to_u2_y = int(aligned_to_u2_y)
        diff_to_u1_x = int(diff_to_u2_x - u1_to_u2_x)
        diff_to_u1_y = int(diff_to_u2_y - u1_to_u2_y)
    elif "upscale_to" == tran.get("name"):
        u1_upscaled = transform.upscale_to(u1, u2)
        score, _, _ = jaccard.jaccard_coef(u2, u1_upscaled)
    elif "duplicate" == tran.get("name"):
        scores = []
        u1_to_u2_xs = []
        u1_to_u2_ys = []
        current = u2.copy()
        current_to_u2_x = 0
        current_to_u2_y = 0
        while current.sum():
            score_tmp, diff_tmp_to_u1_x, diff_tmp_to_u1_y, diff_tmp_to_current_x, diff_tmp_to_current_y, _ = \
                asymmetric_jaccard.asymmetric_jaccard_coef(u1, current)

            if score_tmp < 0.6:
                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)
            u1_aligned, current_aligned, aligned_to_current_x, aligned_to_current_y = utils.align(
                u1, current, u1_to_current_x, u1_to_current_y)
            current = utils.erase_noise_point(
                np.logical_and(current_aligned, np.logical_not(u1_aligned)), 8)
            current_to_u2_x = aligned_to_current_x + current_to_u2_x
            current_to_u2_y = aligned_to_current_y + current_to_u2_y

        if 1 >= len(scores):
            score = 0
            copies_to_u1_x = [0]
            copies_to_u1_y = [0]
        else:
            score = min(scores)
            copies_to_u1_x = (np.array(u1_to_u2_xs[1:]) -
                              u1_to_u2_xs[0]).tolist()
            copies_to_u1_y = (np.array(u1_to_u2_ys[1:]) -
                              u1_to_u2_ys[0]).tolist()
    elif "rearrange" == tran.get("name"):
        score, u1_coms_x, u1_coms_y, u2_coms_x, u2_coms_y = transform.evaluate_rearrange(
            u1, u2)
    else:
        u1_t = transform.apply_unary_transformation(u1, tran)
        score, _, _ = jaccard.jaccard_coef(u1_t, u2)

    if "mirror" == tran.get("name") or "mirror_rot_180" == tran.get("name"):
        # if u1 or u2 is already symmetric, then we shouldn't use mirror tran.
        u1_mirror_score, _, _ = jaccard.jaccard_coef(u1_t, u1)
        u2_mirror = transform.apply_unary_transformation(u2, tran)
        u2_mirror_score, _, _ = jaccard.jaccard_coef(u2_mirror, u2)
        if max(u1_mirror_score, u2_mirror_score) > 0.9:
            score = 0

    prob_anlg_tran_d = assemble_prob_anlg_tran_d(prob,
                                                 anlg,
                                                 tran,
                                                 score,
                                                 diff_to_u1_x=diff_to_u1_x,
                                                 diff_to_u1_y=diff_to_u1_y,
                                                 diff_to_u2_x=diff_to_u2_x,
                                                 diff_to_u2_y=diff_to_u2_y,
                                                 diff=diff,
                                                 copies_to_u1_x=copies_to_u1_x,
                                                 copies_to_u1_y=copies_to_u1_y,
                                                 u1_coms_x=u1_coms_x,
                                                 u1_coms_y=u1_coms_y,
                                                 u2_coms_x=u2_coms_x,
                                                 u2_coms_y=u2_coms_y)

    return prob_anlg_tran_d
示例#13
0
def asymmetric_jaccard_coef_naive(A, B):
    """
    max_diff is trimmed to its minimal box. (max_x, max_y) is the relative position of max_diff to A
    :param A:
    :param B:
    :return: a_j_coef, diff_to_A_x, diff_to_A_y, diff_to_B_x, diff_to_B_y, diff
    """

    A_shape_y, A_shape_x = A.shape
    B_shape_y, B_shape_x = B.shape

    A_sum = A.sum()

    if A_shape_x < B_shape_x and A_shape_y < B_shape_y:
        A_to_B_coords, a_j_coefs = asymmetric_jaccard_coef_naive_embed(
            A, B, A_sum)
    elif A_shape_x >= B_shape_x and A_shape_y >= B_shape_y:
        B_to_A_coords, a_j_coefs = asymmetric_jaccard_coef_naive_embed(
            B, A, A_sum)
        A_to_B_coords = -B_to_A_coords
    elif A_shape_x < B_shape_x and A_shape_y >= B_shape_y:
        A_to_B_coords, a_j_coefs = asymmetric_jaccard_coef_naive_cross(
            A, B, A_sum)
    elif A_shape_x >= B_shape_x and A_shape_y < B_shape_y:
        B_to_A_coords, a_j_coefs = asymmetric_jaccard_coef_naive_cross(
            B, A, A_sum)
        A_to_B_coords = -B_to_A_coords
    else:
        raise Exception("Impossible Exception!")

    a_j_coef = np.max(a_j_coefs)
    coef_argmax = np.where(a_j_coefs == a_j_coef)[0]

    if 1 == len(coef_argmax):
        ii = coef_argmax[0]
        A_to_B_x, A_to_B_y = A_to_B_coords[ii]
    else:

        A_center_x = (A_shape_x - 1) / 2
        A_center_y = (A_shape_y - 1) / 2
        B_center_x = (B_shape_x - 1) / 2
        B_center_y = (B_shape_y - 1) / 2

        closest_center_ii = -1
        smallest_center_dist = np.inf
        for ii in coef_argmax:
            x, y = A_to_B_coords[ii]
            center_dist = abs(x + A_center_x -
                              B_center_x) + abs(y + A_center_y - B_center_y)
            if center_dist < smallest_center_dist:
                closest_center_ii = ii
                smallest_center_dist = center_dist

        A_to_B_x, A_to_B_y = A_to_B_coords[closest_center_ii]

    A_aligned, B_aligned, aligned_to_B_x, aligned_to_B_y = utils.align(
        A, B, A_to_B_x, A_to_B_y)

    diff = np.logical_and(B_aligned, np.logical_not(A_aligned))

    if diff.any():
        diff_y, diff_x = np.where(diff)
        diff_x_min = diff_x.min()
        diff_x_max = diff_x.max() + 1
        diff_y_min = diff_y.min()
        diff_y_max = diff_y.max() + 1
        diff = diff[diff_y_min:diff_y_max, diff_x_min:diff_x_max]
        diff_to_B_x = diff_x_min + aligned_to_B_x
        diff_to_B_y = diff_y_min + aligned_to_B_y
        diff_to_A_x = diff_to_B_x - A_to_B_x
        diff_to_A_y = diff_to_B_y - A_to_B_y
    else:  # diff is all white, i.e. B is completely covered by A
        diff_to_A_x = 0
        diff_to_A_y = 0
        diff_to_B_x = A_to_B_x
        diff_to_B_y = A_to_B_y
        diff = np.full_like(A, fill_value=False)

    return a_j_coef, diff_to_A_x, diff_to_A_y, diff_to_B_x, diff_to_B_y, utils.erase_noise_point(
        diff, 4)