Template matching, false negative on close image's

asked 2020-02-05 08:34:06 -0500

EvilMegaDroid gravatar image

updated 2020-02-05 08:41:45 -0500

I'm having this issue that for some reason, opencv template matching doesn't match the template into an image that is closely the same as the template (around 90%).

Reason I'm search for more than 1 is because the images below are cut from the original (which has many matches).

Here's my code

def remove_match(args):
    original, match, _ = args

    # Load original image, convert to grayscale
    original_image = cv2.imread(original)

    final = original_image.copy()

    found = []

    # Load template, convert to grayscale, perform canny edge detection
    template = cv2.imread(match)
    template = cv2.cvtColor(template, cv2.COLOR_BGR2GRAY)
    template = cv2.Canny(template, 50, 200)

    (tH, tW) = template.shape[:2]

    # Dynamically rescale image for better template matching
    for scale in np.linspace(0.5, 1.0, 10)[::-1]:
        gray = cv2.cvtColor(final, cv2.COLOR_BGR2GRAY)

        # Resize image to scale and keep track of ratio
        resized = maintain_aspect_ratio_resize(gray, width=int(gray.shape[1] * scale))
        r = gray.shape[1] / float(resized.shape[1])

        # Stop if template image size is larger than resized image
        if resized.shape[0] < tH or resized.shape[1] < tW:
            break

        # Detect edges in resized image and apply template matching
        canny = cv2.Canny(resized, 50, 200)
        detected = cv2.matchTemplate(canny, template, cv2.TM_CCOEFF_NORMED)
        (_, max_val, _, max_loc) = cv2.minMaxLoc(detected)

        threshold = 0.5
        loc = np.where(detected >= threshold)
        for pt in zip(*loc[::-1]):
            found.append([0, pt, r])

            # Erase unwanted ROI (Fill ROI with white)
            (start_x, start_y) = (int(max_loc[0] * r), int(max_loc[1] * r))
            (end_x, end_y) = (int((max_loc[0] + tW) * r), int((max_loc[1] + tH) * r))
            cv2.rectangle(
                final, (start_x, start_y), (end_x, end_y), (255, 255, 255), -1
            )

    cv2.imwrite(original.replace("source", "output"), final)

Template image description

Image's:
image description
image description
image description
image description

edit retag flag offensive close merge delete

Comments

LBerger gravatar imageLBerger ( 2020-02-05 09:17:01 -0500 )edit

@LBerger Isn't it possible to match by edges? I mean the script wouldn't work if the color changes. And colormatchtemplate doesn't seem to have a doc for python :(

EvilMegaDroid gravatar imageEvilMegaDroid ( 2020-02-05 09:36:00 -0500 )edit

there is a python binding in doc

LBerger gravatar imageLBerger ( 2020-02-05 09:48:26 -0500 )edit

Yes my bad

EvilMegaDroid gravatar imageEvilMegaDroid ( 2020-02-05 09:50:07 -0500 )edit