首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >为数以百万计的图片做索引?

为数以百万计的图片做索引?
EN

Stack Overflow用户
提问于 2012-03-14 06:19:32
回答 4查看 7.8K关注 0票数 23

这是来自Frank的lib谜libray ( http://libpuzzle.pureftpd.org/project/libpuzzle )。我试图了解如何在mysql数据库中索引和存储数据。矢量的生成是绝对没有问题的。

示例:

代码语言:javascript
运行
AI代码解释
复制
# Compute signatures for two images
$cvec1 = puzzle_fill_cvec_from_file('img1.jpg');
$cvec2 = puzzle_fill_cvec_from_file('img2.jpg');

# Compute the distance between both signatures
$d = puzzle_vector_normalized_distance($cvec1, $cvec2);

# Are pictures similar?
if ($d < PUZZLE_CVEC_SIMILARITY_LOWER_THRESHOLD) {
  echo "Pictures are looking similar\n";
} else {
  echo "Pictures are different, distance=$d\n";
}

这一切对我来说都很清楚--但是现在当我有大量的图片>1.000.000时,我该如何工作呢?我计算向量并将其存储在数据库中的文件名中?现在怎样才能找到类似的图片?如果我将每个向量存储在mysql中,则必须打开每条记录并使用puzzle_vector_normalized_distance函数计算距离。该过程花费大量时间(打开每个数据库条目-将其抛出函数,.)

我从libaray的lib益智中阅读了自述文件,并发现了以下内容:

它能与拥有数百万张图片的数据库一起工作吗? 一个典型的图像签名只需要182个字节,使用内置的压缩/解压缩功能。 类似的签名有相同的“单词”。相同位置的相同值序列。通过使用复合索引(word + position),极大地减少了可能的相似向量集,而且在大多数情况下,实际上不需要计算向量距离。 通过单词和位置进行索引还可以轻松地将数据拆分为多个表和服务器。 所以是的,谜团库当然不是与需要索引数百万张图片的项目不兼容的。

此外,我还找到了关于索引的描述:

如何快速找到类似的图片,如果他们是数百万的记录? 原来的论文有一个简单而有效的答案。 把向量切成固定长度的字。例如,让我们考虑以下向量: A b,c,d,f,g,h,i,k,l,n,p,q,r,s,t,v,w,x,y,z 如果单词长度(K)为10,则可以得到以下单词: A b、c d e f g h h i j在位置0 b c d e f h h j j k处发现,在位置1 c d f g h i j k找到位置2等,直到N-1位置。 然后,用复合索引(word + position)索引向量。 即使有数以百万计的图像,K= 10和N= 100也足以使很少的条目共享相同的索引。 下面是一个非常基本的示例数据库模式:

代码语言:javascript
运行
AI代码解释
复制
+-----------------------------+
| signatures |
+-----------------------------+
| sig_id | signature | pic_id |
+--------+-----------+--------+

+--------------------------+
| words |
+--------------------------+
| pos_and_word | fk_sig_id |
+--------------+-----------+

我建议至少将“word”表拆分为多个表和/或服务器。 默认情况下(lambas=9)签名长度为544字节。为了节省存储空间,可以通过puzzle_compress_cvec()函数将它们压缩到原来大小的三分之一。在使用之前,必须用puzzle_uncompress_cvec()对它们进行解压缩。

我认为压缩是错误的,因为在比较之前,我必须先解压缩每个向量。

我现在的问题是,如何处理数百万张图片,以及如何快速、高效地比较它们。我不明白“向量的切割”如何帮助我解决我的问题。

非常感谢--也许我能在这里找到一个人,它正在和lib谜libaray合作。

干杯。

EN

回答 4

Stack Overflow用户

发布于 2012-03-19 17:34:38

那么,让我们来看看他们给出的例子,并尝试展开。

假设您有一个存储与每个图像(路径、名称、描述等)相关的信息的表。在该表中,您将包含一个用于压缩签名的字段,在初始填充数据库时计算和存储该字段。让我们这样定义该表:

代码语言:javascript
运行
AI代码解释
复制
CREATE TABLE images (
    image_id INTEGER NOT NULL PRIMARY KEY,
    name TEXT,
    description TEXT,
    file_path TEXT NOT NULL,
    url_path TEXT NOT NULL,
    signature TEXT NOT NULL
);

在最初计算签名时,还需要计算签名中的一些单词:

代码语言:javascript
运行
AI代码解释
复制
// this will be run once for each image:
$cvec = puzzle_fill_cvec_from_file('img1.jpg');
$words = array();
$wordlen = 10; // this is $k from the example
$wordcnt = 100; // this is $n from the example
for ($i=0; $i<min($wordcnt, strlen($cvec)-$wordlen+1); $i++) {
    $words[] = substr($cvec, $i, $wordlen);
}

现在,您可以将这些单词放入表中,定义如下:

代码语言:javascript
运行
AI代码解释
复制
CREATE TABLE img_sig_words (
    image_id INTEGER NOT NULL,
    sig_word TEXT NOT NULL,
    FOREIGN KEY (image_id) REFERENCES images (image_id),
    INDEX (image_id, sig_word)
);

现在,在该表中插入单词所在位置的位置索引,以便您知道某个单词何时匹配它在签名中的相同位置:

代码语言:javascript
运行
AI代码解释
复制
// the signature, along with all other data, has already been inserted into the images
// table, and $image_id has been populated with the resulting primary key
foreach ($words as $index => $word) {
    $sig_word = $index.'__'.$word;
    $dbobj->query("INSERT INTO img_sig_words (image_id, sig_word) VALUES ($image_id,
        '$sig_word')"); // figure a suitably defined db abstraction layer...
}

因此,您的数据初始化后,可以相对轻松地获取具有匹配单词的图像:

代码语言:javascript
运行
AI代码解释
复制
// $image_id is set to the base image that you are trying to find matches to
$dbobj->query("SELECT i.*, COUNT(isw.sig_word) as strength FROM images i JOIN img_sig_words
    isw ON i.image_id = isw.image_id JOIN img_sig_words isw_search ON isw.sig_word =
    isw_search.sig_word AND isw.image_id != isw_search.image_id WHERE
    isw_search.image_id = $image_id GROUP BY i.image_id, i.name, i.description,
    i.file_path, i.url_path, i.signature ORDER BY strength DESC");

您可以通过添加一个需要最小HAVINGstrength子句来改进查询,从而进一步减少匹配集。

我不保证这是最有效的设置,但它应该是大致功能,以完成您正在寻找的东西。

基本上,以这种方式拆分和存储单词允许您进行粗略的距离检查,而不必对签名运行专门的函数。

票数 14
EN

Stack Overflow用户

发布于 2012-03-14 07:28:17

我以前试过玩益智游戏-就像你一样。并没有真正开始一个适当的实施。也不清楚该怎么做。(由于缺乏时间,他放弃了这个项目-所以没有真正坚持下去)

无论如何,看看现在,我会尽力提供我的理解-也许我们之间可以解决它:)

查询使用两个阶段的进程-

  1. 首先使用words表。
    1. 拿出“参考”的图像并计算出它的签名。
    2. 想出它的组成词,
    3. 请参阅words表,以查找所有可能的匹配。这可以使用数据库引擎的索引来进行高效的查询。
    4. 编译所有sig_ids的列表。(将在3中得到一些副本。)

  1. 然后查阅签名表
    1. 退出并解压缩所有可能的签名(因为您有一个预先筛选的列表,数量应该相对较少)
    2. 使用puzzle_vector_normalized_distance计算出实际的距离。
    3. 根据需要对结果进行排序和排序

(仅对签名表进行压缩)。字词仍未压缩,因此可以在其上快速查询)

词表是倒排索引的一种形式。实际上,我考虑使用https://stackoverflow.com/questions/tagged/sphinx代替words数据库表,因为这是专门设计为一个非常快速的倒排索引。

..。理论上说无论如何..。

票数 3
EN

Stack Overflow用户

发布于 2014-11-02 00:46:51

我还在php中做lib谜的工作,并且对如何从图像签名生成单词有一些疑问。贾森上面的回答似乎是对的,但我对这部分有一个问题:

代码语言:javascript
运行
AI代码解释
复制
// this will be run once for each image:
$cvec = puzzle_fill_cvec_from_file('img1.jpg');
$words = array();
$wordlen = 10; // this is $k from the example
$wordcnt = 100; // this is $n from the example
for ($i=0; $i<min($wordcnt, strlen($cvec)-$wordlen+1); $i++) {
    $words[] = substr($cvec, $i, $wordlen);
}

签名向量有544个字母长,加上上面创建的单词,我们总是只使用它的前110个字母。这意味着,如果我正确理解了这一点,我们将代表图像内容的上三分之一进行索引。

如果你读到拼图所基于的原始文章(任意类型图像的图像签名),他们会解释单词应该是"...possibly非连续的和重叠的“。我不确定它们是指非毗连和不重叠,还是指非毗连和重叠.

但是如果它们的意思是不重叠的话,我想这些词应该分布在整个签名向量中。这样做也更有意义,因为矢量是通过从左到右,从上到下的图像区域来创建的。通过在整个向量上传播单词,意味着你只考虑整个图像的上部(如果你从向量开始生成所有的单词)。

想听听你们是怎么理解这件事的。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9703762

复制
相关文章
快速理解 Vite 的依赖预构建
当我们使用 Vite 进行开发时,会进行依赖预构建,即将第三方依赖进行打包,并在开发环境下使用这些打包过的第三方依赖。
CandyTong
2023/02/24
1.5K0
快速理解 Vite 的依赖预构建
快速理解 Vite 的依赖预构建
当我们使用 Vite 进行开发时,会进行依赖预构建,即将第三方依赖进行打包,并在开发环境下使用这些打包过的第三方依赖。
CandyTong
2022/09/04
4.2K1
git更新脚本
说明 此脚本用于更新git仓库,主要用于使用ssh克隆的仓库,使用https克隆或者直接下载的不可使用此脚本进行更新,编写此贴用于保存脚本以供后用 Linux平台 Linux平台下的脚本使用的是bash shell脚本进行编写的 #! /bin/bash ######################################## #Usage: ./update comment "msg" ######################################## echo st
impressionyang
2021/05/06
8180
hbase的预region分区 脚本 经典 转
Region是表获取和分布的基本元素,由每个列族的一个Store组成。对象层级图如下:
stys35
2019/03/05
2K0
Gradle 构建脚本
Gradle提供了一种领域特定语言,目前同时支持 Groovy 和 Kotlin 。
佛系编码
2019/12/11
9230
Gradle 构建脚本
详解 Vite 依赖预构建流程
大家好,我是码农小余。我们知道,首次执行 vite 时,服务启动后会对 node_modules 模块和配置 optimizeDeps 的目标进行预构建。本节我们就去探索预构建的流程。
码农小余
2022/06/16
4.7K0
详解 Vite 依赖预构建流程
jenkins构建时环境变量问题
which: no java in (/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin) The JAVA_HOME environment variable is not defined correctly This environment variable is needed to run this program NB: JAVA_HOME should point to a JDK not a JRE
dogfei
2020/07/31
1.1K0
ansible执行带有环境变量的脚本不生效
jenkins发布时,使用ansible执行远程主机上的启动tomcat脚本发现不生效,启动tomcat的脚本中有环境变量。
HaydenGuo
2019/12/12
2.9K0
ansible执行带有环境变量的脚本不生效
构建与部署的脚本化
构建和部署系统必须一直保持活力,即这个系统不仅要从项目刚开始就开发,而且一直要持续到软件在生产环境中的维护阶段。一定要细心地设计和维护它,像对待其他源代码一样对待它,并定期使用,以便当我们需要时,可以确保它还能运行。
新亮
2022/06/30
3550
通过bat脚本配置系统环境变量
用户3519280
2023/07/08
1.4K0
[Go]解决goland terminal 环境变量不更新
在自己的电脑修改了PATH环境变量 , 但是goland terminal不更新 goland只在开机启动的时候会去读取系统的PATH环境变量 1.可以重启电脑解决 2.手动在terminal中设置一
唯一Chat
2021/04/26
3.1K0
[Go]解决goland terminal 环境变量不更新
【综述】基于Transformer的视频语言预训练
Survey: Transformer based Video-Language Pre-training
CV君
2022/04/18
1.1K0
【综述】基于Transformer的视频语言预训练
设置系统环境变量立即生效的VBS脚本
可以设置环境变量并立即生效, 与Windows批处理不同的是此脚本设置的环境变量可保证重启后一样有用. 保存以下内容为 设置环境变量.vbs , 修改要设置的环境变量名即路径即可开始运行设置. Set pSysEnv = CreateObject("WScript.Shell").Environment("System") 'Check whether a character string matches a regular expression ' ^\w+[@]\w+[.]\w+$ E
张善友
2018/01/19
1.8K0
ddns脚本更新DNSPod的解析记录
前两天dnspod突然跟新了API,说是向下兼容旧的API,但是我软路由用的别人的脚本不能正常解析.
小柒吃地瓜
2020/04/23
5K0
Python自动更新脚本
本脚本主要针对python2.6升级至python2.7.12,并且解决了升级后不能使用yum的问题。添加了ipython功能
py3study
2020/01/07
1.2K0
[Linux][bash]更新cowsay和fortune的bash脚本
上次更新fortune自定义发现召唤cowsay的bash shell脚本有小概率的bug,就是随机脚本可能超出cows列出图形的数量,这里修补下。
用户9314062
2022/05/20
6930
config.json详解【鸿蒙专题07】
上一节我在webview的实现中,用到了几个文件夹,这是单独拎出来,做一个介绍,这样的好处就是可以使你更加容易理解一个应用的开发流程。
徐建国
2022/03/30
1.5K0
config.json详解【鸿蒙专题07】
【安德鲁斯】基于脚本的数据库&quot;增量更新&quot;,如果不改变,每次更新java代码、!
1.当然,它是基于SQLiteOpenHelper.onCreate(第一个呼叫建立)、onUpdate(当所谓的升级计划)
全栈程序员站长
2022/07/18
4760
【安德鲁斯】基于脚本的数据库&quot;增量更新&quot;,如果不改变,每次更新java代码、!
数据获取脚本重大更新
之前很多脚本都有从高德获取,某个路径(公交地铁线路、OD导航等等)。由于我自己不太常用(是的,目前的状态是既不用画图,也不用做项目,平时看书写字、想事情),所以也没有体会到最后想导进ArcGIS的艰难(特别是一条路径一条路径地导入)。
Sidchen
2021/04/13
5520
数据获取脚本重大更新
golang构建项目的脚本
说来有些悲哀,最近升级了VSCode,golang插件居然无法使用了,一直无法使用,配置了大半天,还是不行,只能提交了反馈,希望能够得到回复吧。不过突然想到一个方法,就是编写脚本,然后在本地运行,虽然
陨石坠灭
2020/01/21
1.2K0
golang构建项目的脚本

相似问题

字节、字和双字数表示

22

指向双字节的指针--即4位字节--如何指向双倍,即8位字节?

13

将双字节转换为Pascal 6字节(48位)真实格式

13

32位和64位操作系统中的双字节大小

31

检测32位双字+双字进位/ C++

24
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

扫码加入开发者社群
关注 腾讯云开发者公众号

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档