【问题标题】:Image similarity detection图像相似度检测
【发布时间】:2026-02-04 20:55:02
【问题描述】:

我一直在写一个可以抓取 Deviantart.com 的抓取工具。它在本地保存新图像的副本,并在 Postgresql 数据库中为图像创建记录。我的问题:当新图像出现时,我怎么知道这个新图像是否与我以前见过的图像相对应?在 DA 上,被欺骗的情况相当罕见,但与此同时,从更普遍的意义上来说,这是一个有趣的问题。

对如何进行的想法?

现在 Postgresql 数据库在我抓取图像时被填充,并且它有一个看起来像这样的表:

CREATE TABLE Image
(
    id SERIAL PRIMARY KEY NOT NULL,
    url varchar(5000) UNIQUE NOT NULL,
    dateadded timestamp without time zone default (now() at time zone 'utc'),
    width int,
    height int
);

其中 url 是我从 DA 抓取的图像的链接(例如:http://th05.deviantart.net/fs70/PRE/f/2014/222/2/3/sketch_dump_56_by_lilaira-d7uj8pe.png),dateadded 是刮板找到图像的datetimewidthheight 是图像尺寸。

我目前不将图像本身存储在数据库中,但我会保留一个本地镜像——我获取图像的 url 和 wget -r -nc 文件。所以对于一个网址:http://th05.deviantart.net/fs70/PRE/f/2014/222/2/3/sketch_dump_56_by_lilaira-d7uj8pe.png 我在<somedir>/th05.deviantart.net/fs70/PRE/f/2014/222/2/3/sketch_dump_56_by_lilaira-d7uj8pe.png 保留一个本地副本

现在,一般情况下的图像识别非常困难。我希望能够处理诸如轻微调整大小之类的事情,我可以通过将所有图像标准化为特定分辨率来解决这个问题,并在查询时将查询图像标准化为相同的分辨率。我希望能够处理诸如格式更改(PNG vs JPG vs 等)之类的事情,我可以通过将图像文件读入标准化格式(例如:每个像素的未压缩 RGB 值,尽管理想情况下会出现一些“松弛”)这里容忍)。

很高兴拥有(愿意放弃简化/更好的准确性):

  • 我希望能够处理裁剪图像(例如:我以前见过imageA,有人将imageA 裁剪并上传为imageB 我想注意到作为副本)。
  • 我希望能够处理带有徽标的图像水印
  • 我希望能够在要分类的新图像是先前看到的图像的子图像的情况下处理裁剪(即 - 我存储了 imageA,有人拿走了 imageA 并裁剪它,我'希望能够将裁剪后的图像映射到 imageA)

约束/额外信息:

  • 我对查找不同但相似的图像完全不感兴趣(例如:同一辆红色巴士的两张不同照片应报告为两张不同的图像)
  • 虽然我并不完全反对使用元数据(例如:艺术家、图像类别等),但我希望尽可能将其限制为图像数据(EXIF 数据、分辨率、RBG 颜色值) .
  • 缩小尺寸并出现在 较大图像中的图像,我希望将其视为不同。例如:我有imageA,我将其调整为 50x50,并且 50x50 网格出现在新图像中,我不会认为新图像与imageA“相同”(尽管我想按照之前概述的标准我会考虑 imageA 新图像的副本)
  • 如果可以检测到图像中的“微小”修订(例如:图像中伽马值的全面变化等),那就太好了,但不是必需的

想法?有什么建议吗?

对于我的用例,我更关心误报而不是误报,因此“模糊匹配”方法应该谨慎行事。

万一这很重要,我会用 Python 编写所有这些内容,尽管 TBH 如果它优雅/高效地解决了我的问题,我很乐意使用替代技术。

【问题讨论】:

标签: image image-processing machine-learning similarity


【解决方案1】:

我会在不靠近边缘的某个地方抓取一个小的子图像,然后在数据库图像中它的源位置附近进行交叉关联。您可以在互相关之前对其重新采样以解决较小的调整大小,并且您可以选择匹配的附近区域的大小以解决一定百分比的不对称作物。

为避免在无特征区域(例如天空)上完美拟合,您可以使用局部图像变化作为子图像位置的选择标准。

这仍然会很慢,因此有必要使用全局图像度量来首先从数据库中选择候选副本(例如 danf 提到的颜色直方图)。

【讨论】: