python Opencv计算图像相似度过程解析


Posted in Python onDecember 03, 2019

这篇文章主要介绍了python Opencv计算图像相似度过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下

一、相关概念

一般我们人区分谁是谁,给物品分类,都是通过各种特征去辨别的,比如黑长直、大白腿、樱桃唇、瓜子脸。王麻子脸上有麻子,隔壁老王和儿子很像,但是儿子下巴涨了一颗痣和他妈一模一样,让你确定这是你儿子。
还有其他物品、什么桌子带腿、镜子反光能在里面倒影出东西,各种各样的特征,我们通过学习、归纳,自然而然能够很快识别分类出新物品。

而没有学习训练过的机器就没办法了。

但是图像是一个个像素点组成的,我们就可以通过不同图像之间这些差异性就判断两个图的相似度了。其中颜色特征是最常用的,(其余常用的特征还有纹理特征、形状特征和空间关系特征等)
其中又分为

  • 直方图
  • 颜色集
  • 颜色矩
  • 聚合向量
  • 相关图

1、直方图

在Python中利用opencv中的calcHist()方法获取其直方图数据,返回的结果是一个列表,使用matplotlib,画出了这两张图的直方图数据图

import cv2
import numpy
from matplotlib import pyplot
if __name__ == '__main__':
  imgobj1 = cv2.imread('pho.jpg')
  imgobj2 = cv2.imread('ph1.jpg')
  hist1 = cv2.calcHist([imgobj1], [0], None, [256], [0.0, 255.0])
  hist2 = cv2.calcHist([imgobj2], [0], None, [256], [0.0, 255.0])
  pyplot.plot(range(256), hist1, 'r')
  pyplot.plot(range(256), hist2, 'b')
  pyplot.show()
  cv2.imshow('img1',imgobj1)
  cv2.imshow('img2',imgobj2)
  cv2.waitKey(0)

python Opencv计算图像相似度过程解析

1.2 灰度图及作用

灰度图是只含有黑白颜色,和0~255亮度等级的图片。灰度图具有存储小,其亮度值就是256色调色板索引号,从整幅图像的整体和局部的色彩以及亮度等级分布特征来看,灰度图描述与彩色图的描述是一致的特点。因此很多真彩色图片的分析,第一步就是转换为灰度图,然后再进行分析。

真彩色,因为是24位,2(^8) * 2(^8)* 2(^8) = 16777216种颜色,需要调色板16777216 * 4byte字节的空间也就是64MB的调色板空间,所以真彩色是不用调色板的。

例如视频目标跟踪和识别时,第一步就是要转换为灰度图。现有的成熟分析算法多是基于灰度图像的,灰度图像综合了真彩色位图的RGB各通道的信息。

(一):单通道图,

俗称灰度图,每个像素点只能有有一个值表示颜色,它的像素值在0到255之间,0是黑色,255是白色,中间值是一些不同等级的灰色。(也有3通道的灰度图,3通道灰度图只有一个通道有值,其他两个通道的值都是零)。

(二):三通道图,每个像素点都有3个值表示 ,所以就是3通道。也有4通道的图。例如RGB图片即为三通道图片,RGB色彩模式是工业界的一种颜色标准,是通过对红(R)、绿(G)、蓝(B)三个颜色通道的变化以及它们相互之间的叠加来得到各式各样的颜色的,RGB即是代表红、绿、蓝三个通道的颜色,这个标准几乎包括了人类视力所能感知的所有颜色,是目前运用最广的颜色系统之一。总之,每一个点由三个值表示。

直方图判断相似度,如上图,就算重合度即可

1.3 图像指纹和汉明距离

图像指纹:

和人的指纹一样,是身份的象征,而图像指纹简单点来讲,就是将图像按照一定的哈希算法,经过运算后得出的一组二进制数字。

汉明距离:

假如一组二进制数据为101,另外一组为111,那么显然把第一组的第二位数据0改成1就可以变成第二组数据111,所以两组数据的汉明距离就为1

简单点说,汉明距离就是一组二进制数据变成另一组数据所需的步骤数,显然,这个数值可以衡量两张图片的差异,汉明距离越小,则代表相似度越高。汉明距离为0,即代表两张图片完全一样。

1.3.1 平均哈希

此算法是基于比较灰度图每个像素与平均值来实现的

一般步骤:

  • 缩放图片,一般大小为8*8,64个像素值。
  • 转化为灰度图
  • 计算平均值:计算进行灰度处理后图片的所有像素点的平均值,直接用numpy中的mean()计算即可。
  • 比较像素灰度值:遍历灰度图片每一个像素,如果大于平均值记录为1,否则为0.
  • 得到信息指纹:组合64个bit位,顺序随意保持一致性。
  • 最后比对两张图片的指纹,获得汉明距离即可。
import cv2
import numpy as np

img1 = cv2.imread("/absPath.png")
img2 = cv2.imread("./x.png")

#调整到8*8
img1 = cv2.resize(img1,(8,8))
img2 = cv2.resize(img2,(8,8))

#转化为灰度图
gray1 = cv2.cvtColor(img1,cv2.COLOR_BGR2GRAY)
gray2 = cv2.cvtColor(img2,cv2.COLOR_BGR2GRAY)

#获取哈希
hash1 = getHash(gray1)
hash2 = getHash(gray2)

ret = Hamming_distance(hash1,hash2)


# 输入灰度图,返回hash
def getHash(image):
  avreage = np.mean(image) #计算像素平均值
  hash = []
  for i in range(image.shape[0]):
    for j in range(image.shape[1]):
      if image[i, j] > avreage:
        hash.append(1)
      else:
        hash.append(0)
  return hash
# 计算汉明距离
def Hamming_distance(hash1, hash2):
  num = 0
  for index in range(len(hash1)):
    if hash1[index] != hash2[index]:
      num += 1
  return num

1.3.2 感知哈希及d哈希

感知哈希算法(pHash)

平均哈希算法过于严格,不够精确,更适合搜索缩略图,为了获得更精确的结果可以选择感知哈希算法,它采用的是DCT(离散余弦变换)来降低频率的方法

一般步骤:

  • 缩小图片:32 * 32是一个较好的大小,这样方便DCT计算
  • 转化为灰度图
  • 计算DCT:利用Opencv中提供的dct()方法,注意输入的图像必须是32位浮点型,所以先利用numpy中的float32进行转换
  • 缩小DCT:DCT计算后的矩阵是32 * 32,保留左上角的8 * 8,这些代表的图片的最低频率
  • 计算平均值:计算缩小DCT后的所有像素点的平均值。
  • 进一步减小DCT:大于平均值记录为1,反之记录为0.
  • 得到信息指纹:组合64个信息位,顺序随意保持一致性。
  • 最后比对两张图片的指纹,获得汉明距离即可。

dHash算法

相比pHash,dHash的速度要快的多,相比aHash,dHash在效率几乎相同的情况下的效果要更好,它是基于渐变实现的。

步骤:

缩小图片:收缩到9*8的大小,以便它有72的像素点

转化为灰度图

计算差异值:dHash算法工作在相邻像素之间,这样每行9个像素之间产生了8个不同的差异,一共8行,则产生了64个差异值
获得指纹:如果左边的像素比右边的更亮,则记录为1,否则为0.
最后比对两张图片的指纹,获得汉明距离即可。

dHash:

#差值感知算法
def dhash(image1,image2):
  image1 = cv2.resize(image1,(9,8))
  image2 = cv2.resize(image2,(9,8))
  gray1 = cv2.cvtColor(image1,cv2.COLOR_BGR2GRAY) #切换至灰度图
  gray2 = cv2.cvtColor(image2,cv2.COLOR_BGR2GRAY)
  hash1 = dhashcaulate(gray1)
  hash2 = dhashcaulate(gray2)
  return Hamming_distance(hash1,hash2)
 
def dhashcaulate(gray):
  hash_str = ''
  for i in range(8):
    for j in range(8):
      if gray[i, j] > gray[i, j + 1]:
        hash_str = hash_str + '1'
      else:
        hash_str = hash_str + '0'
  return hash_str

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
学习python处理python编码问题
Mar 13 Python
Python中模拟enum枚举类型的5种方法分享
Nov 22 Python
python使用BeautifulSoup分页网页中超链接的方法
Apr 04 Python
python中zip和unzip数据的方法
May 27 Python
Python3实现发送QQ邮件功能(html)
Dec 15 Python
python基于物品协同过滤算法实现代码
May 31 Python
Python爬虫抓取技术的一些经验
Jul 12 Python
tensorflow实现在函数中用tf.Print输出中间值
Jan 21 Python
浅谈python 调用open()打开文件时路径出错的原因
Jun 05 Python
python中常见错误及解决方法
Jun 21 Python
Python 程序报错崩溃后如何倒回到崩溃的位置(推荐)
Jun 23 Python
使用Python+OpenCV进行卡类型及16位卡号数字的OCR功能
Aug 30 Python
django 中使用DateTime常用的时间查询方式
Dec 03 #Python
在django中自定义字段Field详解
Dec 03 #Python
python 实现单通道转3通道
Dec 03 #Python
python3 图片 4通道转成3通道 1通道转成3通道 图片压缩实例
Dec 03 #Python
python3实现elasticsearch批量更新数据
Dec 03 #Python
python实现从wind导入数据
Dec 03 #Python
python 导入数据及作图的实现
Dec 03 #Python
You might like
phpMyAdmin2.11.6安装配置方法
2008/08/24 PHP
使用PHP备份MYSQL数据的多种方法
2014/01/15 PHP
PHP开发微信支付的代码分享
2014/05/25 PHP
PHP使用stream_context_create()模拟POST/GET请求的方法
2016/04/02 PHP
PHP性能分析工具xhprof的安装使用与注意事项
2017/12/19 PHP
thinkPHP+LayUI 流加载实现功能
2019/09/27 PHP
如何取得中文输入的真实长度?
2006/06/24 Javascript
理解Javascript_01_理解内存分配原理分析
2010/10/11 Javascript
DB.ASP 用Javascript写ASP很灵活很好用很easy
2011/07/31 Javascript
Textbox控件注册回车事件及触发按钮提交事件具体实现
2013/03/04 Javascript
JS Replace()的高级使用方法介绍
2013/06/29 Javascript
如何在MVC应用程序中使用Jquery
2014/11/17 Javascript
JavaScript的History API使搜索引擎抓取AJAX内容
2015/12/07 Javascript
微信小程序 火车票查询实例讲解
2016/10/17 Javascript
Vue.js第二天学习笔记(vue-router)
2016/12/01 Javascript
微信小程序实现多个按钮toggle功能的实例
2017/06/13 Javascript
详谈Node.js之操作文件系统
2017/08/29 Javascript
基于$.ajax()方法从服务器获取json数据的几种方式总结
2018/01/31 Javascript
Rollup处理并打包JS文件项目实例代码
2018/05/31 Javascript
JavaScript设计模式之责任链模式实例分析
2019/01/16 Javascript
js实现点击按钮随机生成背景颜色
2020/09/05 Javascript
梳理一下vue中的生命周期
2020/12/30 Vue.js
python魔法方法-属性访问控制详解
2016/07/25 Python
Python实现动态加载模块、类、函数的方法分析
2017/07/18 Python
Windows环境下python环境安装使用图文教程
2018/03/13 Python
四种会话跟踪技术
2015/05/20 面试题
化学专业毕业生自荐信
2013/11/15 职场文书
校长先进事迹材料
2014/02/01 职场文书
消防安全汇报材料
2014/02/08 职场文书
招股说明书范本
2014/05/06 职场文书
2014世界杯球队球队口号
2014/06/05 职场文书
市政工程技术专业自荐书
2014/07/06 职场文书
2016公务员年度考核评语
2015/12/01 职场文书
MySQL 存储过程的优缺点分析
2021/05/20 MySQL
JavaScript前端面试扁平数据转tree与tree数据扁平化
2022/06/14 Javascript
java实现web实时消息推送的七种方案
2022/07/23 Java/Android