CPR的最邻图片搜索
CPR找相似图片的核心思想
一句话概括:把每张图片的特征转换成一个”条形统计图”,然后对比统计图的形状,形状越像,图片就越相似。
此博客是由ai整理得到 并非本人手写!仅做临时复习使用!
具体步骤(三步走)
第一步:把特征变成”篮子”(Codebook)
想象你有一堆水果,你想统计每种水果有多少个。但你不知道有多少种水果,所以你先准备几个”篮子”,比如100个篮子。
- Codebook就是这100个篮子
- 每个篮子代表一种”特征模式”(比如某种纹理、某种形状)
- 所有训练图片的特征会被分配到这100个篮子里,每个篮子会聚集相似的特征
类比:就像你去超市,货架上预先摆放了100类商品,所有新来的商品都要归类到这100类里。
第二步:把图片分成小块,每个块统计篮子里的数量(BlockWiseHistogramEncoder)
现在有一张图片,你不能只看整张,要把它切成小块(比如8×8=64块)。
对每一小块:
- 提取这块的特征
- 看这个特征最像哪个篮子,就把它放进那个篮子
- 统计这个小块里每个篮子有多少个特征
结果:每小块得到一个”条形统计图”,图上有100根柱子,每根柱子代表一个篮子的特征数量。
举例:
- 第1小块:篮子1有5个特征,篮子2有3个特征,篮子3有0个…
- 第2小块:篮子1有2个特征,篮子2有7个特征…
- …以此类推64个小块
最终:整张图片 = 64个小块 × 100根柱子 = 一个三维的统计图(64×100的矩阵)
第三步:对比统计图找相似图片(检索)
现在你有:
- 训练集里每张图片都有一个64×100的统计图
- 新来一张测试图片,也算出它的64×100统计图
怎么找最相似的?
方法有两种:
方法1:KL散度(CPR主要用这个)
- 对比两个统计图的”形状差异”
- KL散度越小,说明两个统计图越像
- 就像对比两张柱状图,哪个柱子高哪个柱子低,越接近就越相似
方法2:欧氏距离
- 简单粗暴,直接计算两个统计图上每个点的距离
- 距离越近,越相似
CPR的小技巧:
- 不是所有64个块都用来对比,只对比其中80%最相似的块(l_ratio=4/5)
- 这样可以忽略掉那些差异太大的块,避免噪声干扰
为什么要这样做?
优点1:更鲁棒
- 统计图看的是”整体分布”,不是单个特征的具体数值
- 即使图片有点光照变化、小干扰,统计图形状也不会变太大
优点2:保留空间信息
- 把图片分块,每个块单独统计
- 所以能知道”哪一块像哪一块”,而不是整张图片混在一起
优点3:计算高效
- 统计图(64×100)比原始特征(可能几万维)小很多
- 对比统计图很快
整个流程图解
1 | 原始图片 |
关键参数解释
| 参数 | 含义 | 作用 |
|---|---|---|
n_clusters |
篮子数量(100) | 决定统计图的细致程度 |
S |
分块数量(8×8) | 决定空间信息的保留程度 |
d_method |
对比方法(’kl’或’euc’) | 决定相似度计算方式 |
l_ratio |
对比比例(4/5) | 过滤掉不相似的块 |
和你的想法的关系
你的想法是”找最相似的整张图片”,CPR做的就是这件事,只是它用统计图来表示整张图片,而不是直接用原始特征。
区别:
- 简单方法:直接用特征向量对比(比如用FAISS)
- CPR方法:用统计图对比(更鲁棒,但复杂一点)
如果你用CPR的方法,你需要:
- 先用训练集训练出Codebook(聚类中心)
- 为每张训练图片算出统计图,存起来
- 测试时,算出测试图片的统计图,和训练集的统计图对比
这样理解清楚了吗?还有哪一步想让我再详细解释?