2

我正在尝试找出图像的地理散列方法。这很难,因为可能图像的空间比 lat/lng 的维度要高得多。(地理散列将位置转换为字符串,其中字符串逐渐细化位置)

所以,我需要的是:

  • INPUT:磁盘上的 JPG 或 PNG 图像列表
  • 输出:对于每个图像一个字符串,其中任何两个图像之间的公共字符串前缀越长,两个图像相同的可能性就越高。

它不需要完美,也不需要处理极端情况,例如裁剪图像或经过大量调整的图像。它适用于不同分辨率和压缩级别的同一图像的多个副本。

我不能使用:

  • 文件或图像数据散列,因为即使两个图像之间的微小变化也会产生完全不同的散列,并且您不会得到任何接近
  • 图像减法,因为它不会是 N 对 N 比较。

我已阅读其他答案以尝试小波压缩或拉普拉斯/高斯金字塔,但我不确定如何在 Java 或 Python 中实现。不过,我进步了!

  1. 使用http://today.java.net/pub/a/today/2007/04/03/perils-of-image-getscaledinstance.html将大小调整为 32x32以不丢弃数据。好的,一切都变成了一个正方形。
  2. 创建一个由逐渐缩小的缩略图组成的金字塔,一直到 2x2。
  3. 在 2x2 中,编码一串“下一个像素是否比当前像素亮?如果是,则为 1,否则为 0 ”(这会丢弃所有色调和饱和度,我可能想以某种方式使用色调)
  4. 对 8x8 和 32x32 金字塔中的连续二进制数进行编码
  5. 将大二进制数转换为更高的基数表示,如 Base62。

这似乎运作良好!压缩或色彩平衡的微小差异不足以改变“该区域的左侧是否比右侧更亮”。但是,我认为我正在重新发明轮子,某种渐进式编码可能会更好?SIFT 和其他特征检测是多余的,我不需要能够处理裁剪或旋转。

4

3 回答 3

0

在我看来,您所描述的似乎是应用于图像相似性问题 的局部敏感散列的一个示例。

我不确定公共前缀属性是否适合良好的哈希函数。我希望一个好的散列函数具有两个属性:

1) 良好的定位 - 对于图像 I1 和 I2,norm(Hash(I1)-Hash(I2)) 应该代表 I1 和 I2 的视觉感知相似性。

2)良好的压缩——高维图像数据应该以最有区别的方式嵌入到哈希函数的低维空间中。

于 2011-12-27T22:54:49.300 回答
0

这个怎么样。哈希字符串由三个字符组成,分别代表红绿蓝:

{R0, G0, B0}, {R1, G1, B1}, {R2, G2, B2}, ...

对于每个组,图像被调整为 2^N x 2^N 的正方形。然后,该值是某些穿过像素的每种颜色的强度差异的总和(例如,255 或任何您的编码)。

因此,作为一个小例子,要计算例如第 1 组(2x2 图像),可以使用以下代码(我只关心红色像素)

int rSum = 0;
int rLast = 0;
for (int i=0; i<2; i++) {
  for (int j=0; j<2; j++) {
    rSum += Math.abs(image[i][j].r - rLast);
    rLast = image[i][j].r;
  }
}
rSum %= 255;

我相信这具有相似的图像应该彼此接近的特性,无论是对于散列中的每个字符还是就散列中的连续字符而言。

尽管 N 值越高,发生碰撞的机会就越高(许多图像的 RG 和 B 强度具有相同的差和值),但每次连续迭代都应该揭示有关未经测试的图像的新信息与之前的迭代。

在计算上可能相当昂贵,但您有一个优势(我从您可能希望的问题中推断出),一旦在某个阈值内检测到负数,您就可以结束哈希的计算。

只是一个想法,如果我不清楚,请告诉我!

于 2011-12-27T22:59:13.350 回答
0

从以下方面获得良好的结果:

缩小(使用不丢弃信息的良好缩放)到三个图像:1x7 7x1 和 6x6 图像。

全部转为灰度。

对于每张图像,做“下一个像素更亮吗?'1':'0' 编码,输出为base62。

这些输出成为三列的值。Nice 先后细化差分,打包成 2 个字符、2 个字符和 6 个字符。没错,丢弃所有颜色,但仍然很好!

于 2012-01-06T23:29:46.097 回答