我需要确定酸奶在超市的位置。源照片看起来像
带模板:
我使用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,但这种方法在这种情况下不工作。
4条答案
按热度按时间xxe27gdn1#
我提出了一种基于this论文中讨论的方法。我对该方法进行了一些修改,因为用例并不完全相同,但他们确实使用SIFT特征匹配来定位视频帧中的多个对象。他们使用PCA来减少时间,但静态图像可能不需要。
对不起,我不能写一个代码,因为这将需要大量的时间,但我相信这应该工作,以找到所有出现的模板对象。
修改后的方法是这样的:
将模板图像划分为区域:沿水平方向的左、中、右沿着和沿垂直方向的上、下沿着
现在,当您匹配模板和源图像之间的特征时,您将从源图像上多个位置的这些区域中的一些关键点获得匹配的特征。您可以使用这些关键点来识别模板的哪个区域出现在哪个位置如果存在重叠区域,即来自不同区域的关键点与源图像中的接近关键点匹配,则这将这意味着错误的匹配。
将源图像上邻域内的每组匹配关键点标记为左、中、右、上、下,这取决于它们是否具有来自模板图像中特定区域的关键点的多数匹配。
从源图像上的每个左区域开始向右移动,如果我们找到一个中心区域,然后是一个右区域,那么在标记为左和右的区域之间的源图像的这个区域可以被标记为一个模板对象的位置。
当从左区域向右移动时,可能存在重叠的对象,这可能导致左区域后面跟着另一个左区域。两个左区域之间的区域可以标记为一个模板对象。
对于进一步细化的位置,标记为一个模板对象的源图像的每个区域可以被裁剪并与模板图像重新匹配。
mu0hgdu02#
试着在空间上工作:对于img2中的每个关键点,在周围设置一些边界框,并仅考虑其中的点,以检查ransac单应性是否最佳。
您也可以使用重叠窗口,然后丢弃类似的单应性结果
von4xj4u3#
这里是你可以做的
基础图像=货架全貌
模板图像=单个产品图像
1.从两个图像中获取SIFT匹配。(基础图像和模板图像)
1.做特征匹配。
1.获取基础图像中所有匹配的点。(参见图)
1.根据模板图像的大小创建集群。(此处阈值为50px)
1.获取聚类的边界框。
1.裁剪每个边界框cluter并检查与模板图像的匹配。
1.接受所有cluters,其中至少有最低百分比的匹配。(这里采取的关键点的最低10%)
mlmc2os54#
首先,您可以使用像this这样的网络检测货架上的任何物品,它在此确切的上下文中进行了预训练,并且工作得很好。您还应该在将图像馈送到网络之前对其进行校正。您将获得每个产品的边界框(可能是一些假阳性/阴性,但这是另一个问题)。然后,您可以使用SIFT将每个框与模板进行匹配并计算分数(这取决于你定义哪个分数起作用),但我建议使用另一种方法,如暹罗网络,如果你有一个一致的数据集。