【发布时间】:2022-01-18 06:28:11
【问题描述】:
带模板:
我使用SIFT提取模板的关键点:
img1 = cv.imread('train.jpg')
sift = cv.SIFT_create()# queryImage
kp1, des1 = sift.detectAndCompute(img1, None)
path = glob.glob("template.jpg")
cv_img = []
l=0
for img in path:
img2 = cv.imread(img) # trainImage
# Initiate SIFT detector
# find the keypoints and descriptors with SIFT
kp2, des2 = sift.detectAndCompute(img2,None)
# FLANN parameters
FLANN_INDEX_KDTREE = 1
index_params = dict(algorithm = FLANN_INDEX_KDTREE, trees = 5)
search_params = dict(checks=50) # or pass empty dictionary
flann = cv.FlannBasedMatcher(index_params,search_params)
matches = flann.knnMatch(des1,des2,k=2)
# Need to draw only good matches, so create a mask
# ratio test as per Lowe's paper
if (l < len(matches)):
l = len(matches)
image = img2
match = matches
h_query, w_query, _= img2.shape
matchesMask = [[0,0] for i in range(len(match))]
good_matches = []
good_matches_indices = {}
for i,(m,n) in enumerate(match):
if m.distance < 0.7*n.distance:
matchesMask[i]=[1,0]
good_matches.append(m)
good_matches_indices[len(good_matches) - 1] = i
bboxes = []
src_pts = np.float32([ kp1[m.queryIdx].pt for m in good ]).reshape(-1,2)
dst_pts = np.float32([ kp2[m.trainIdx].pt for m in good ]).reshape(-1,2)
model, inliers = initialize_ransac(src_pts, dst_pts)
n_inliers = np.sum(inliers)
matched_indices = [good_matches_indices[idx] for idx in inliers.nonzero()[0]]
print(len(matched_indices))
model, inliers = ransac(
(src_pts, dst_pts),
AffineTransform, min_samples=4,
residual_threshold=4, max_trials=20000
)
n_inliers = np.sum(inliers)
print(n_inliers)
matched_indices = [good_matches_indices[idx] for idx in inliers.nonzero()[0]]
print(matched_indices)
q_coordinates = np.array([(0, 0), (h_query, w_query)])
coords = model.inverse(q_coordinates)
print(coords)
h_query, w_query,_ = img2.shape
q_coordinates = np.array([(0, 0), (h_query, w_query)])
coords = model.inverse(q_coordinates)
print(coords)
# bboxes_list.append((i, coords))
M, mask = cv.findHomography(src_pts, dst_pts, cv.RANSAC, 2)
draw_params = dict(matchColor = (0,255,0),
singlePointColor = (255,0,0),
matchesMask = matchesMask,
flags = cv.DrawMatchesFlags_DEFAULT)
img3 = cv.drawMatchesKnn(img1,kp1,image,kp2,match,None,**draw_params)
plt.imshow(img3),plt.show()
SIFT 的结果是这样的
问题是对点进行分类以获得代表每种酸奶的矩形的最佳方法是什么?我尝试了RANSAC,但这种方法在这种情况下不起作用。
【问题讨论】:
-
将大海捞针中的每个特征与针中的特征相匹配。这似乎是你所做的,所以这很好。 -- 尝试findHomography,去除匹配单应性的内点,重复。 -- 或许可以细分图像以帮助查找Homography。
-
模板匹配也是一种选择。 Stackoverflow上有很多这样的问题……也不清楚你是否只想搜索立方体形状的酸奶、绿色酸奶、活性酸奶或具有奇异果味的绿色酸奶。 Imo,考虑到您想要实现的目标,您需要不同的策略。
-
opencv 的“模板匹配”除了翻译之外对任何东西都不是不变的。缩放、剪切、旋转……尤其是光照变化(取决于匹配模式),都会引起问题。 -- 其他软件包具有在轮廓/边缘/零件模型上运行的“模板匹配”,因此更高级一些。 -- 可能更容易采用通用对象检测 DNN 并在模板上对其进行训练。
-
@ChristophRackwitz 你在 OpenCVs 模板匹配上是对的,我同意你的方法。我只想提一下,还有其他策略。可能,我也会使用 R-CNN(并增加我的酸奶;))或类似的东西,但入门级别总是很高。很大程度上还取决于图像的输入质量以及您可以在超市拍照的设置。
-
@ChristophRackwitz 我尝试了您的解决方案,但效果也不太好
标签: python opencv computer-vision