一个简单的人物图片相似对比程序

Posted 林嘉瑜

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了一个简单的人物图片相似对比程序相关的知识,希望对你有一定的参考价值。

程序是参考了两部分的别人的代码,一个是找出照片中的人头,另一个是对两个人头照片做对比。

# -*- coding: utf-8 -*-
# feimengjuan
# 利用python实现多种方法来实现图像识别

import cv2
import numpy as np
from matplotlib import pyplot as plt, image


# 最简单的以灰度直方图作为相似比较的实现
def classify_gray_hist(image1, image2, size=(256, 256)):
    # 先计算直方图
    # 几个参数必须用方括号括起来
    # 这里直接用灰度图计算直方图,所以是使用第一个通道,
    # 也可以进行通道分离后,得到多个通道的直方图
    # bins 取为16
    image1 = cv2.resize(image1, size)
    image2 = cv2.resize(image2, size)
    hist1 = cv2.calcHist([image1], [0], None, [256], [0.0, 255.0])
    hist2 = cv2.calcHist([image2], [0], None, [256], [0.0, 255.0])
    # 可以比较下直方图
    plt.plot(range(256), hist1, r)
    plt.plot(range(256), hist2, b)
    plt.show()
    # 计算直方图的重合度
    degree = 0
    for i in range(len(hist1)):
        if hist1[i] != hist2[i]:
            degree = degree + (1 - abs(hist1[i] - hist2[i]) / max(hist1[i], hist2[i]))
        else:
            degree = degree + 1
    degree = degree / len(hist1)
    return degree


# 计算单通道的直方图的相似值
def calculate(image1, image2):
    hist1 = cv2.calcHist([image1], [0], None, [256], [0.0, 255.0])
    hist2 = cv2.calcHist([image2], [0], None, [256], [0.0, 255.0])
    # 计算直方图的重合度
    degree = 0
    for i in range(len(hist1)):
        if hist1[i] != hist2[i]:
            degree = degree + (1 - abs(hist1[i] - hist2[i]) / max(hist1[i], hist2[i]))
        else:
            degree = degree + 1
    degree = degree / len(hist1)
    return degree


# 通过得到每个通道的直方图来计算相似度
def classify_hist_with_split(image1, image2, size=(256, 256)):
    # 将图像resize后,分离为三个通道,再计算每个通道的相似值
    image1 = cv2.resize(image1, size)
    image2 = cv2.resize(image2, size)
    sub_image1 = cv2.split(image1)
    sub_image2 = cv2.split(image2)
    sub_data = 0
    for im1, im2 in zip(sub_image1, sub_image2):
        sub_data += calculate(im1, im2)
    sub_data = sub_data / 3
    return sub_data


# 平均哈希算法计算
def classify_aHash(image1, image2):
    image1 = cv2.resize(image1, (8, 8))
    image2 = cv2.resize(image2, (8, 8))
    gray1 = cv2.cvtColor(image1, cv2.COLOR_BGR2GRAY)
    gray2 = cv2.cvtColor(image2, cv2.COLOR_BGR2GRAY)
    hash1 = getHash(gray1)
    hash2 = getHash(gray2)
    return Hamming_distance(hash1, hash2)


def classify_pHash(image1, image2):
    image1 = cv2.resize(image1, (32, 32))
    image2 = cv2.resize(image2, (32, 32))
    gray1 = cv2.cvtColor(image1, cv2.COLOR_BGR2GRAY)
    gray2 = cv2.cvtColor(image2, cv2.COLOR_BGR2GRAY)
    # 将灰度图转为浮点型,再进行dct变换
    dct1 = cv2.dct(np.float32(gray1))
    dct2 = cv2.dct(np.float32(gray2))
    # 取左上角的8*8,这些代表图片的最低频率
    # 这个操作等价于c++中利用opencv实现的掩码操作
    # 在python中进行掩码操作,可以直接这样取出图像矩阵的某一部分
    dct1_roi = dct1[0:8, 0:8]
    dct2_roi = dct2[0:8, 0:8]
    hash1 = getHash(dct1_roi)
    hash2 = getHash(dct2_roi)
    return 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


if __name__ == __main__:
    face_cascade = cv2.CascadeClassifier(haarcascade_frontalface_alt2.xml)
    face_cascade.load(F:\pycharm\py2_7\Lib\site-packages\cv2\data\haarcascade_frontalface_default.xml)
    scaling_factor = 0.5
    img1 = cv2.imread(d://68.jpg)
    #img1 = cv2.resize(img1,(300,300))
    img1 = cv2.resize(img1, None, fx=scaling_factor * 3, fy=scaling_factor * 3, interpolation=cv2.INTER_AREA)
    gray = cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY)
    face_rects = face_cascade.detectMultiScale(gray, 1.1, 5)
    for (x, y, w, h) in face_rects:
        img1 = img1[y:y + h,x:x + w]
        #cv2.rectangle(img1, (x, y), (x + w, y + h), (0, 255, 0), 3)

    img2 = cv2.imread(d://69.jpg)
    #img2 = cv2.resize(img2,(300,300))
    img2 = cv2.resize(img2, None, fx=scaling_factor * 3, fy=scaling_factor * 3, interpolation=cv2.INTER_AREA)
    gray2 = cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY)
    face_rects2 = face_cascade.detectMultiScale(gray2, 1.1, 5)
    for (x, y, w, h) in face_rects2:
        img2 = img2[y:y + h,x:x + w]
        #cv2.rectangle(img2, (x, y), (x + w, y + h), (0, 255, 0), 3)
    #degree = classify_gray_hist(img1, img2)
    degree = classify_hist_with_split(img1,img2)
    #degree = classify_aHash(img1,img2)
    #degree = classify_pHash(img1,img2)
    out = format(相似度:%f % (float)(degree*100))
    print out
    img1 = cv2.resize(img1, (300, 300))
    cv2.imshow(img1, img1)
    img2 = cv2.resize(img2, (300, 300))
    cv2.imshow(img2,img2)

    #degree = classify_hist_with_split(img1,img2)
    # degree = classify_aHash(img1,img2)
    # degree = classify_pHash(img1,img2)
    #print degree
    cv2.waitKey(0)

 

以上是关于一个简单的人物图片相似对比程序的主要内容,如果未能解决你的问题,请参考以下文章

有啥可以对比两张图片得出相似度的软件。

图片哈希概论及python中如何实现对比两张相似的图片

Java 如何对比两张图片的相似度

图片相似度判断

java 对比图片相似度的算法。。说说想法也行

图像视频相似度算法