python实现图像检索的三种(直方图/OpenCV/哈希法)
这篇文章主要介绍了python实现图像检索的三种(直方图/OpenCV/哈希法),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
简介:
本文介绍了图像检索的三种实现方式,均用python完成,其中前两种基于直方图比较,哈希法基于像素分布。
检索方式是:提前导入图片库作为检索范围,给出待检索的图片,将其与图片库中的图片进行比较,得出所有相似度后进行排序,从而检索结果为相似度由高到低的图片。由于工程中还包含Qt界面类、触发函数等其他部分,在该文档中只给出关键函数的代码。
开发系统:MacOS
实现方式:Qt + Python
方法一:自定义的直方图比较算法
a) 基本思路
遍历图片像素点,提取R\G\B值并进行对应的计数,得到原始直方图,但由于0-255的范围太大,因此每一个像素值的统计量均偏小,因此分别将R\G\B的256个像素值映射到0-31共32个像素值上,将像素值范围由256*3缩小到32*3。记录像素值采用的数据结构为一维数组,第1到32个值为R的像素直方图,第33到第64个值为G的像素统计,第65到96个值为B的像素统计。得到直方图后,计算待检索图的直方图和图片库中图像的直方图之间的相似性。
b) 具体实现
用到的函数:
- split_Img()
- calc_Hist(img)
- calc_Similar(h1,h2)
- calc_Similar_Split(h1,h2)
遍历图片的像素点以计算直方图:calc_Hist(img)
尝试了两种方式,第一种是对图像遍历时逐个调用getpixel()来获取R,G,B的值,但发现这种方式的速度太慢。第二种采用的是内存读取,利用load()函数一次性读取图像的像素值,然后对像素值进行遍历,该方法的速度比逐个提取更快。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
|
直方图比较 calc_Similar(h1,h2)
采用的公式是:
其中N为颜色级数,Sim越靠近1则两幅图像的相似度越高。
c) 问题和改进
简单实现直方图比较后,检索的结果并不好,和预期相比误差较大。分析原因,直方图比较主要依靠整幅图像的色彩统计来进行比较,而对像素的位置并没有很好的记录,因此会造成误判。
同时增加calc_Similar_Split(h1,h2)函数,加入分块比较的部分,计算方法是:对每个小块调用calc_Similar(h1,h2),累加计算结果,最后除以16取平均值。
测试发现效果显著提升,基于颜色相似的同时保留了形状信息。
函数如下:
1 2 3 4 5 6 7 8 9 10 |
|
#该函数用于统一图片大小为256*256,并且分割为16个块,返回值是16个局部图像句柄的数组 def split_Img(img, size = (64,64)): img = img.resize((256,256)).convert('RGB') w,h = img.size sw,sh = size return [img.crop((i,j,i+sw,j+sh)).copy() for i in xrange(0,w,sw) for j in xrange(0,h,sh)] #计算两个直方图之间的相似度,h1和h2为直方图,zip表示同步遍历 def calc_Similar(h1,h2): return sum(1 - (0 if g==s else float(abs(g-s))/max(g,s)) for g,s in zip(h1,h2)) / len(h1)
方法二:openCV库的直方图比较算法实现
openCV开源库已经集成了直方图提取、直方图均衡化以及直方图比较的功能,调用方便。为了进一步了解直方图比较的各类实现方法,利用openCV重新进行了实验。
a) 基本思路
对图片库中每个图片提取直方图并均衡化,然后调用cv库函数进行直方图比较,结果进行排序,并显示。
b) 具体实现
首先调用cv2.imread()读取图像,然后调用cv2.calcHist()计算直方图,cv2.normalize()均衡化后进入比较阶段,调用cv2.compareHist(),比较待检索图和图片库图像之间的直方图差异,然后调用DisplayTotalPics()进行显示。
关键代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
|
c) 问题与解决
openCV中的compareHist函数中提供了4中比较方法:
1.相关系数标准(method=CV_COMP_CORREL) 值越大,相关度越高,最大值1,最小值0
2.卡方系数标准(method=CV_COMP_CHISQR) 值越小,相关度越高,无上限,最小值0
3.相交系数标准(method=CV_COMP_INTERSECT)值大,相关度越高,最大9.455319,最小0
4.巴氏系数的标准(method=CV_COMP_BHATTACHARYYA) 值小,相关度越高,最大值1,最小值0
测试后选择的是method = cv2.cv.CV_COMP_INTERSECT
另外,该方法的速度很快,完全基于图像的色彩分布,但在一些情况下精度并不高。
方法三:平均哈希值比较算法实现
用到的函数:getKey(),getCode(),cmpCode()
a) 基本思路
平均哈希值的比较算法是基于像素分布的,比较对象是灰度图的图像指纹。图像指纹的计算通过比较每个图的像素值和平均像素值来计算,然后计算图像指纹之间的汉明距离,排序后得到相似图像。
b) 具体实现
具体方法是:计算进行灰度处理后图片的所有像素点的平均值,然后遍历灰度图片每一个像素,如果大于平均值记录为1,否则为0,这一步通过定义函数getCode(img)完成。接着计算编码之间的汉明距离,即一组二进制数据变为另一组数据所需的步骤数,汉明距离越小,说明图像指纹的相似度越高。计算汉明距离可以通过简单的遍历和计数来完成,函数为compCode(code1,code2),其中code1和code2为getCode得到的图像指纹。
关键函数代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
|
c) 问题与优化
我们发现在数据量大时,该方法的检索速度较慢,因此我们将图像指纹也作为图像的属性存在self.hashCode中,在importFolder时计算好,避免后续操作中的冗余重复计算。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。
python实现图像检索的三种(直方图/OpenCV/哈希法)相关推荐
- Python 发送 email 的三种方式
Python发送email的三种方式,分别为使用登录邮件服务器.使用smtp服务.调用sendmail命令来发送三种方法 本文原文自米扑博客:Python 发送 email 的三种方式 Python发 ...
- 测试Python下载图片的三种方法
简 介: 通过Python软件包对网络URL图片链接进行下载,可以加快后期处理.本文测试了urllib, request两个软件包对图片进行下载效果.如果图片原网页有了防止下载机制,是无法下载图片. ...
- python学习音频-详解python播放音频的三种方法
第一种 使用pygame模块 pygame.mixer.init() pygame.mixer.music.load(self.wav_file) pygame.mixer.music.set_vol ...
- python可以播放音乐吗_详解python播放音频的三种方法
第一种 使用pygame模块 pygame.mixer.init() pygame.mixer.music.load(self.wav_file) pygame.mixer.music.set_vol ...
- python如何安装matplotlib_详解python安装matplotlib库三种失败情况
(可能只有最后一句命令有用,可能全篇都没用) (小白方法,可能只适用于本人情况) 安装matplotlib时,出现的三种失败情况 1.read timed out 一开始我在pycharm终端使用pi ...
- Python语言学习:三种随机函数random.seed()、numpy.random.seed()、set_random_seed()及random_normal的简介、使用方法(固定种子)详细攻略
Python语言学习:三种随机函数random.seed().numpy.random.seed().set_random_seed()及random_normal的简介.使用方法(固定种子)之详细攻 ...
- Python实现二叉树的三种深度遍历方法!
python代码实现了二叉树,这次将会实现二叉树的几种遍历方法,来更好的解析二叉树的结构特点.分别是一种广度遍历,和三种深度遍历方法:先序遍历,中序遍历,后序遍历.下面是代码实现: 1.先序遍历 遍历 ...
- python调用cmd命令释放端口_详解python调用cmd命令三种方法
目前我使用到的python中执行cmd的方式有三种 使用os.system("cmd") 该方法在调用完shell脚本后,返回一个16位的二进制数,低位为杀死所调用脚本的信号号码, ...
- python实现单例模式的三种方式及相关知识解释
python实现单例模式的三种方式及相关知识解释 模块模式 装饰器模式 父类重写new继承 单例模式作为最常用的设计模式,在面试中很可能遇到要求手写.从最近的学习python的经验而言,singlet ...
- 【Python】Python创建虚拟环境的三种方式
Python创建虚拟环境的三种方式比较 Python创建虚拟环境的三种方式 首先:为什么需要虚拟环境? Pipenv vs Virtualenv vs Conda 1. Virtualenv 2. P ...
最新文章
- 使用struts2+JQuery实现的简单的ajax例子
- 织梦首页常用调用标签
- Guava库学习:学习Collections(二)Lists
- python朋友圈为什么这么火-用Python发一个高逼格的朋友圈「附代码」
- 最长公共子序列Java代码实现
- 在word中的公式以代码形式体现在web上的方法
- 操作系统(十四)进程调度的时机、调度方式
- 上海人工智能实验室牛雅哲:通用决策AI平台的开拓创新之路
- python中减法运算函数_详解 Python 的二元算术运算,为什么说减法只是语法糖?...
- python中的线程之semaphore信号量
- C++ —— C++程序编译的四个过程
- mariadb不能导入与mysql可以,mysql/mariadb知识点总结(12):insert语句总结
- Python开发利器PyCharm 2.7附注册码
- webstrom 里面使用github
- NotePad++ 配置lua语法检查
- 如何用15天摸清一个新的行业?
- Java单词查询小程序
- 葛道辉,李洪升,张亮,等. 轻量级神经网络架构综述
- emc4012光纤直连服务器,Dell EMC PowerVault ME4012存储
- 查看JS代码中\x68等加密数据内容的解决办法