一般我们人区分谁是谁,给物品分类,都是通过各种特征去辨别的,比如黑长直、大白腿、樱桃唇、瓜子脸。王麻子脸上有麻子,隔壁老王和儿子很像,但是儿子下巴涨了一颗痣和他妈一模一样,让你确定这是你儿子。
还有其他物品、什么桌子带腿、镜子反光能在里面倒影出东西,各种各样的特征,我们通过学习、归纳,自然而然能够很快识别分类出新物品。
而没有学习训练过的机器就没办法了。但是图像是一个个像素点组成的,我们就可以通过不同图像之间这些差异性就判断两个图的相似度了。其中颜色特征是最常用的,(其余常用的特征还有纹理特征、形状特征和空间关系特征等)
其中又分为
直方图
颜色集
颜色矩
聚合向量
相关图
1、直方图
在Python中利用opencv中的calcHist()方法获取其直方图数据,返回的结果是一个列表,使用matplotlib,画出了这两张图的直方图数据图
import cv2
import numpy
from matplotlib import pyplot
if __name__ == '__main__':
imgobj1 = cv2.imread('pho.jpg')
imgobj2 = cv2.imread('ph1.jpg')
hist1 = cv2.calcHist([imgobj1], [0], None, [256], [0.0, 255.0])
hist2 = cv2.calcHist([imgobj2], [0], None, [256], [0.0, 255.0])
pyplot.plot(range(256), hist1, 'r')
pyplot.plot(range(256), hist2, 'b')
pyplot.show()
cv2.imshow('img1',imgobj1)
cv2.imshow('img2',imgobj2)
cv2.waitKey(0)
- 灰度图是只含有黑白颜色,和0~255亮度等级的图片。灰度图具有存储小,其亮度值就是256色调色板索引号,从整幅图像的整体和局部的色彩以及亮度等级分布特征来看,灰度图描述与彩色图的描述是一致的特点。因此很多真彩色图片的分析,第一步就是转换为灰度图,然后再进行分析。
真彩色,因为是24位,2(^8) * 2(^8)* 2(^8) = 16777216种颜色,需要调色板16777216 * 4byte字节的空间也就是64MB的调色板空间,所以真彩色是不用调色板的。
例如视频目标跟踪和识别时,第一步就是要转换为灰度图。现有的成熟分析算法多是基于灰度图像的,灰度图像综合了真彩色位图的RGB各通道的信息。
(一):单通道图,
俗称灰度图,每个像素点只能有有一个值表示颜色,它的像素值在0到255之间,0是黑色,255是白色,中间值是一些不同等级的灰色。(也有3通道的灰度图,3通道灰度图只有一个通道有值,其他两个通道的值都是零)。
(二):三通道图,每个像素点都有3个值表示 ,所以就是3通道。也有4通道的图。例如RGB图片即为三通道图片,RGB色彩模式是工业界的一种颜色标准,是通过对红(R)、绿(G)、蓝(B)三个颜色通道的变化以及它们相互之间的叠加来得到各式各样的颜色的,RGB即是代表红、绿、蓝三个通道的颜色,这个标准几乎包括了人类视力所能感知的所有颜色,是目前运用最广的颜色系统之一。总之,每一个点由三个值表示。
- 直方图判断相似度,如上图,就算重合度即可
图像指纹:
和人的指纹一样,是身份的象征,而图像指纹简单点来讲,就是将图像按照一定的哈希算法,经过运算后得出的唯一一组二进制数字。汉明距离:
假如一组二进制数据为101,另外一组为111,那么显然把第一组的第二位数据0改成1就可以变成第二组数据111,所以两组数据的汉明距离就为1
简单点说,汉明距离就是一组二进制数据变成另一组数据所需的步骤数,显然,这个数值可以衡量两张图片的差异,汉明距离越小,则代表相似度越高。汉明距离为0,即代表两张图片完全一样。
此算法是基于比较灰度图每个像素与平均值来实现的
一般步骤:
- 缩放图片,一般大小为8*8,64个像素值。
- 转化为灰度图
- 计算平均值:计算进行灰度处理后图片的所有像素点的平均值,直接用numpy中的mean()计算即可。
- 比较像素灰度值:遍历灰度图片每一个像素,如果大于平均值记录为1,否则为0.
- 得到信息指纹:组合64个bit位,顺序随意保持一致性。
- 最后比对两张图片的指纹,获得汉明距离即可。
import cv2
import numpy as np
img1 = cv2.imread("/absPath.png")
img2 = cv2.imread("./x.png")
#调整到8*8
img1 = cv2.resize(img1,(8,8))
img2 = cv2.resize(img2,(8,8))
#转化为灰度图
gray1 = cv2.cvtColor(img1,cv2.COLOR_BGR2GRAY)
gray2 = cv2.cvtColor(img2,cv2.COLOR_BGR2GRAY)
#获取哈希
hash1 = getHash(gray1)
hash2 = getHash(gray2)
ret = Hamming_distance(hash1,hash2)
# 输入灰度图,返回hash
def getHash(image):
avreage = np.mean(image) #计算像素平均值
hash = []
for i in range(image.shape[0]):
for j in range(image.shape[1]):
if image[i, j] > avreage:
hash.append(1)
else:
hash.append(0)
return hash
# 计算汉明距离
def Hamming_distance(hash1, hash2):
num = 0
for index in range(len(hash1)):
if hash1[index] != hash2[index]:
num += 1
return num