|
|
# -*- coding: utf-8 -*-
|
|
|
import cv2
|
|
|
import os
|
|
|
import numpy as np
|
|
|
from PIL import Image
|
|
|
from skimage import io
|
|
|
from psd_tools import PSDImage
|
|
|
|
|
|
# 均值哈希算法
|
|
|
def aHash(img,shape=(10,10)):
|
|
|
# 缩放为10*10
|
|
|
img = cv2.resize(img, shape)
|
|
|
# 转换为灰度图
|
|
|
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
|
|
|
# s为像素和初值为0,hash_str为hash值初值为''
|
|
|
s = 0
|
|
|
hash_str = ''
|
|
|
# 遍历累加求像素和
|
|
|
for i in range(shape[0]):
|
|
|
for j in range(shape[1]):
|
|
|
s = s + gray[i, j]
|
|
|
# 求平均灰度
|
|
|
avg = s / 100
|
|
|
# 灰度大于平均值为1相反为0生成图片的hash值
|
|
|
for i in range(shape[0]):
|
|
|
for j in range(shape[1]):
|
|
|
if gray[i, j] > avg:
|
|
|
hash_str = hash_str + '1'
|
|
|
else:
|
|
|
hash_str = hash_str + '0'
|
|
|
return hash_str
|
|
|
|
|
|
# 差值感知算法
|
|
|
def dHash(img,shape=(10,10)):
|
|
|
# 缩放10*11
|
|
|
img = cv2.resize(img, (shape[0]+1, shape[1]))
|
|
|
# 转换灰度图
|
|
|
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
|
|
|
hash_str = ''
|
|
|
# 每行前一个像素大于后一个像素为1,相反为0,生成哈希
|
|
|
for i in range(shape[0]):
|
|
|
for j in range(shape[1]):
|
|
|
if gray[i, j] > gray[i, j + 1]:
|
|
|
hash_str = hash_str + '1'
|
|
|
else:
|
|
|
hash_str = hash_str + '0'
|
|
|
return hash_str
|
|
|
|
|
|
|
|
|
# 感知哈希算法(pHash)
|
|
|
def pHash(img,shape=(10,10)):
|
|
|
# 缩放32*32
|
|
|
img = cv2.resize(img, (32, 32)) # , interpolation=cv2.INTER_CUBIC
|
|
|
|
|
|
# 转换为灰度图
|
|
|
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
|
|
|
# 将灰度图转为浮点型,再进行dct变换
|
|
|
dct = cv2.dct(np.float32(gray))
|
|
|
# opencv实现的掩码操作
|
|
|
dct_roi = dct[0:10, 0:10]
|
|
|
|
|
|
hash = []
|
|
|
avreage = np.mean(dct_roi)
|
|
|
for i in range(dct_roi.shape[0]):
|
|
|
for j in range(dct_roi.shape[1]):
|
|
|
if dct_roi[i, j] > avreage:
|
|
|
hash.append(1)
|
|
|
else:
|
|
|
hash.append(0)
|
|
|
return hash
|
|
|
|
|
|
|
|
|
# 通过得到RGB每个通道的直方图来计算相似度
|
|
|
def classify_hist_with_split(image1, image2, size=(256, 256)):
|
|
|
# 将图像resize后,分离为RGB三个通道,再计算每个通道的相似值
|
|
|
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 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
|
|
|
|
|
|
# Hash值对比
|
|
|
def cmpHash(hash1, hash2,shape=(10,10)):
|
|
|
n = 0
|
|
|
# hash长度不同则返回-1代表传参出错
|
|
|
if len(hash1)!=len(hash2):
|
|
|
return -1
|
|
|
# 遍历判断
|
|
|
for i in range(len(hash1)):
|
|
|
# 相等则n计数+1,n最终为相似度
|
|
|
if hash1[i] == hash2[i]:
|
|
|
n = n + 1
|
|
|
return n/(shape[0]*shape[1])
|
|
|
|
|
|
def file_inspect():
|
|
|
|
|
|
# 文件路径
|
|
|
png_file = 'K:/work/mine_clearance/class1/userfiles2/result.png'
|
|
|
psd_file = 'K:/work/mine_clearance/class1/userfiles2/result.psd'
|
|
|
result_png = 'K:/work/mine_clearance/class1/userfiles2/result3.png'
|
|
|
# 检查文件是否存在
|
|
|
if os.path.exists(png_file) and os.path.exists(psd_file):
|
|
|
psd_to_png(psd_file, result_png)
|
|
|
if image_similarity(png_file, result_png) != 1:
|
|
|
print('result.psd文件与result.png不匹配')
|
|
|
return 0
|
|
|
return 1
|
|
|
else:
|
|
|
print('缺少文件')
|
|
|
return 0
|
|
|
|
|
|
def image_specifications():
|
|
|
# 打开图像文件
|
|
|
image = Image.open('K:/work/mine_clearance/class1/userfiles2/result.psd')
|
|
|
image2 = Image.open('K:/work/mine_clearance/class1/userfiles2/result2.png')
|
|
|
# 获取图像尺寸(宽度和高度)
|
|
|
width, height = image2.size
|
|
|
width2, height2 = image.size
|
|
|
width_difference = abs(width - width2)
|
|
|
height_difference = abs(height - height2)
|
|
|
if width_difference > 20 or height_difference > 20:
|
|
|
print('图片未按照规格修改,请修改在测试!')
|
|
|
|
|
|
def similitude():
|
|
|
img1 = cv2.imread('K:/work/mine_clearance/class1/userfiles2/result.png')
|
|
|
img2 = cv2.imread('K:/work/mine_clearance/class1/userfiles2/image.png')
|
|
|
data = []
|
|
|
hash1 = aHash(img1)
|
|
|
hash2 = aHash(img2)
|
|
|
data.append(cmpHash(hash1, hash2))
|
|
|
|
|
|
hash1 = dHash(img1)
|
|
|
hash2 = dHash(img2)
|
|
|
data.append(cmpHash(hash1, hash2))
|
|
|
|
|
|
hash1 = pHash(img1)
|
|
|
hash2 = pHash(img2)
|
|
|
data.append(cmpHash(hash1, hash2))
|
|
|
|
|
|
data.append(classify_hist_with_split(img1, img2)[0])
|
|
|
|
|
|
data.append(calculate(img1, img2)[0])
|
|
|
flage = 1
|
|
|
for item in data:
|
|
|
print(item)
|
|
|
if item < 0.7:
|
|
|
flage = 0
|
|
|
if flage == 1:
|
|
|
print('恭喜你制作明信片成功!')
|
|
|
else:
|
|
|
print('制作失败')
|
|
|
|
|
|
def psd_to_png(psd_path, png_path):
|
|
|
try:
|
|
|
psd_image = PSDImage.open(psd_path)
|
|
|
image_pil = psd_image.topil()
|
|
|
image_np = cv2.cvtColor(np.array(image_pil), cv2.COLOR_RGB2BGR)
|
|
|
cv2.imwrite(png_path, image_np)
|
|
|
return 1
|
|
|
except Exception as e:
|
|
|
print("psd文件与png文件相同大小")
|
|
|
return 0
|
|
|
|
|
|
def image_similarity(image1, image2):
|
|
|
# 读取图片
|
|
|
img1 = cv2.imread(image1)
|
|
|
img2 = cv2.imread(image2)
|
|
|
# 将图片调整为相同尺寸
|
|
|
img1 = cv2.resize(img1, img2.shape[:2][::-1])
|
|
|
# 计算直方图差异
|
|
|
hist1 = cv2.calcHist([img1], [0, 1, 2], None, [8, 8, 8], [0, 256, 0, 256, 0, 256])
|
|
|
hist2 = cv2.calcHist([img2], [0, 1, 2], None, [8, 8, 8], [0, 256, 0, 256, 0, 256])
|
|
|
similarity = cv2.compareHist(hist1, hist2, cv2.HISTCMP_CORREL)
|
|
|
|
|
|
return similarity
|
|
|
if __name__=="__main__":
|
|
|
# file_inspect()
|
|
|
similitude()
|
|
|
# if file_inspect():
|
|
|
# similitude()
|
|
|
# image_specifications() |