Template matching with multiple objects in OpenCV Python

后端 未结 1 981
时光说笑
时光说笑 2021-01-14 13:22

I\'m trying to find multiple templates in an image using opencv python, according to this link.

But the problem is that multiple points returned for a single object

1条回答
  •  被撕碎了的回忆
    2021-01-14 14:24

    One way to find multiple matches is to write over the found matches and run the match again. Edit: A better way to find multiple matches is to write over the results. In the first example we fill the matched part of results with zeroes (use ones for SQDIFF or CCORR_NORMED) , and then look for the next match in a loop.

    import cv2
    import numpy as np
    import time
    
    image = cv2.imread('smiley.png', cv2.IMREAD_COLOR )
    template = cv2.imread('template.png', cv2.IMREAD_COLOR)
    
    h, w = template.shape[:2]
    
    method = cv2.TM_CCOEFF_NORMED
    
    threshold = 0.90
    
    start_time = time.time()
    
    res = cv2.matchTemplate(image, template, method)
    
    # fake out max_val for first run through loop
    max_val = 1
    while max_val > threshold:
        min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res)
    
        if max_val > threshold:
            res[max_loc[1]-h//2:max_loc[1]+h//2+1, max_loc[0]-w//2:max_loc[0]+w//2+1] = 0   
            image = cv2.rectangle(image,(max_loc[0],max_loc[1]), (max_loc[0]+w+1, max_loc[1]+h+1), (0,255,0) )
    
    cv2.imwrite('output.png', image)
    

    input image:

    use the eyes as template images (since there is more than one eye!)

    output:

    And here is the original way I did it by writing over the image. This way is way is much slower because we do n+1 matchTemplate operations for n matches. By one measurement, this technique is 1000 times slower.

    import cv2
    import numpy as np
    
    image = cv2.imread('smiley.png', cv2.IMREAD_COLOR )
    template = cv2.imread('template.png', cv2.IMREAD_COLOR)
    
    h, w = template.shape[:2]
    
    method = cv2.TM_CCOEFF_NORMED
    
    threshold = 0.95
    
    # fake out max_val for first run through loop
    max_val = 1
    while max_val > threshold:
        res = cv2.matchTemplate(image, template, method)
        min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res)
    
        # using top ranked score, fill in that area with green
        image[max_loc[1]:max_loc[1]+h+1:, max_loc[0]:max_loc[0]+w+1, 0] = 0    # blue channel
        image[max_loc[1]:max_loc[1]+h+1:, max_loc[0]:max_loc[0]+w+1, 1] = 255  # green channel
        image[max_loc[1]:max_loc[1]+h+1:, max_loc[0]:max_loc[0]+w+1, 2] = 0    # red channel
    
    
    cv2.imwrite('output.png', image)
    

    output image:

    0 讨论(0)
提交回复
热议问题