OpenCV多模板匹配-改进匹配

gv8xihay  于 2022-11-15  发布在  其他
关注(0)|答案(1)|浏览(194)

我试着在Map上识别4个相同的基准标记。在互联网的帮助下,我创造了一些东西,但我正在寻找改进搜索的方法,因为结果远不完美。
到目前为止,我尝试了以下方法:

  • 更改阈值
  • 尝试不同的cv2方法
  • 缩小图像和模板

这是我的代码:

import cv2
import numpy as np
from imutils.object_detection import non_max_suppression
  
# Reading and resizing the image

big_image = cv2.imread('20221028_093830.jpg')
 
scale_percent = 10 # percent of original size
width = int(big_image.shape[1] * scale_percent / 100)
height = int(big_image.shape[0] * scale_percent / 100)
dim = (width, height)

img = cv2.resize(big_image, dim, interpolation = cv2.INTER_AREA)

temp = cv2.imread('try_fiduc.png')
  
# save the image dimensions
W, H = temp.shape[:2]
  
# Converting them to grayscale
img_gray = cv2.cvtColor(img, 
                        cv2.COLOR_BGR2GRAY)
temp_gray = cv2.cvtColor(temp,
                         cv2.COLOR_BGR2GRAY)

# Blur the image
img_blurred = cv2.GaussianBlur(img_gray, (7, 7), 0)

# Increasing contrast
img_contrast = img_blurred*3

# Passing the image to matchTemplate method
match = cv2.matchTemplate(
    image=img_contrast, templ=temp_gray, 
  method=cv2.TM_CCOEFF)\

# Define a minimum threshold
thresh = 6000000

# Select rectangles with confidence greater than threshold
(y_points, x_points) = np.where(match >= thresh)
  
# initialize our list of rectangles
boxes = list()
  
# loop over the starting (x, y)-coordinates again
for (x, y) in zip(x_points, y_points):
    
    # update our list of rectangles
    boxes.append((x, y, x + W, y + H))
  
# apply non-maxima suppression to the rectangles
# this will create a single bounding box
boxes = non_max_suppression(np.array(boxes))
  
# loop over the final bounding boxes
for (x1, y1, x2, y2) in boxes:
    
    # draw the bounding box on the image
    cv2.rectangle(img, (x1, y1), (x2, y2),
                  (255, 0, 0), 3)
  

# Show the template and the final output
cv2.imshow("Template", temp_gray)
cv2.imshow("Image", img_contrast)
cv2.imshow("After NMS", img)
cv2.waitKey(0)
  
# destroy all the windows manually to be on the safe side
cv2.destroyAllWindows()

这是我的模板:

这是我的形象:https://ibb.co/QHQh65s
这就是结果:

**还有什么方法可以改进模板匹配?**最后我希望能够从更远的距离识别它们,而不是错误的匹配。任何帮助都将不胜感激。

shstlldc

shstlldc1#

下面是我在Python/OpenCV中的实现方式。与您的基本相同,只是做了一些更改。
首先,我不需要计算调整大小的dim值,我只需要使用scale_percent/100这个分数。
第二,我将阈值图像和反转模板,使您匹配图像和模板中的黑色环。
第三,我将使用TM_SQDIFF并查找低于阈值的值。

import cv2
import numpy as np
from imutils.object_detection import non_max_suppression
  
# Reading and resizing the image

big_image = cv2.imread('diagram.jpg')
 
scale_percent = 10 # percent of original size
scale = scale_percent/100

img = cv2.resize(big_image, (0,0), fx=scale, fy=scale, interpolation = cv2.INTER_AREA)

temp = cv2.imread('ring.png')

# save the image dimensions
W, H = temp.shape[:2]
  
# Converting them to grayscale
img_gray = cv2.cvtColor(img, 
                        cv2.COLOR_BGR2GRAY)
temp_gray = cv2.cvtColor(temp,
                         cv2.COLOR_BGR2GRAY)

# threshold (and invert template)
img_thresh = cv2.threshold(img_gray, 0, 255, cv2.THRESH_BINARY+cv2.THRESH_OTSU)[1]
temp_thresh = cv2.threshold(temp_gray, 0, 255, cv2.THRESH_BINARY_INV+cv2.THRESH_OTSU)[1]

# Passing the image to matchTemplate method
match = cv2.matchTemplate(
    image=img_thresh, templ=temp_thresh, 
  method=cv2.TM_SQDIFF)\

min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(match)
print(min_val, max_val)

# Define a threshold
# thresh between 40000000 and 60000000 works
thresh = 50000000

# Select rectangles with confidence less than threshold for TM_SQDIFF
(y_points, x_points) = np.where(match <= thresh)
  
# initialize our list of rectangles
boxes = list()
  
# loop over the starting (x, y)-coordinates again
for (x, y) in zip(x_points, y_points):    
    # update our list of rectangles
    boxes.append((x, y, x + W, y + H))
  
# apply non-maxima suppression to the rectangles
# this will create a single bounding box
boxes = non_max_suppression(np.array(boxes))
  
# loop over the final bounding boxes
result = img.copy()
for (x1, y1, x2, y2) in boxes:    
    # draw the bounding box on the image
    cv2.rectangle(result, (x1, y1), (x2, y2),
                  (255, 0, 0), 3)

# save result
cv2.imwrite('diagram_match_locations.jpg', result) 

# Show the template and the final output
cv2.imshow("Template_thresh", temp_thresh)
cv2.imshow("Image_thresh", img_thresh)
cv2.imshow("After NMS", result)
cv2.waitKey(0)
  
# destroy all the windows manually to be on the safe side
cv2.destroyAllWindows()

结果:

相关问题