假设我拥有数千个具有不同形式和大小(小于100 x 100px)的图像的数据库,并且保证每个图像只显示一个对象 - 符号,徽标,道路标志等。我想成为能够从互联网上获取任何图像(“my_image.jpg”)并回答问题“我的数据库中是否包含任何对象(对象可以调整大小,但没有变形)?” - 让我们说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:对不起我的英语:)
答案 0 :(得分:1)
这看起来像是我的图像检索问题。但是,在您的情况下,您更感兴趣的是二进制YES / NO答案,它告诉输入图像(my_image.jpg)是否是数据库中存在的对象。
我可以建议的第一件事是你可以将所有图像(包括输入)的大小调整为固定大小,比如说100 x 100.但是如果某个图像中的某个对象非常小或存在于特定区域图像(例如,左上角)然后调整大小会使事情变得更糟。但是,从你的问题中不清楚这种情况有多大。
关于你找到对象位置的第二个问题,我认为你正在考虑这个,因为你的输入图像是大尺寸的,比如500 x 500?如果是这样,那么调整大小是更好的主意。但是,如果您问这个问题是因为对象局部定位到图像中的特定区域,那么我认为您可以计算出一个渐变图像,它将帮助您识别背景区域,如下所示:因为背景没有变化(完全白色),所以渐变值将是属于背景区域的像素为零。
我建议您阅读有关对象分类的基于视觉词袋(例如here)的方法,而不是计算和使用图像哈希。虽然您的目标不是对对象进行分类,但它会帮助您提出一种不同的方法来解决您的问题。
答案 1 :(得分:0)
毕竟我找到了对我来说非常好的解决方案,也许对其他人有用:
我使用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
如果结果&lt;接受,我几乎可以肯定答案是#34; GOT YOU!&#34; :)这个解决方案允许我在7分钟内将my_image与1000个对象进行比较。