Сопоставление шаблонов в многомасштабных нормированных методах не работает - PullRequest
0 голосов
/ 29 марта 2020

Я пытаюсь выполнить многомасштабное сопоставление с шаблоном для некоторой сегментации сигнатуры, и я застрял, потому что хочу получить оценку «точности» лучшего соответствия, которое он возвращает.

Результаты возвращаются правильно, когда я использую cv2.TM_CCOEFF и cv2.TM_CCORR, но как только я пытаюсь cv2.TM_CCOEFF_NORMED и cv2.TM_CCORR_NORMED, они больше не соответствуют должным образом. Максимальное значение cv2.TM_CCOEFF возвращает очень большое значение (сумму всех точечных продуктов?), Которое я не знаю, как определить количественно в рейтинге производительности.

Я прошел через несколько онлайн учебные пособия

https://www.pyimagesearch.com/2015/01/26/multi-scale-template-matching-using-python-opencv/

https://docs.opencv.org/2.4/doc/tutorials/imgproc/histograms/template_matching/template_matching.html

о сопоставлении с шаблоном, но я не могу понять, почему это не работает Я догадываюсь, что шкала влияет на результаты, но я не уверен.

Может кто-нибудь сказать мне, как заставить методы NORMED работать для нескольких шкал или как количественно оценить maxValue в балл?

Мой код ниже:

import os
import fitz
import numpy as np
import cv2
import matplotlib.pyplot as plt
from skimage import measure, morphology
from skimage.color import label2rgb
from skimage.measure import regionprops
from PIL import Image

working_dir="/testdocs2sift"
files=os.listdir(f".{working_dir}")
imgs=[]


#reading image
img1 = cv2.imread(f'.{working_dir}/9_finaloutput.png', 0)
img1.shape
# img1.threshold
# gray1 = cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY)

# image 2
img2 = cv2.imread(f'.{working_dir}/trumpsig.png', 0)
plt.imshow(img2)

# template matching test 1
import cv2 
import numpy as np
import imutils

# # Read the main image 
# img_rgb = cv2.imread('mainimage.jpg'). 

img_gray  = cv2.imread(f'.{working_dir}/5_finaloutput.png', 0)

# img_gray = cv2.adaptiveThreshold(img_gray,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY,11,5)
img_gray= cv2.threshold(img_gray, 127, 255, cv2.THRESH_BINARY_INV)[1]
# img_gray=cv2.normalize(img_gray, None, alpha=-1, beta=1, norm_type=cv2.NORM_MINMAX)


fig1, ax1 = plt.subplots(figsize=(15,15))
# template2
ax1.imshow(img_gray)
ax1.set_axis_off()
ax1.title.set_text('img_gray')


template = cv2.imread(f'.{working_dir}/obamasig2.png', 0) 
# template = cv2.threshold(template, 180, 255, cv2.THRESH_BINARY_INV)[1]
template = cv2.adaptiveThreshold(template,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY_INV,7,11)
# template=cv2.normalize(template, None, alpha=-1, beta=1, norm_type=cv2.NORM_MINMAX)

fig2, ax2 = plt.subplots(figsize=(15,15))
# template2
ax2.imshow(template)
ax2.set_axis_off()
ax2.title.set_text('template')


(tH, tW) = template.shape[:2]
print(f"template shape is {template.shape}")
# Read the template 

print(f"img shape is {img_gray.shape}")
# Store width and height of template in w and h 
w, h = template.shape[::-1] 
found = None
count=0
bestpercent=0
# bestresult=[]

methods = ['cv2.TM_CCOEFF', 'cv2.TM_CCOEFF_NORMED', 'cv2.TM_CCORR',
            'cv2.TM_CCORR_NORMED', 'cv2.TM_SQDIFF', 'cv2.TM_SQDIFF_NORMED']

for scale in np.linspace(0.1, 2.0, 20)[::-1]: 
    count+=1
    try:
    # resize the image according to the scale, and keep track 
    # of the ratio of the resizing
        resized = imutils.resize(img_gray, width = int(img_gray.shape[1] * scale))
        print(f"resized shape is {resized.shape}")
        r = img_gray.shape[1] / float(resized.shape[1])
#         print(f"ratio is {r}")

        result = cv2.matchTemplate(resized, template, cv2.TM_CCORR)
        print(f"result shape is {result.shape}")
#         print(f"result is {result}")


        (minVal, maxVal, minLoc, maxLoc) = cv2.minMaxLoc(result)
        print(minVal, maxVal, minLoc, maxLoc)

#     if we have found a new maximum correlation value, then update the found variable 
        if found is None or maxVal > found[0]: 
            found = (maxVal, maxLoc, r)
            print(f"found is {found}")
            bestresult=result
            print(f"This is a better match at maxVal is {maxVal}, maxLoc is {maxLoc}, ratio is {r}")
        else:
            print("This is NOT a better match")

        percentage=maxVal*r/(template.shape[0]*template.shape[1])
        if percentage>bestpercent:
            bestpercent=percentage
    except:
        print("didnt work")

# unpack the found varaible and compute the (x, y) coordinates 
# of the bounding box based on the resized ratio 
print(f"Best value, best location, and ratio is {found}")
print(f"best percent is {bestpercent}")

print(f"found is {found}")

(bestVal, bestLoc, bestr) = found

print(f"found2 is {found}")

(startX, startY) = (int(bestLoc[0] * bestr), int(bestLoc[1] * bestr)) 
(endX, endY) = (int((bestLoc[0] + tW) * bestr), int((bestLoc[1] + tH) * bestr)) 

# print(f"maxLoc is {bestLoc}, r is {bestr}")

# print(f"startx starty is {(startX, startY)}, endx end y is {(endX, endY)}")

# draw a bounding box around the detected result and display the image 
cv2.rectangle(img_gray, (startX, startY), (endX, endY), (255, 255, 0), 2) 


# Show the final image with the matched area. 
fig10, ax10 = plt.subplots(figsize=(15,15))
ax10.imshow(cv2.bitwise_not(img_gray), cmap='Greys_r')
ax10.set_axis_off()
ax10.title.set_text('final')
...