Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

Template matching, false negative on close image's

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%).

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

Template matching, false negative on close image's

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