直接上代码,因为里面的注解直接看就可以:
# -*- coding: utf-8 -*-
# 声明文件编码为utf-8,确保中文字符等可以正确显示。
from PIL import Image
# 导入PIL库中的Image模块,用于图像处理。
from numpy import average, dot, linalg
# 从numpy库中导入average(求平均值)、dot(点积)和linalg(线性代数)函数。
import cv2
# 导入OpenCV库,但实际上在这段代码中并未使用到。
import requests
# 导入requests库,用于发送HTTP请求。
from io import BytesIO
# 导入BytesIO类,用于在内存中处理二进制数据流。
import numpy as np
# 导入numpy库,并简写为np,用于进行数值计算。
# 对图片进行统一化处理
def get_thum(image, size=(64, 64), greyscale=False):
# 利用image的resize方法对图像大小重新设置, Image.ANTIALIAS为高质量的缩放方法。
image = image.resize(size, Image.ANTIALIAS)
if greyscale:
# 如果greyscale为True,则将图片转换为灰度图。
image = image.convert('L')
return image
# 返回处理后的图片。
def getImageByUrl(url):
# 根据图片url获取图片对象的函数。
html = requests.get(url, verify=False) # 发送HTTP GET请求获取图片数据,verify=False表示不进行SSL证书验证。
image = Image.open(BytesIO(html.content)) # 使用PIL的Image模块打开获取到的图片数据。
return image # 返回图片对象。
# 计算图片的余弦距离(实际上计算的是余弦相似度)
def similarity_pics(image1, image2):
# 这里的注释掉的部分代码是用于从网络或本地文件系统中加载图片的,但在这段代码中并未使用。
image1 = get_thum(image1) # 对第一张图片进行统一化处理。
image2 = get_thum(image2) # 对第二张图片进行统一化处理。
images = [image1, image2] # 将两张图片放入一个列表中。
vectors = [] # 用于存储每张图片的向量表示。
norms = [] # 用于存储每张图片的向量的范数。
for image in images: # 遍历每张图片。
vector = [] # 用于存储当前图片的向量表示。
for pixel_tuple in image.getdata(): # 遍历图片的每个像素。
vector.append(average(pixel_tuple)) # 将像素值的平均值添加到向量中(对于灰度图是像素值本身,对于彩色图是RGB三通道的平均值)。
vectors.append(vector) # 将当前图片的向量添加到vectors列表中。
norms.append(linalg.norm(vector, 2)) # 计算当前图片的向量的2范数,并添加到norms列表中。
a, b = vectors # 分别取出两张图片的向量表示。
a_norm, b_norm = norms # 分别取出两张图片的向量的范数。
res = dot(a / a_norm, b / b_norm) # 计算两张图片的向量的余弦相似度。
return res # 返回余弦相似度。
# 检查是否是URL,然后加载图像
def load_image(image_path_or_url):
if isinstance(image_path_or_url, str) and image_path_or_url.startswith('http'):
return getImageByUrl(image_path_or_url)
elif isinstance(image_path_or_url, str):
return Image.open(image_path_or_url)
else:
raise ValueError("Input must be a string representing a file path or URL.")
# 使用load_image函数加载图像
image1 = load_image('1.png') # 从本地文件系统中加载第一张图片。
image2 = load_image('2.png') # 从本地文件系统中加载第二张图片。
cosin = similarity_pics(image1, image2) # 计算两张图片的余弦相似度。
print('图片余弦相似度', cosin) # 打印出余弦相似度。注意这里实际上计算的是余弦相似度,而不是余弦距离,余弦相似度的值越接近1表示越相似。