pythonopencv算法_深入学习OpenCV中图像相似度的算法(比对像素方差,感知哈希算法,模板匹配(OCR数字匹配),OpenCV的安装)...

本文详细介绍了使用Python OpenCV实现图像相似度比对的三种算法:像素方差比对、感知哈希算法和模板匹配。通过计算方差、应用感知哈希和模板匹配方法,可以有效地检测图像的相似度。文中还提供了代码示例和实战应用,如信用卡数字识别。
摘要由CSDN通过智能技术生成

如果需要处理的原图及代码,请移步小编的GitHub地址

传送门:请点击我

如果点击有误:https://github.com/LeBron-Jian/ComputerVisionPractice

最近一段时间学习并做的都是对图像进行处理,其实自己也是新手,各种尝试,所以我这个门外汉想总结一下自己学习的东西,图像处理的流程。但是动起笔来想总结,一下却不知道自己要写什么,那就把自己做过的相似图片搜索的流程整理一下,想到什么说什么吧。

一:图片相似度算法(对像素求方差并比对)的学习

1.1 算法逻辑

1.1.1 缩放图片

将需要处理的图片所放到指定尺寸,缩放后图片大小由图片的信息量和复杂度决定。譬如,一些简单的图标之类图像包含的信息量少,复杂度低,可以缩放小一点。风景等复杂场景信息量大,复杂度高就不能缩放太小,容易丢失重要信息。根据自己需求,弹性的缩放。在效率和准确度之间维持平衡。

1.1.2 灰度处理

通常对比图像相似度和颜色关系不是很大,所以处理为灰度图,减少后期计算的复杂度。如果有特殊需求则保留图像色彩。

1.1.3 计算平均值

此处开始,与传统的哈希算法不同:分别依次计算图像每行像素点的平均值,记录每行像素点的平均值。每一个平均值对应着一行的特征。

1.1.4 计算方差

对得到的所有平均值进行计算方差,得到的方差就是图像的特征值。方差可以很好的反应每行像素特征的波动,既记录了图片的主要信息。

1.1.5 比较方差

经过上面的计算之后,每张图都会生成一个特征值(方差)。到此,比较图像相似度就是比较图像生成方差的接近成程度。

一组数据方差的大小可以判断稳定性,多组数据方差的接近程度可以反应数据波动的接近程度。我们不关注方差的大小,只关注两个方差的差值的大小。方差差值越小图像越相似!

1.2 代码:

import cv2

import matplotlib.pyplot as plt

#计算方差

def getss(list):

#计算平均值

avg=sum(list)/len(list)

#定义方差变量ss,初值为0

ss=0

#计算方差

for l in list:

ss+=(l-avg)*(l-avg)/len(list)

#返回方差

return ss

#获取每行像素平均值

def getdiff(img):

#定义边长

Sidelength=30

#缩放图像

img=cv2.resize(img,(Sidelength,Sidelength),interpolation=cv2.INTER_CUBIC)

#灰度处理

gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)

#avglist列表保存每行像素平均值

avglist=[]

#计算每行均值,保存到avglist列表

for i in range(Sidelength):

avg=sum(gray[i])/len(gray[i])

avglist.append(avg)

#返回avglist平均值

return avglist

#读取测试图片

img1=cv2.imread("james.jpg")

diff1=getdiff(img1)

print('img1:',getss(diff1))

#读取测试图片

img11=cv2.imread("durant.jpg")

diff11=getdiff(img11)

print('img11:',getss(diff11))

ss1=getss(diff1)

ss2=getss(diff11)

print("两张照片的方差为:%s"%(abs(ss1-ss2)))

x=range(30)

plt.figure("avg")

plt.plot(x,diff1,marker="*",label="$jiames$")

plt.plot(x,diff11,marker="*",label="$durant$")

plt.title("avg")

plt.legend()

plt.show()

cv2.waitKey(0)

cv2.destroyAllWindows()

两张原图:

1226410-20181011202007860-247616267.png

1226410-20181011201608008-1027505445.png

图像结果如下:

img1: 357.03162469135805

img11: 202.56193703703704

两张照片的方差为:154.469687654321

1226410-20181011201754547-1118765723.png

实验环境开始设置了图片像素值,而且进行灰度化处理,此方法比对图像相似对不同的图片方差很大,结果很明显,但是对比比较相似,特别相似的图片不适应。

二:图片相似度算法(感知哈希算法)的学习

"感知哈希算法"(Perceptual hash algorithm),它的作用是对每张图片生成一个"指纹"(fingerprint)字符串,然后比较不同图片的指纹。结果越接近,就说明图片越相似。

2.1 算法步骤

2.1.1 缩小尺寸

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

2.1.2 简化色彩

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

2.1.3 计算平均值

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

2.1.4 比较像素的灰度平均值

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

2.1.5 计算哈希值

将上一步的比较结果,组合在一起,就构成了一个64位的整数,这就是这张图片的指纹。组合的次序并不重要,只要保证所有图片都采用同样次序就行了。

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

此算法参考博客:http://www.ruanyifeng.com/blog/2011/07

/principle_of_similar_image_search.html

但是未实现代码,代码如下:

#!/usr/bin/python

import glob

import os

import sys

from PIL import Image

EXTS = 'jpg', 'jpeg', 'JPG', 'JPEG', 'gif', 'GIF', 'png', 'PNG'

def avhash(im):

if not isinstance(im, Image.Image):

im = Image.open(im)

im = im.resize((8, 8), Image.ANTIALIAS).convert('L')

avg = reduce(lambda x, y: x + y, im.getdata()) / 64.

return reduce(lambda x, (y, z): x | (z << y),

enumerate(map(lambda i: 0 if i < avg else 1, im.getdata())),

0)

def hamming(h1, h2):

h, d = 0, h1 ^ h2

while d:

h += 1

d &= d - 1

return h

if __name__ == '__main__':

if len(sys.argv) <= 1 or len(sys.argv) > 3:

print "Usage: %s image.jpg [dir]" % sys.argv[0]

else:

im, wd = sys.argv[1], '.' if len(sys.argv) < 3 else sys.argv[2]

h = avhash(im)

os.chdir(wd)

images = []

for ext in EXTS:

images.extend(glob.glob('*.%s' % ext))

seq = []

prog = int(len(images) > 50 and sys.stdout.isatty())

for f in images:

seq.append((f, hamming(avhash(f), h)))

if prog:

perc = 100. * prog / len(images)

x = int(2 * perc / 5)

print '\rCalculating... [' + '#' * x + ' ' * (40 - x) + ']',

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值