【问题标题】:Searching for objects from database on image从图像上的数据库中搜索对象
【发布时间】:2018-01-19 19:35:45
【问题描述】:

假设我的数据库包含数千张不同形式和大小(小于 100 x 100 像素)的图像,并且保证每张图像只显示一个对象 - 符号、徽标、路标等。我想成为能够从 Internet 获取任何图像(“my_image.jpg”)并回答“my_image 是否包含我的数据库中的任何对象(对象可以调整大小,但没有变形)?” - 假设有 95% 的可靠性。为了简化 my_images 将有白色背景。

我正在尝试使用 imagehash (https://github.com/JohannesBuchner/imagehash),这将非常有帮助,但为了获得有益的结果,我认为我必须(几乎)计算 my_image 的所有可能散列 - 原因是我不知道对象大小和 my_image 上的位置:

hash_list = []
MyImage = Image.open('my_image.jpg')

for x_start in range(image_width):
    for y_start in range(image_height):
        for x_end in range(x_start, image_width):
            for y_end in range(y_start, image_height):
                hash_list.append(imagehash.phash(MyImage.\
                crop(x_start, y_start, x_end, y_end)))

...然后尝试在数据库中找到类似的哈希,但是当例如 image_width = image_height = 500 时,这个循环和搜索将需要很长时间。当然我可以稍微优化一下,但对于更大的图像,它仍然看起来像 seppuku:

MIN_WIDTH = 30
MIN_HEIGHT = 30
STEP = 2

hash_list = []
MyImage = Image.open('my_image.jpg')

for x_start in range(0, image_width - MIN_WIDTH, STEP):
    for y_start in range(0, image_height - MIN_HEIGHT, STEP):
        for x_end in range(x_start + MIN_WIDTH, image_width, STEP):
            for y_end in range(y_start + MIN_HEIGHT, image_height, STEP):
                hash_list.append(...)

我想知道是否有一些很好的方法来定义 my_image 的哪些部分在计算哈希时是有利可图的——例如,切割边缘看起来是个坏主意。也许有一个更简单的解决方案?如果程序能在最多 20 分钟内给出答案,那就太好了。如有任何建议,我将不胜感激。

PS:对不起我的英语:)

【问题讨论】:

    标签: image-processing computer-vision image-recognition pattern-recognition


    【解决方案1】:

    毕竟我找到了对我来说看起来非常不错的解决方案,也许它对其他人有用:

    我正在使用 SIFT 从 my_image 中检测“最佳候选者”:

    def multiscale_template_matching(template, image):
        results = []
        for scale in np.linspace(0.2, 1.4, 121)[::-1]:
            res = imutils.resize(image, width=int(image.shape[1] * scale))
            r = image.shape[1] / float(res.shape[1])
            if res.shape[0] < template.shape[0] or res.shape[1] < template.shape[1];
               break
    
            ## bigger correlation <==> better matching
            ## template_mathing uses SIFT to return best correlation and coordinates
            correlation, (x, y) = template_matching(template, res)
            coordinates = (x * r, y * r)
            results.appent((correlation, coordinates, r))
    
        results.sort(key=itemgetter(0), reverse=True)
        return results[:10]
    

    然后对于结果,我正在计算哈希:

    ACCEPTABLE = 10
    
    def find_best(image, template, candidates):
        template_hash = imagehash.phash(template)
        best_result = 50  ## initial value must be greater than ACCEPTABLE
        best_cand = None
    
        for cand in candidates:
            cand_hash = get_hash(...)
            hash_diff = template_hash - cand_hash
            if hash_diff < best_result:
                best_result = hash_diff
                best_cand = cand
    
        if best_result <= ACCEPTABLE:
            return best_cand, best_result
        else:
            return None, None
    

    如果结果

    【讨论】:

      【解决方案2】:

      对我来说,这看起来像是一个图像检索问题。但是,在您的情况下,您对二进制 YES / NO 答案更感兴趣,该答案告诉输入图像 (my_image.jpg) 是否属于数据库中存在的对象。

      我可以建议的第一件事是,您可以将所有图像(包括输入)调整为固定大小,例如 100 x 100。但是如果某些图像中的对象非常小或存在于特定区域图像(例如,左上角)然后调整大小会使事情变得更糟。但是,您的问题并不清楚您的情况有多大。

      关于查找对象位置的第二个问题,我认为您正在考虑这个问题,因为您的输入图像尺寸很大,例如 500 x 500?如果是这样,那么调整大小是更好的主意。但是,如果您问这个问题是因为对象定位到图像中的特定区域,那么我认为您可以计算一个渐变图像,这将帮助您识别背景区域,如下所示:因为背景没有变化(完全白色),渐变值将是属于背景区域的像素为零。

      我建议您阅读基于视觉词袋(例如here)的对象分类方法,而不是计算和使用图像哈希。尽管您的目标不是对对象进行分类,但它会帮助您想出不同的方法来解决您的问题。

      【讨论】:

      • 感谢您的回答。我正在尝试调整输入图像的大小,但我注意到这会导致效率降低并且结果不清楚。另一方面,我正在阅读有关 SIFT 的信息,它看起来很有希望,但我不知道这是否会是更省时的解决方案。你有过“筛选”的经历吗?
      • 由于图像的背景是白色的,如何从原始图像中裁剪包围对象的最小矩形,然后尝试调整大小?关于 SIFT,我会推荐 BoW、LBP 等。
      • 感谢您对 BoW,LBP 的建议。在调整大小之前裁剪是很好的观察。我会考虑一下,但恐怕我想改进我的解决方案以在未来识别更困难的问题 - 请在下面查看我的答案。另一方面,我也考虑深度学习 :)
      猜你喜欢
      • 2013-10-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-07-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多