给定主题图像的散列"100111..10",我们希望在汉明距离为8的 Elasticsearch索引中找到所有相似的图像散列.
当然,查询可以返回距离大于8的图像,Elasticsearch或外部的脚本可以过滤结果集.但总搜索时间必须在1秒左右.
每个文档都有images包含图像哈希的嵌套字段:
{
"images": {
"type": "nested",
"properties": {
"pHashFingerprint": {"index": "not_analysed", "type": "string"}
}
}
}
Run Code Online (Sandbox Code Playgroud)
事实: Elasticsearch模糊查询仅支持最大2的Levenshtein距离.
我们使用自定义标记生成器将64位字符串拆分为4组16位,并使用4个模糊查询进行4组搜索.
分析:
{
"analysis": {
"analyzer": {
"split4_fingerprint_analyzer": {
"type": "custom",
"tokenizer": "split4_fingerprint_tokenizer"
}
},
"tokenizer": {
"split4_fingerprint_tokenizer": {
"type": "pattern",
"group": 0,
"pattern": "([01]{16})"
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
然后新的字段映射:
"index_analyzer": "split4_fingerprint_analyzer",
Run Code Online (Sandbox Code Playgroud)
然后查询:
{
"query": {
"filtered": {
"query": {
"nested": {
"path": "images",
"query": {
"bool": …Run Code Online (Sandbox Code Playgroud) 我知道你可以使用.NET或Java的pHash,但我想要一个纯.NET(最好)或Java实现.还有其他可用的吗?我特别感兴趣的是图像散列功能.
感知散列是一种创建图像数字散列的方法,然后能够比较这些散列以查看图像是否相似.它允许真正快速的图像识别.
如何编译pHash iOS?
我阅读文档,但没有提及iOS/arm并Google没有帮助.
因此,如果有人能够为iOS编译pHash,请分享您的经验.
首先,我使用SIFT来识别实时服务中的类似图像.像手机相机的照片一样,旋转量小,效果模糊.
我发现了Phash.所以,我在其演示页面上测试了phash .但结果让我感叹.
这是上述测试的结果:

在该测试中,两个图像固定在x轴上.所以他们没有轮换.但右图像的徽标被删除,人被移到左侧.在我看来,这是'非常相似'.此外,SIFT完全抓住了这一点.
现在,这是个问题.
我已经检查了像Phasher这样的方法来获得类似的图像.基本上将图像大小调整为8x8,灰度,获得平均像素并创建每个像素的二进制散列,比较它是高于还是低于平均像素.
这个方法在这里有很好的解释:http: //hackerfactor.com/blog/index.php?/archives/432-Looks-Like -It.html
工作示例: - 桌面上计算机的图像1 - 图像2,相同,但带有硬币

这可行,因为,使用非常简化的灰度图像的散列,它们将几乎相同,甚至相同.所以你可以得出结论,当90%以上的像素相同时(在同一个地方!)
我的问题是从相同的角度拍摄但角度不同的图像,例如:

在这种情况下,生成的哈希"指纹"是相互移位的,我们无法一点一点地比较哈希,它会有很大的不同.
像素是"相似的",但它们不在同一个地方,因为在这种情况下有更多的天空,并且房屋"开始"比第一个更低.
因此,哈希比较导致"它们是不同的图像".
可能的方法:
我正在考虑为第一个图像创建一个更大的哈希,然后为第二个图像获得10个随机"子哈希",并尝试查看10个子哈希是否在第一个大哈希的"某个地方"(如果一个子串被包含在另一个更大的中).
这里的问题我认为是处理数千张图像时的CPU /时间,因为你必须将1张图像与1000张进行比较,并且在每张图像中,将10个子哈希与一个大的哈希进行比较.
其他方案?;-)
我试图在MySQL数据库中改进搜索类似图像的pHashed.现在我比较pHash计算汉明距离像这样:
SELECT * FROM images WHERE BIT_COUNT(hash ^ 2028359052535108275) <= 4
Run Code Online (Sandbox Code Playgroud)
选择结果(引擎MyISAM)
因此查询时间增加取决于表中的行数.
我还尝试在SQL上的二进制字符串上的stackoverflow 汉明距离上找到解决方案
SELECT * FROM images WHERE
BIT_COUNT(h1 ^ 11110011) +
BIT_COUNT(h2 ^ 10110100) +
BIT_COUNT(h3 ^ 11001001) +
BIT_COUNT(h4 ^ 11010001) +
BIT_COUNT(h5 ^ 00100011) +
BIT_COUNT(h6 ^ 00010100) +
BIT_COUNT(h7 ^ 00011111) +
BIT_COUNT(h8 ^ 00001111) <= 4
Run Code Online (Sandbox Code Playgroud)
行300000; 查询时间~240ms
我将数据库引擎更改为PostgreSQL.将此MySQL查询转换为PyGreSQL但 没有成功.行300000; 查询时间〜18s
有优化上述查询的解决方案吗? 我的意思是优化不依赖于行数.
我有限的方法(工具)来解决这个问题.MySQL到目前为止似乎是最简单的解决方案,但我可以在每个开源数据库引擎上部署代码,该引擎将在专用机器上使用Ruby.有一些针对MsSQL的现成解决方案/sf/answers/415166111/(未经测试).也许有人知道如何为MySQL或PostgreSQL翻译它.
请根据一些代码或观察结果发布答案.我们在stackoverflow.com上有很多关于汉明距离的理论问题
谢谢!
我试图将使用PIL加载的iamge转换为Cimg图像对象.据我所知,Cimg是一个c ++库,PIL是一个python成像库.给定一个图像网址,我的目的是计算图像的pHash而不将其写入磁盘.pHash模块与Cimg图像对象一起使用,它已在C++中实现.所以我打算使用python扩展绑定将我的python程序中所需的图像数据发送到c ++程序.在下面的代码片段中,我将从给定的URL加载图像:
//python code sniplet
import PIL.Image as pil
file = StringIO(urlopen(url).read())
img = pil.open(file).convert("RGB")
Run Code Online (Sandbox Code Playgroud)
我需要构建的Cimg图像对象如下所示:
CImg ( const t *const values,
const unsigned int size_x,
const unsigned int size_y = 1,
const unsigned int size_z = 1,
const unsigned int size_c = 1,
const bool is_shared = false
)
Run Code Online (Sandbox Code Playgroud)
我可以使用img.size获取width(size_x)和height(size_y)并将其传递给c ++.我不确定如何填充Cimg对象的'values'字段?使用什么样的数据结构将图像数据从python传递到c ++代码?
另外,还有其他方法将PIL图像转换为Cimg吗?
我们有一个图像数据库,我使用David Oftedal实施的Neal Krawetz博士的方法计算了PHASH .
部分示例代码计算这些长度之间的差异在这里:
ulong hash1 = AverageHash(theImage);
ulong hash2 = AverageHash(theOtherImage);
uint BitCount(ulong theNumber)
{
uint count = 0;
for (; theNumber > 0; theNumber >>= 8) {
count += bitCounts[(theNumber & 0xFF)];
}
return count;
}
Console.WriteLine("Similarity: " + ((64 - BitCount(hash1 ^ hash2)) * 100.0) / 64.0 + "%");
Run Code Online (Sandbox Code Playgroud)
挑战是我只知道其中一个哈希,我想查询SOLR以找到相似顺序的其他哈希值.
几点说明:
编辑,一些额外的信息(道歉我陷入了问题并开始假设它是一个广为人知的领域).这是直接下载到C#console/sample app:http://01101001.net/Imghash.zip
此控制台应用程序的示例输出将是:
004143737f7f7f7f phash-test-001.jpg
0041417f7f7f7f7f phash-test-002.jpg
相似度:95.3125%
我正在尝试实现一个通用的指纹记忆器:我们有一个可以通过智能指纹表达的文件(如图像的pHash或音频的色度图),如果我们想要的(昂贵的)函数已经在类似的文件上计算过,然后我们返回相同的结果(避免昂贵的计算)。
局部敏感哈希(LSH) 是一种流行且性能良好的解决方案,用于解决昂贵的多维空间中的近似最近邻问题。
pHash是一个很好的库,它实现了图像的感知散列。
因此,pHash 将多维输入(图像)转换为一维对象(哈希码),这与 LSH(再次,LSH 中的多维对象)有所不同。
所以我想知道我们如何为 pHash 哈希值实现单维 LSH?或者简单地说:我们如何将类似的 pHash 值分组到 bin 中?它可以替代经典的 LSH 方法吗(如果不是为什么)?
我正在尝试计算输入散列和数据库存储的散列之间的汉明距离。这些是感知散列,因此它们之间的汉明距离对我很重要,并告诉我两个不同图像的相似程度(参见http://en.wikipedia.org/wiki/Perceptual_hashing,http://jenssegers.com/61/感知图像哈希,http://stackoverflow.com/questions/21037578/)。哈希是 16 个十六进制字符长,如下所示:
b1d0c44a4eb5b5a9
1f69f25228ed4a31
751a0b19f0c2783f
我的数据库看起来像这样:
CREATE TABLE `hashes` (
`id` int(11) NOT NULL,
`hash` binary(8) NOT NULL
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=latin1;
INSERT INTO `hashes` (`id`, `hash`) VALUES
(1, 0xb1d0c44a4eb5b5a9),
(2, 0x1f69f25228ed4a31),
(3, 0x751a0b19f0c2783f);
Run Code Online (Sandbox Code Playgroud)
现在,我知道我可以像这样查询汉明距离:
SELECT BIT_COUNT(0xb1d0c44a4eb5b5a9 ^ 0x751a0b19f0c2783f)
Run Code Online (Sandbox Code Playgroud)
正如预期的那样,它将输出 38。但是,我似乎无法为此比较引用列名。以下不按预期工作。
SELECT BIT_COUNT(hash ^ 0x751a0b19f0c2783f) FROM hashes
Run Code Online (Sandbox Code Playgroud)
有谁知道如何SELECT使用我的数据库中的列像上面的第一个查询一样计算汉明距离?我试着使用的场景无数hex(),unhex(),conv(),并cast()以不同的方式。这是在 MySQL 中。
更新我上面的查询在 MySQL v8 中运行时似乎按预期工作(感谢@LukStorms 指出这一点)。您可以使用我下面的小提琴并更改左上角的版本。我现在的问题是:如何确保该行为适用于所有版本的 MySQL?