22

我的用户正在将图像上传到我的网站,我想首先向他们提供已经上传的图像。我的想法是 1. 为每个现有图像创建某种图像“散列” 2. 创建新上传图像的散列并将其与数据库中的其他图像进行比较

我找到了一些有趣的解决方案,例如http://www.pureftpd.org/project/libpuzzlehttp://phash.org/等,但他们遇到了一个或多个问题

  1. 他们需要一些非标准的 PHP 扩展(或者根本不在 PHP 中)——这对我来说没问题,但我想将它创建为我流行的 CMS 的插件,它在许多托管环境中使用,不受我的控制。
  2. 他们正在比较两张图片,但我需要一对多(例如数千张)进行比较,并且一张一张地进行比较会非常无效/缓慢......

我可以只找到非常相似的图像(例如不同的大小、重新保存的 jpg 或不同的 jpg 压缩系数)。

我得到的唯一想法是将图像大小调整为例如 5px*5px* 256 色,创建它的字符串表示,然后找到相同的。但我猜想即使只有两张大小不同的相同图像,它也可能会在颜色上产生微小的差异,所以只找到 100% 相同的图像是没有用的。

所以我需要一些好的图像字符串表示格式,而不是可以与一些 SQL 函数一起使用来找到类似的,或者其他一些好的方法。例如 phash 创建感知散列,所以当两个数字接近时,图像也应该接近,所以我只需要找到最近的距离。但它又是外部库。

有什么简单的方法吗?

4

4 回答 4

23

我以前也遇到过同样的问题。

随意复制我所做的,希望它能帮助您/解决您的问题。


我是如何解决的

我的第一个失败的想法,类似于你可能在想的,是我最终为每张图片制作了字符串(无论大小)。但是我很快就发现这可以超快地填充您的数据库,并且效果不佳。

下一个选项(有效)是一个较小的图像(就像你的5px想法),我就是这样做的,但是使用10px*10px图像。我为每个图像创建“哈希”的方式就是imagecolorat()函数。

请参阅此处的 php.net。

收到rgb图像的颜色时,我将它们四舍五入到最接近的50,这样颜色就不那么具体了。该数字 ( ) 是您想要更改的数字,具体50取决于您希望搜索的具体程度。

例如:

// Pixel RGB
rgb(105, 126, 225) // Original
rgb(100, 150, 250) // After rounding numbers to nearest 50

在对每个像素执行此操作后(10px*10pxrgb()返回 100 ),然后我将它们转换为数组,并将它们作为 and 存储在数据库base64_encode()serialize()

在搜索相似的图像时,我对他们想要上传的图像执行了完全相同的过程,然后从数据库中提取图像“哈希”以比较它们,并查看匹配的圆角rgb's。


提示

  • 四舍五入的越大,您50的搜索就越不具体(反之亦然)。rgb

  • 如果您希望您的SQL更具体,最好将有关图像的额外/特定信息存储在数据库中,以便您可以限制在数据库中获得的搜索。例如。如果纵横比为4:3,则仅从数据库中拉取图像4:3。(ETC)

  • 要完美地获得这个5px*可能很困难5px,因此建议使用 phpthumb。我使用它的语法:

phpthumb.php?src=IMAGE_NAME_HERE.png&w=10&h=10&zc=1
// &w=  width of your image
// &h=  height of your image
// &zc= zoom control. 0:Keep aspect ratio, 1:Change to suit your width+height

祝朋友好运,希望能帮到你。

于 2012-07-05T01:17:51.337 回答
2

对于一个简单的 php 实施检查:https ://github.com/kennethrapp/phasher

但是 - 我想知道是否有一个用于“比较”的本机 mySql 函数(参见上面的 php 类)

于 2013-05-06T19:57:30.330 回答
0

以学术的方式把它放下,你正在寻找的是一个相似度函数,它接收两个图像并返回一个指示两个图像有多远/相似的指标。这个指标很容易是一个从 -1 到 1 的十进制数(相距很远到很近)。拥有此功能后,您可以将图像设置为参考并将所有图像与其进行比较。然后找到与一个相似的图像就像找到最接近的相似性因子一样简单,只需在 MySQL 等 RDBMS 中的双字段上进行简单搜索即可。

现在剩下的就是如何定义相似度函数。老实说,这是特定于问题的。这取决于你所说的相似。但是协方差通常是一个很好的起点,它只需要你的两个图像大小相同,我认为这没什么大不了的。但是,您可以找到许多其他想法来搜索“两个图像之间的相似性度量”。

于 2013-12-28T20:10:33.963 回答
0

我将图像缩小到 8x8,然后将 RGB 转换为 1 字节 HSV,因此结果哈希是 172 字节字符串。

HSVHSVHSVHSVHSVHSVHSVHSV... (from 8x8 block, 172 bytes long)
0fff0f3ffff4373f346fff00...

它不是 100% 准确(未找到一些重复项),但效果很好,并且看起来没有误报结果。

于 2013-12-17T11:01:01.110 回答