利用python进行识别相似图片
转自:https://segmentfault.com/a/1190000004467183
利用python进行识别相似图片(一)
文章简介
在网上看到python做图像识别的相关文章后,真心感觉python的功能实在太强大,因此将这些文章总结一下,建立一下自己的知识体系。
当然了,图像识别这个话题作为计算机科学的一个分支,不可能就在本文简单几句就说清,所以 本文只作基本算法的科普向 。
如有错误,请多包涵和多多指教。
参考的文章和图片来源会在底部一一列出。
以及本篇文章所用的代码都会在底下给出github地址。
安装相关库
python用作图像处理的相关库主要有 openCV
(C++编写,提供了python语言的接口), PIL
,但由于PIL很早就停了,所以不支持python3.x,所以建议使用基于PIL的 pillow
,本文也是在python3.4和pillow的环境下进行实验。
pillow下载地址
PIL的下载地址
openCV的官网
至于opencv,在做人脸识别的时候会用到,但本文不会涉及到, 在本专栏的后续中会谈及openCV的人脸识别和基于此的python图片爬虫,有兴趣的朋友可以关注本专栏。
相关背景
要识别两张相似图像,我们从感性上来谈是怎么样的一个过程?首先我们会区分这两张相片的类型,例如是风景照,还是人物照。风景照中,是沙漠还是海洋,人物照中,两个人是不是都是国字脸,还是瓜子脸(还是倒瓜子脸……哈哈……)。
那么从机器的角度来说也是这样的,先识别图像的特征,然后再相比。
很显然,在没有经过训练的计算机(即建立模型),那么计算机很难区分什么是海洋,什么是沙漠。但是计算机很容易识别到图像的像素值。
因此,在图像识别中, 颜色特征
是最为常用的。(其余常用的特征还有 纹理特征
、 形状特征
和 空间关系特征
等)
其中又分为
直方图
颜色集
颜色矩
聚合向量
相关图
直方图计算法
这里先用直方图进行简单讲述。
先借用一下 恋花蝶
的图片,
从肉眼来看,这两张图片大概也有八成是相似的了。
在python中可以依靠 Image
对象的 histogram()
方法获取其直方图数据,但这个方法返回的结果是一个列表,如果想得到下图可视化数据,需要另外使用 matplotlib
,这里因为主要介绍算法思路, matplotlib
的使用这里不做介绍。
是的,我们可以明显的发现,两张图片的直方图是近似重合的。所以利用直方图判断两张图片的是否相似的方法就是,计算其直方图的重合程度即可。
计算方法如下:
其中gi和si是分别指两条曲线的第i个点。
最后计算得出的结果就是就是其相似程度。
不过,这种方法有一个明显的弱点,就是他是按照颜色的全局分布来看的,无法描述颜色的局部分布和色彩所处的位置。
也就是假如一张图片以蓝色为主,内容是一片蓝天,而另外一张图片也是蓝色为主,但是内容却是妹子穿了蓝色裙子,那么这个算法也很可能认为这两张图片的相似的。
缓解这个弱点有一个方法就是利用 Image
的 crop
方法把图片等分,然后再分别计算其相似度,最后综合考虑。
图像指纹与汉明距离
在介绍下面其他判别相似度的方法前,先补充一些概念。第一个就是 图像指纹
图像指纹和人的指纹一样,是身份的象征,而图像指纹简单点来讲, 就是将图像按照一定的哈希算法,经过运算后得出的一组二进制数字。
说到这里,就可以顺带引出 汉明距离 的概念了。
假如一组二进制数据为 101
,另外一组为 111
,那么显然把第一组的第二位数据 0
改成 1
就可以变成第二组数据 111
,所以两组数据的汉明距离就为 1
简单点说,汉明距离就是 一组二进制数据变成另一组数据所需的步骤数 ,显然,这个数值可以 衡量两张图片的差异 ,汉明距离越小,则代表相似度越高。汉明距离为0,即代表两张图片完全一样。
如何计算得到汉明距离,请看下面三种哈希算法
平均哈希法(aHash)
此算法是基于比较灰度图每个像素与平均值来实现的
一般步骤
1.缩放图片,可利用
Image
对象的resize(size)
改变,一般大小为8*8,64个像素值。2.转化为灰度图转灰度图的算法。
1.浮点算法:Gray=Rx0.3+Gx0.59+Bx0.11
2.整数方法:Gray=(Rx30+Gx59+Bx11)/100
3.移位方法:Gray =(Rx76+Gx151+Bx28)>>8;
4.平均值法:Gray=(R+G+B)/3;
5.仅取绿色:Gray=G;
在 python
中,可用 Image
的对象的方法 convert('L')
直接转换为灰度图
3.计算平均值:计算进行灰度处理后图片的所有像素点的平均值。
4.比较像素灰度值:遍历灰度图片每一个像素,如果大于平均值记录为1,否则为0.
5.得到信息指纹:组合64个bit位,顺序随意保持一致性。
最后比对两张图片的指纹,获得汉明距离即可。
感知哈希算法(pHash)
平均哈希算法过于严格,不够精确,更适合搜索缩略图,为了获得更精确的结果可以选择感知哈希算法,它采用的是DCT(离散余弦变换)来降低频率的方法
一般步骤:
缩小图片:
32 * 32
是一个较好的大小,这样方便DCT计算转化为灰度图:把缩放后的图片转化为256阶的灰度图。(具体算法见平均哈希算法步骤)
计算DCT:DCT把图片分离成分率的集合
缩小DCT:DCT计算后的矩阵是
32 * 32
,保留左上角的8 * 8
,这些代表的图片的最低频率计算平均值:计算缩小DCT后的所有像素点的平均值。
进一步减小DCT:大于平均值记录为1,反之记录为0.
得到信息指纹:组合64个信息位,顺序随意保持一致性。
最后比对两张图片的指纹,获得汉明距离即可。
这里给出别人的DCT的介绍和计算方法(离散余弦变换的方法)
DCT的维基百科
luoweifu的博客
dHash算法
相比pHash,dHash的速度要快的多,相比aHash,dHash在效率几乎相同的情况下的效果要更好,它是基于渐变实现的。
步骤:
缩小图片:收缩到9*8的大小,一遍它有72的像素点
转化为灰度图:把缩放后的图片转化为256阶的灰度图。(具体算法见平均哈希算法步骤)
计算差异值:dHash算法工作在相邻像素之间,这样每行9个像素之间产生了8个不同的差异,一共8行,则产生了64个差异值
获得指纹:如果左边的像素比右边的更亮,则记录为1,否则为0.最后比对两张图片的指纹,获得汉明距离即可。
总结
这几种算法是识别相似图像的基础,显然,有时两图中的人相似比整体的颜色相似更重要,所以我们有时需要进行人脸识别,然后在脸部区进行局部哈希,或者进行其他的预处理再进行哈希,这里涉及其他知识本文不作介绍。
下一次将讲述利用opencv和以训练好的模型来进行人脸识别。
本文算法的实现在下面,点一下下面的连接就好
我的github仓库
利用python进行识别相似图片(二)
前言
和网上各种首先你要有一个女朋友
的系列一样,想进行人脸判断,首先要有脸
,
只要能靠确定人脸的位置,那么进行两张人脸是否相似的操作便迎刃而解了。
所以本篇文章着重讲述如何利用openCV定位人脸。
上一篇文章的地址:
利用python进行识别相似图片(一)
安装openCV
opencv官网
在进行下一步操作时,我们需要安装openCV,本来安装openCV的步骤跟平常安装其他模块一样,而然由于python的历史原因(用过都懂……),弄得一点都不友好。
先说一下,python2.7的用户,可以直接在openCV的官网上直接下载,然后在openCV的build\python
的目录下,根据自己的情况,选择x86
,x64
下的cv2.pyd
放到你python的安装目录的
\Lib\site-packages\
下。
至于python3.4的用户,即有点特别。你可以在StackOverFlow找到这样
和这样的答案,但我们不要这么麻烦。
进入这个网站,下载openCV相关whl
文件,例如
opencv_python-3.1.0-cp35-none-win_amd64.whl
然后再对应目录下使用pip install opencv_python-3.1.0-cp35-none-win_amd64.whl
命令即可
安装完成后,可以在python的命令行下测试。
import cv2
如果没有报错的话,恭喜你安装成功。
不过无论是哪个版本的用户,在python上使用openCV都需要先安装numpy这个模块。
numpy
人脸识别的原理
opencv的人脸识别是基于了haar特征
,关于什么叫haar特征
,足以开另外一篇文章说明了,碍于篇幅,这里不做介绍。
opencv提供已经训练好的数据写成了xml文件,放在了opencv\sources\data\haarcascades
的目录下。
如果只是安装了opencv_python-3.1.0-cp35-none-win_amd64.whl
的,可以在我的github上,下载cvdata
里面的内容
,地址会在文章底部给出。
除了人脸识别的数据外,还有人眼,上半身,下半身……等人体特征的数据,观察xml文件的命名,不难见名知义。
接下来会介绍如何利用这个已经训练好的数据,如果仍对haar
模型感兴趣,可以参考以下地址。
zouxy09的专栏
如何使用训练好的数据
先讲关于openCV基本的一些操作。全部具体代码,请查看我的github。
读入一张图片
cv2.imread(path)
如果你用type()
把其返回值的类型是numpy.ndarray
。
而同样,numpy.asarray(Image)
返回的亦是numpy.ndarray
对象,为什么强调这两点?
cv2.imread(path)
不能读取中文路径,若路径中含有中文字符,其会返回None
在后面的操作中,包括是切割图片(人脸部分),再进行局部哈希,比较相似度,
等等都是用Image
对象进行操作,如果再用Image.open()
读入图片未免显得麻烦。
所以干脆统一用Image.open()
打开图片,再用numpy.asarray(Image)
转化即可。
需要注意有一个不同的地方是虽然其返回的也是三维数组,但在第三维,即某个坐标下的RGB值,两个矩阵的顺序是反的,但只要另外编写一个小函数将其反转即可。
载入xml数据
face_cascade = cv2.CascadeClassifier(xml_path)
将图片灰度化
if img.ndim == 3:gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)else:gray = img # 如果img维度为3,说明不是灰度图,先转化为灰度图gray,如果不为3,也就是2,原图就是灰度图
img是之前读入的三维数组,虽然灰度图可以用Image
对象的convert('L')
完成,但由于不确定
opencv的处理方法是否和该方法一样,所以还是用opencv自己的方法进行处理比较好。
获取人脸坐标
faces = face_cascade.detectMultiScale(gray, scaleFactor=1.1, minNeighbors=3,
minSize=(10,10),flags=cv2.CASCADE_SCALE_IMAGE)
scale_factor:被检测对象的尺度变化。尺度越大,越容易漏掉检测的对象,但检测速度加快;尺度越小,检测越细致准确,但检测速度变慢。
min_neighbors:数值越大,检测到对象的条件越苛刻;反之检测到对象的条件越宽松;
minSize:检测对象的大小
该方法返回的是一个列表,每个列表元素是长度为四的元组,分别脸部的左上角的x,y值,脸部区域的宽度和高度。
下一步操作
通过上述的方法,我们就已经获取到人脸的位置,下一步你可以通过ImageDraw
`对象进行绘图,框出人脸的位置。
同样,你也可以使用Image
的crop
方法把人脸部分提取出来,然后进行局部哈希,
通过上一篇文章提及的算法,比较两者的相似度。
两种操作分别在我的github中实现了,请参考我的github中face1.py
,和face2.py
两个python文件。
写一只具有识别能力的图片爬虫
在上一篇文章中,我说了会应用这些算法做成以只具有识别能力的图片爬虫,然现在我也确实是在做但考虑到作为核心的图片识别和人脸识别的部分我已经写成文章分享出来,其余部分就是想写其他爬虫一样而已,所以我决定看看这两篇文章的反响后再决定是否继续该系列,把图片爬虫的制作过程和大家分享一下。
总结
鉴于个人实力有限,本文未能详细说明人脸识别的原理,但总结了如何利用已经训练好的数据进行人脸识别,希望能帮到有需要的朋友。
如有不足之处,欢迎提出。
本文涉及内容的详细代码在下面的github地址。
我的github仓库
利用python进行识别相似图片相关推荐
- 利用python进行识别相似图片(二)
前言 和网上各种首先你要有一个女朋友的系列一样,想进行人脸判断,首先要有脸, 只要能靠确定人脸的位置,那么进行两张人脸是否相似的操作便迎刃而解了. 所以本篇文章着重讲述如何利用openCV定位人脸. ...
- python图片-利用python进行识别相似图片(一)
文章简介 在网上看到python做图像识别的相关文章后,真心感觉python的功能实在太强大,因此将这些文章总结一下,建立一下自己的知识体系. 当然了,图像识别这个话题作为计算机科学的一个分支,不可能 ...
- python识图找图_利用python进行识别相似图片(二)
前言 和网上各种首先你要有一个女朋友的系列一样,想进行人脸判断,首先要有脸, 只要能靠确定人脸的位置,那么进行两张人脸是否相似的操作便迎刃而解了. 所以本篇文章着重讲述如何利用openCV定位人脸. ...
- python识图打怪_利用python进行识别相似图片(二)
前言 和网上各种首先你要有一个女朋友的系列一样,想进行人脸判断,首先要有脸, 只要能靠确定人脸的位置,那么进行两张人脸是否相似的操作便迎刃而解了. 所以本篇文章着重讲述如何利用openCV定位人脸. ...
- 利用Python实现自动批量图片格式转换
文章目录 利用Python实现自动批量图片格式转换 0.背景 1.简单思路 2.进一步改进 3.最终版本 4.总结 利用Python实现自动批量图片格式转换 0.背景 在一个漫画网站下载了一些图片,但 ...
- 利用Python批量识别电子账单数据
文章目录 一.前言 二.调用Baidu aip识别 三.批量识别电子账单 一.前言 有一定数量类似如下截图所示的账单,利用 Python 批量识别电子账单数据,并将数据保存到Excel. 百度智能云接 ...
- python账单查询软件_利用Python批量识别电子账单数据的方法
这篇文章主要介绍了利用Python批量识别电子账单数据的方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下 一.前言 有一定数量类似如下截图所示的账单,利用 ...
- python如何识别身份证图片上的证件号码及姓名
要在Python中识别身份证图片上的号码和姓名,可以使用OCR(光学字符识别)技术.OCR技术可以将图像中的文本转换为计算机可读的文本格式. 以下是一个示例代码,使用tesseract OCR库和Op ...
- python抓取网站图片_利用python抓取网站图片
看了网上关于python抓取网站图片的例子,所以自己也尝试着写一个,但是发现这个网站的src不是标准的路径,需要自己添加前面的目录地址,尝试了几次也不成功,所以希望有经验的朋友指导下. 本人是初学者, ...
- python ppt 图片_利用Python将PPT转换为图片并合成长图
最近因为某些需求需要将PPT转换为图片并合并成预览图,于是第一时间就想到了用python解决问题,过程中参考了一位老哥写的文章,链接如下.Python行家:用Python实现ppt转化图片(附带长图合 ...
最新文章
- Java程序设计进阶之路一:捕捉异常
- 直立车各环的调试_平衡小车调试指南(直立环 速度环)
- Windows 7 部署 Android 开发环境傻瓜式教程(Eclipse+ADT)
- C++实现Schmidt施密特正交化算法(附完整源码)
- map 和set 有什么区别,分别又是怎么实现的
- 对弈程序基本技术----Alpha-Beta搜索
- 神经网络架构搜索_神经网络架构
- chromium之histogram.h
- [转]C#操作Excel开发报表系列整理
- 《大话数据结构》学习笔记
- java 替换所有中文_java 替换中文
- unity3d面试题
- 计算机基础及msoffice应用内容,计算机一级计算机基础及 ms office 应用考些什么 自考计算机应用基础,要考哪些内容?...
- 用电脑怎么快速抠图?怎么把图片抠成透明背景?
- 平衡运输问题及其表上作业法---指派问题及其匈牙利解法
- Cesium 可视域分析代码段(源码)补充
- linux系统中ssh命令,Linux系统中SSH 命令的用法有哪些?
- 骄傲! 咱中国人的区块链技术闯进了国际学术顶会!
- 六:分布式架构存储设计
- it转正述职报告_IT试用期转正工作总结
热门文章
- PS放大图片而不模糊的操作方法
- 【渝粤题库】陕西师范大学200101 西方文学 作业(高起专)
- 如何制作微信小程序(三个步骤开发小程序)
- 各行业的英语术语(绝对精华 1)
- Ajax的回调函数(js与JQuery写法)
- 运动世界校园显示服务器异常,运动世界校园跑完是异常成绩,计入有效成绩里吗?...
- 国仁老猫:新人怎么做好一场直播带货;首先需要明白以下几点即可。
- python可以做微信小游戏吗_python可以写微信小游戏吗
- 获取iPhone手机 UDID的方式--一网打尽(无论有无MAC电脑)
- php 高德地图经纬度,高德地图php 换取经纬度 地址