zoukankan      html  css  js  c++  java
  • 相似图片搜索的原理

    谷歌几年前就在首页开放“相似图片搜索”,对图片搜索的原理不甚了解,查阅了资料,现在记录下备忘。

    要判断某两张图片是否相似,本质来说就是看他们的特征是否一致。就像我们使用指纹来区分不同的人一样,如果我们能提取到图片的指纹,那么区分图像是否相似将变得很简单。如果我们能将图片的特征量化成一个字符串(姑且称为特征码吧),这个特征码就可以作为图片的指纹,通过分析两个特征码之间的差异,就能得出是否相似的结论。最重要的就是要得到图片的特征码

    方案一:

    一、缩小尺寸
    将图片缩小到8×8的尺寸,总共64个像素。这一步的作用是去除图片的细节,只保留结构、明暗等基本信息,摒弃不同尺寸、比例带来的图片差异。

    二、简化色彩
    将缩小后的图片,转为64级灰度。也就是说,所有像素点总共只有64种颜色。

    三、计算平均值
    计算所有64个像素的灰度平均值。

    四、比较像素的灰度
    将每个像素的灰度,与平均值进行比较。大于或等于平均值,记为1;小于平均值,记为0。

    五、计算特征码
    将上一步的比较结果,组合在一起,就构成了一个64位的整数,这就是这张图片的指纹。

    得到指纹以后,就可以对比不同的图片,看看64位中有多少位是不一样的。在理论上,这等同于计算Hamming distance。如果不相同的数据位不超过5,就说明两张图片很相似;如果大于10,就说明这是两张不同的图片。

    方案二:

    每张图片都可以生成颜色分布的直方图。如果两张图片的直方图很接近,就可以认为它们很相似。

    任何一种颜色都是由红绿蓝三原色(RGB)构成的,如果每种原色都可以取256个值,那么整个颜色空间共有1600万种颜色。针对这1600万种颜色比较直方图,计算量实在太大了,因此需要采用简化方法。可以将0~255分成四个区:0~63为第0区,64~127为第1区,128~191为第2区,192~255为第3区。这意味着红绿蓝分别有4个区,总共可以构成64种组合。

    任何一种颜色必然属于这64种组合中的一种,这样就可以统计每一种组合包含的像素数量。

    上图是某张图片的颜色分布表,将表中最后一栏提取出来,组成一个64维向量,这个向量就是这张图片的特征码。

    方案三:

    除了颜色构成,还可以从比较图片内容的相似性入手。

    首先,将原图转成一张较小的灰度图片,假定为50×50像素。然后,确定一个阈值,将灰度图片转成黑白图片。如果两张图片很相似,它们的黑白轮廓应该是相近的。于是,问题就变成了,第一步如何确定一个合理的阈值,正确呈现照片中的轮廓?

    显然,前景色与背景色反差越大,轮廓就越明显。这意味着,如果我们找到一个值,可以使得前景色和背景色各自的”类内差异最小”,或者”类间差异最大”,那么这个值就是理想的阈值。

  • 相关阅读:
    思念
    空白
    curl json string with variable All In One
    virtual scroll list All In One
    corejs & RegExp error All In One
    socket.io All In One
    vue camelCase vs PascalCase vs kebabcase All In One
    element ui 表单校验,非必填字段校验 All In One
    github 定时任务 UTC 时间不准确 bug All In One
    input range & color picker All In One
  • 原文地址:https://www.cnblogs.com/ykzou/p/6941674.html
Copyright © 2011-2022 走看看