Infi-chu:

http://www.cnblogs.com/Infi-chu/

以图搜图的使用已经非常广泛了,我现在来介绍一下简单的以图搜图的相关算法及其实践。

一、感知hash算法

感知哈希算法:
感知哈希算法(Perceptual hash algorithm)是哈希算法的一类,主要用来做相似图片的搜索工作。
图片所包含的特征被用来生成一组指纹(不过它不是唯一的), 而这些指纹是可以进行比较的。
步骤:
1.把图片转化为字符串,这个字符串就是图片的hash值,又称指纹。
2.求两个字符串之间的相似度(汉明距离),字符串越相似,即图片越相似。

二、汉明距离

汉明距离:
汉明距离是两个字符串对应位置的不同字符的个数。换句话说,它就是将一个字符串变换成另外一个字符串所需要替换的字符个数。
例如:
1011101 与 1001001 之间的汉明距离是 2。
2143896 与 2233796 之间的汉明距离是 3。
“toned” 与 “roses” 之间的汉明距离是 3。

三、均值hash

下面的例子是使用了像素平均值,又叫均值哈希。
优点:均值哈希较为简单。
缺点:对图像灰度的平均值特别敏感,也不具备旋转不变性。
import cv2
def p_hash(path):
# Step1. 把图像缩小为8 * 8,并转化为灰度图
src = cv2.imread(path, 0)
src = cv2.resize(src, (8, 8), cv2.INTER_LINEAR)
# Step2. 计算64个像素的灰度均值
avg = sum([sum(src[i]) for i in range(8)]) / 64
# Step3. 与平均值比较,生成01字符串
string = ''
for i in range(8):
string += ''.join(map(lambda i: '0' if i < avg else '1', src[i]))
# Step4. 计算hash值
result = ''
for i in range(0, 64, 4):
result += ''.join('%x' % int(string[i: i + 4], 2))
return result def hamming(str1, str2):
if len(str1) != len(str2):
return
count = 0
for i in range(0, len(str1)):
if str1[i] != str2[i]:
count += 1
return count # 读取四张图片,进行测试
h1 = p_hash('1.jpg')
h2 = p_hash('2.jpg')
h3 = p_hash('3.jpg')
h4 = p_hash('4.jpg') # 四张图片的相互对比
print('1&2 --> ',hamming(h1,h2))
print('1&3 --> ',hamming(h1,h3))
print('1&4 --> ',hamming(h1,h4))
print('2&3 --> ',hamming(h2,h3))
print('2&4 --> ',hamming(h2,h4))
print('3&4 --> ',hamming(h3,h4))

结果:

1&2 -->  1
1&3 --> 0
1&4 --> 1
2&3 --> 1
2&4 --> 1
3&4 --> 1

四、余弦感知哈希

为了提升更好的识别效果,可以使用余弦感知哈希算法。
优点:能够处理旋转图形。
缺点:只能够识别变形程度在25%以内的图片。 步骤:
1.缩小尺寸:将图像缩小到32*32,并转为灰度图。
2.计算DCT:对图像进行二维离散余弦变换。
3.缩小DCT:只保留矩阵左上角8*8区域,对这个区域求哈希均值,并生成01字符串。
4.计算hash值。
5.求汉明距离
import numpy as np
import cv2 def p_hash(path):
# Step1. 把图像缩小为32 * 32,并转化为灰度图
src = cv2.imread(path, 0)
src = cv2.resize(src, (32, 32), cv2.INTER_LINEAR) # Step2. 对图像进行余弦变换
h, w = src.shape[:2]
arr = np.zeros((h, w), np.float32)
arr[:h, :w] = src
src = cv2.dct(cv2.dct(arr)) # 离散余弦变换
src.resize(8, 8) # Step3. 计算64个像素的灰度均值
avg = sum([sum(src[i]) for i in range(8)]) / 64 # Step4. 与平均值比较,生成01字符串
string = ''
for i in range(8):
string += ''.join(map(lambda i: '0' if i < avg else '1', src[i])) # Step5. 计算hash值
result = ''
for i in range(0, 64, 4):
result += ''.join('%x' % int(string[i: i + 4], 2))
return result def hamming(str1, str2):
if len(str1) != len(str2):
return
count = 0
for i in range(0, len(str1)):
if str1[i] != str2[i]:
count += 1
return count # 读取四张图片,进行测试
h1 = p_hash('1.jpg')
h2 = p_hash('2.jpg')
h3 = p_hash('3.jpg')
h4 = p_hash('4.jpg') # 四张图片的相互对比
print('1&2 --> ',hamming(h1,h2))
print('1&3 --> ',hamming(h1,h3))
print('1&4 --> ',hamming(h1,h4))
print('2&3 --> ',hamming(h2,h3))
print('2&4 --> ',hamming(h2,h4))
print('3&4 --> ',hamming(h3,h4))
print('1&1 --> ',hamming(h1,h1))

结果:

1&2 -->  3
1&3 --> 1
1&4 --> 6
2&3 --> 3
2&4 --> 6
3&4 --> 5
1&1 --> 0

图例:

‘1.jpg’

‘2.jpg’

‘3.jpg’

‘4.jpg’

Python3 图像识别(二)的更多相关文章

  1. 循序渐进Python3(二) -- 数据类型

    数据类型 一.数字(int) Python可以处理任意大小的正负整数,但是实际中跟我们计算机的内存有关,在32位机器上,整数的位数为32位,取值范围为 -2**31-2**31-1,在64位系统上,整 ...

  2. python3 基础二——基本的数据类型三

    一.字符串str 1.创建字符串,为变量分配一个值 word='字符串' sentence="字符串\n" #python中单引号和双引号使用完全相同 paragraph=&quo ...

  3. python3 基础二——基本的数据类型二

    一.数字(Number) 1.Python支持三种不同的数值类型:整型(int),浮点型(float),复数(complex) 2.Python数字数据类型用于存储数值 3.数据类型是不允许改变的,这 ...

  4. python3 基础二——基本的数据类型一

    一.基本的数据类型 Python3 中有六个标准的数据类型Number(数字). String(字符串). List(列表) .Tuple(元组). Sets(集合) .Dictionary(字典) ...

  5. python3 入门 (二) 列表的使用

    列表用于组织其它数值,即写在方括号之间.用逗号分隔开的数值列表.列表内的项目不必全是相同的类型. 列表的定义 student = ['Tom', 'Jack', 'Avril'] 添加元素 将另一个列 ...

  6. python3基础(二)

    loops循环语句 一 if语句,if语句配合else使用,可以没有else. 单分支if语句 age = input('Age:') password = '67' if age == passwo ...

  7. Python3 图像识别(一)

    Infi-chu: http://www.cnblogs.com/Infi-chu/ 一.环境准备: 1.Python3.x(我是用的是Python3.6.5),这个问题不大,只要3.4以上就OK. ...

  8. 廖雪峰python3练习题二

    字符串和编码 题目: 答案: #!/usr/bin/env python3 #-*- coding:utf-8 -*- s1 = 72 s2 = 85 print('小明的成绩提高了%.1f%%个百分 ...

  9. python3之二年级上数学练习题生成

    二年级上数学练习题生成 作为一个家长不容易啊 1 #coding:utf-8 2 import random 3 #小学二年级上数学练习(100以内加减乘) 4 #生成的题数 5 count = 50 ...

随机推荐

  1. 沉淀,再出发:AngularJS初探

    沉淀,再出发:AngularJS初探 一.前言 知识的学习需要形成一个闭环,在这个闭环之内可以自圆其说,从而触类旁通,加以理想创造,从而产生灵感.关于前端的知识,我已经写得差不多了,但是还有一个知识点 ...

  2. 沉淀,再出发:百度地图api的使用浅思

    沉淀,再出发:百度地图api的使用浅思 一.前言   百度地图想必大家都使用过,但是看到别人使用百度地图的API时候是不是一头雾水呢,其实真正明白了其中的意义就像是调用豆瓣电影api的接口一样的简单, ...

  3. 关于Oracle伪列rownum

    rownum列跟rowid列不一样,虽然同为表的伪列.但是rowid列是列的一个固定属性,而rownum列是结果集的一个排序.所以像如下查询是不会返回结果的:select rowid,rownum,e ...

  4. 020.2.1 system

    内容:System的常用方法1.currentTimeMillis()方法(与1970年相差多少毫秒),2.Properties  getProperties():获取系统属性3.Set<Str ...

  5. TreadingTCPServer

    TreadingTCPServer实现的socket服务器内部会为每个client创建一个线程,该线程用来和客户端进行交互. 1.TreadingTCPServer基础 使用TreadingTCPSe ...

  6. c++ 派生类的构造函数次序

    #include <iostream> using namespace std; class CFatherSum //父类Sum { public: CFatherSum(int iRe ...

  7. P1314 聪明的质监员

    题目描述 小T 是一名质量监督员,最近负责检验一批矿产的质量.这批矿产共有 n 个矿石,从 1 到 n 逐一编号,每个矿石都有自己的重量 \(w_i\)​ 以及价值 \(v_i\) .检验矿产的流程是 ...

  8. node.js的npm命令常见错误及解决方案

    使用npm命令进行模块安装的时候场出现各种错误,本文总结我所遇到的各种错误,并提供解决方案.(大部分内容为网上收集) 首先使用淘宝 NPM 镜像 大家都知道国内直接使用 npm 的官方镜像是非常慢的, ...

  9. 组合测试(Combinatorial Test)/配对测试 (pairwise)

    组合测试方法:配对测试实践 实施组合测试 常用的Pairwise工具集:http://www.pairwise.org/tools.asp 成对测试(Pairwise Testing)又称结对测试.两 ...

  10. VC++使用socket进行TCP、UDP通信实例总结

    1.        两台计算机通信需要协议,通信的两台计算机IP必须唯一 2.        同一个计算机可以进行多个应用程序与其他计算机通信,IP地址唯一,而端口号是区别同一计算机(同一IP)的唯一 ...