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

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

# -*- 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()