一种基于颜色统计和特征指纹的图片相似度计算方法
1.摘要
图片相似度有很多实际应用,比如谷歌搜图、淘宝识物购买,现在很多类似应用已经使用神经网络训练实现,但是本文仅仅从图像处理角度出发,根据图像内容特征信息实现图片相似度计算。如题描述,我们将从颜色和内容信息两方面进行。
2.实现
本节内容将从原理、代码实现并结合应用效果介绍感知哈希算法和颜色分量统计算法
from math import sqrt
import numpy as np
import pandas as pd
import itertools
2.1.感知哈希算法
- 原理描述:结合离散余弦变换,将灰度图片所包含的特征生成一组指纹(哈希值),计算图片相似度即计算图片指纹的相似度。
- 关于离散余弦变换:灰度图是二维矩阵,由不同频率的成分组成。一般来说亮度变化小的区域是低频成分,它描述大范围的信息。而亮度变化剧烈的区域(比如物体的边缘)就是高频的成分,它描述具体的细节。由于大多数自然信号的能量都集中在余弦变换后的低频部分,可以舍弃信息含量更少的高频部分而提高计算效率,具体使用方法是离散余弦变换(DCT)。
- 具体步骤:
-
简化色彩:BGR2GRAY;
-
计算DCT:计算图片的DCT变换,得到32*32的DCT系数矩阵;
-
缩小DCT:保留左上角的8*8的矩阵(最低频率);
-
计算平均值:计算DCT的均值;
-
计算hash值:根据8*8的DCT矩阵,设置0或1的64位的hash值,大于等于DCT均值的设为”1”,小于DCT均值的设为“0”。将得到的二维数组拉伸成一维,构成了一个长度为64位的向量,这就是这张图片的指纹;
-
计算两张图片指纹,使用汉明距离计算相似度。
结果并不能告诉我们真实性的低频率,只能粗略地告诉我们较于平均值频率的相对比例。只要图片的整体结构保持不变,hash结果值就不变。能够避免伽马校正或颜色直方图被调整带来的影响。
#均值哈希算法
def aHash(img):
img=cv2.resize(img,(8,8),interpolation=cv2.INTER_CUBIC)
gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
s=0
hash_str=''
for i in range(8):
for j in range(8):
s=s+gray[i,j]
avg=s/64
for i in range(8):
for j in range(8):
if gray[i,j]>avg:
hash_str=hash_str+'1'
else:
hash_str=hash_str+'0'
return hash_str
#差值感知算法
def dHash(img):
img=cv2.resize(img,(9,8),interpolation=cv2.INTER_CUBIC)
gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
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
# 感知哈希算法
def pHash(img):
img = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
img=cv2.resize(img,(32,32),interpolation=cv2.INTER_CUBIC)
_ = np.array(img,np.float32)
__ = cv2.dct(_)
#取低频区域
img_dct = __[:8,:8]
#把二维list变成一维list
img_list = []
for i in img_dct.tolist():
for j in i:
img_list.append(j)
#计算均值并哈希转换
avg = sum(img_list)*1./len(img_list)
hash_str = ''
for i in img_list:
if i > avg:
hash_str=hash_str+'1'
else:
hash_str=hash_str+'0'
return hash_str
#Hash值对比
def compCode(code1,code2,length):
num = 0
for index in range(0,len(code1)):
if code1[index] != code2[index]:
num+=1
return (1-(num / length))
# 感知哈希算法使用:
compCode(pHash(img_a),pHash(img_b),64)
2.2.颜色分量统计算法
- 原理描述:每张图片都有自己特定的颜色分布。将1600多万种颜色分为N个颜色区间,对每张图片,统计其每个颜色区间的像素个数,获得一组长度为N的向量。计算图片相似度即计算向量之间的相似度。
- 具体步骤:
- 规整尺寸:resize(102410243);
- 颜色分区:将RGB每个颜色通道均分为m个数值区间,共得到m的三次方(记为N)个颜色区间;
- 统计每个颜色区间内的像素个数,获得向量;
- 计算向量之间的相似度;
# 代码不贴了 有兴趣私聊
3.验证效果
感知哈希算法中,经过了余弦离散变化,图像内部信息的大都集中在低频区域,将计算重点缩小至该区域,但是仅仅对灰度图研究,丢失了颜色信息,而颜色分量统计算法从颜色角度出发,统计了整张图片的颜色分布情况,两种方法结合保证了相似度的准确性。
扫描二维码关注公众号,回复:
8511545 查看本文章
以下风景图(450×800×3)为例,记为img
- 将原图上下平均拆分
img_up:225×800
img_dn:225×800 - 将原图左右比例拆分
img_left:450×600
img_right:450×600
感知哈希算法效果如下:
综合两种算法一起的效果如下:
参考:https://blog.csdn.net/haofan_/article/details/77097473?locationNum=7&fps=1