标签: phash

在Elasticsearch中通过pHash距离搜索类似的图像

类似的图像搜索问题

  • 数百万张图像在Elasticsearch中进行了标记和存储.
  • 格式为"11001101 ... 11"(长度64),但可以更改(最好不要).

给定主题图像的散列"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)

image hamming-distance elasticsearch phash

36
推荐指数
4
解决办法
8316
查看次数

对于pHash开源感知哈希库有哪些替代方案?

我知道你可以使用.NET或Java的pHash,但我想要一个纯.NET(最好)或Java实现.还有其他可用的吗?我特别感兴趣的是图像散列功能.

感知散列是一种创建图像数字散列的方法,然后能够比较这些散列以查看图像是否相似.它允许真正快速的图像识别.

.net java hash image-processing phash

14
推荐指数
1
解决办法
9096
查看次数

为iOS编译pHash

如何编译pHash iOS

我阅读文档,但没有提及iOS/armGoogle没有帮助.

因此,如果有人能够为iOS编译pHash,请分享您的经验.

iphone arm objective-c ios phash

13
推荐指数
1
解决办法
1218
查看次数

Phash vs. SIFT识别相似图像

我对都有疑问

首先,我使用SIFT来识别实时服务中的类似图像.像手机相机的照片一样,旋转量小,效果模糊.

我发现了Phash.所以,我在其演示页面上测试了phash .但结果让我感叹.

这是上述测试的结果:

Phash的演示

在该测试中,两个图像固定在x轴上.所以他们没有轮换.但右图像的徽标被删除,人被移到左侧.在我看来,这是'非常相似'.此外,SIFT完全抓住了这一点.

现在,这是个问题.

  1. pHash比SIFT快?
  2. pHash的准确度是否可靠?
  3. SIFT的输出太大,无法用于实时服务.所以我必须使用hash来使输出更小,如LSH(局部敏感散列).我尝试其他任何方式?

image process vision sift phash

7
推荐指数
1
解决办法
2399
查看次数

如何知道图像是否与另一个图像相似(角度略有不同但观点相同)

我已经检查了像Phasher这样的方法来获得类似的图像.基本上将图像大小调整为8x8,灰度,获得平均像素并创建每个像素的二进制散列,比较它是高于还是低于平均像素.

这个方法在这里有很好的解释:http: //hackerfactor.com/blog/index.php?/archives/432-Looks-Like -It.html

工作示例: - 桌面上计算机的图像1 - 图像2,相同,但带有硬币

在此输入图像描述

这可行,因为,使用非常简化的灰度图像的散列,它们将几乎相同,甚至相同.所以你可以得出结论,当90%以上的像素相同时(在同一个地方!)

我的问题是从相同的角度拍摄但角度不同的图像,例如:

在此输入图像描述

在这种情况下,生成的哈希"指纹"是相互移位的,我们无法一点一点地比较哈希,它会有很大的不同.

像素是"相似的",但它们不在同一个地方,因为在这种情况下有更多的天空,并且房屋"开始"比第一个更低.

因此,哈希比较导致"它们是不同的图像".

可能的方法:

我正在考虑为第一个图像创建一个更大的哈希,然后为第二个图像获得10个随机"子哈希",并尝试查看10个子哈希是否在第一个大哈希的"某个地方"(如果一个子串被包含在另一个更大的中).

这里的问题我认为是处理数千张图像时的CPU /时间,因为你必须将1张图像与1000张进行比较,并且在每张图像中,将10个子哈希与一个大的哈希进行比较.

其他方案?;-)

hash comparison image phash

7
推荐指数
2
解决办法
2457
查看次数

MySQL或PostgreSQL的汉明距离优化?

我试图在MySQL数据库中改进搜索类似图像的pHashed.现在我比较pHash计算汉明距离像这样:

SELECT * FROM images WHERE BIT_COUNT(hash ^ 2028359052535108275) <= 4
Run Code Online (Sandbox Code Playgroud)

选择结果(引擎MyISAM)

  • 20000行; 查询时间<20ms
  • 100000行; 查询时间~60ms#这很好,直到达到150000行
  • 30万行; 查询时间~150ms

因此查询时间增加取决于表中的行数.


我还尝试在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上有很多关于汉明距离的理论问题

谢谢!

mysql sql query-optimization hamming-distance phash

5
推荐指数
1
解决办法
4935
查看次数

将使用PIL加载的图像转换为Cimg图像对象

我试图将使用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吗?

c++ cimg python-imaging-library python-2.7 phash

5
推荐指数
1
解决办法
712
查看次数

使用SOLR计算两个ulongs之间的"相似性"/"bitcount"

我们有一个图像数据库,我使用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以找到相似顺序的其他哈希值.

几点说明:

  1. 在这里使用SOLR(只有我有的替代品是HBASE)
  2. 想避免在solr中安装任何自定义java(很高兴安装现有的插件)
  3. 很高兴在C#中进行大量的预处理
  4. 很高兴使用多个字段将数据存储为位串,长串等
  5. 使用SOLRNet作为客户端

编辑,一些额外的信息(道歉我陷入了问题并开始假设它是一个广为人知的领域).这是直接下载到C#console/sample app:http://01101001.net/Imghash.zip

此控制台应用程序的示例输出将是:

004143737f7f7f7f phash-test-001.jpg
0041417f7f7f7f7f phash-test-002.jpg
相似度:95.3125%

c# solr bit-manipulation solrnet phash

5
推荐指数
1
解决办法
694
查看次数

局部敏感哈希还是 pHash?

我正在尝试实现一个通用的指纹记忆器:我们有一个可以通过智能指纹表达的文件(如图像的pHash或音频的色度图),如果我们想要的(昂贵的)函数已经在类似的文件上计算过,然后我们返回相同的结果(避免昂贵的计算)。

局部敏感哈希(LSH) 是一种流行且性能良好的解决方案,用于解决昂贵的多维空间中的近似最近邻问题。

pHash是一个很好的库,它实现了图像的感知散列。

因此,pHash 将多维输入(图像)转换为一维对象(哈希码),这与 LSH(再次,LSH 中的多维对象)有所不同。

所以我想知道我们如何为 pHash 哈希值实现单维 LSH?或者简单地说:我们如何将类似的 pHash 值分组到 bin 中?它可以替代经典的 LSH 方法吗(如果不是为什么)?

c++ hash locality-sensitive-hash phash

5
推荐指数
1
解决办法
1334
查看次数

如何计算 MySQL 查询中两个散列之间的差异?

我正在尝试计算输入散列和数据库存储的散列之间的汉明距离。这些是感知散列,因此它们之间的汉明距离对我很重要,并告诉我两个不同图像的相似程度(参见http://en.wikipedia.org/wiki/Perceptual_hashinghttp://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?

小提琴:https : //www.db-fiddle.com/f/mpqsUpZ1sv2kmvRwJrK5xL/0

mysql hash bit-manipulation hamming-distance phash

5
推荐指数
1
解决办法
1218
查看次数