You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

200 lines
6.1 KiB

5 months ago
# -*- 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为像素和初值为0hash_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计数+1n最终为相似度
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()