【问题标题】:SIFT match computer visionSIFT 匹配计算机视觉
【发布时间】: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


【解决方案1】:

首先,您可以使用this 之类的网络检测货架上的任何商品,它已在此确切上下文中进行了预训练并且运行良好。您还应该在将图像输入网络之前对其进行校正。您将获得每个产品的边界框(可能是一些误报/误报,但这是另一个问题)。然后,您可以使用 SIFT 将每个框与模板匹配并计算分数(取决于您定义哪个分数有效),但如果您的数据集一致,我建议使用其他方法,例如连体网络。

【讨论】:

猜你喜欢
  • 2013-11-12
  • 2018-11-07
  • 2012-01-28
  • 2011-10-18
  • 2017-08-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-04
相关资源
最近更新 更多