

发布于 2025-09-01 11:30469浏览教程如下~~~
https://www.bilibili.com/video/BV1LtaJzmEdz/
指令作用
给你一张图像 在给你一个文件来,文件夫有很多图像你给我判断这个图片是不是已经在文件表中,不是用md5判断 用像素相似度

代码如下:
# 使用此指令前,请确保安装必要的Python库,例如使用以下命令安装:
# pip install opencv-python numpy pillow
import os
import cv2
import numpy as np
from PIL import Image
from typing import *
try:
from xbot.app.logging import trace as print
except:
from xbot import print
def check_image_similarity(target_image, images_folder, similarity_threshold=0.95):
"""
title: 图像相似度检测
description: 检查目标图像 % target_image % 是否与文件夹 % images_folder % 中的任何图像相似,基于像素相似度而非MD5。
inputs:
- target_image (file): 需要检查的目标图像文件路径,eg: "target.jpg"
- images_folder (folder): 包含多个图像的文件夹路径,eg: "images_folder/"
- similarity_threshold (float): 相似度阈值,范围0-1,默认0.95,eg: "0.95"
outputs:
- result (dict): 包含是否找到相似图像及相似图像信息的字典,eg: "{'found': True, 'similar_image': 'image1.jpg', 'similarity': 0.98}"
"""
# 检查输入参数
if not os.path.isfile(target_image):
raise FileNotFoundError(f"目标图像文件不存在: {target_image}")
if not os.path.isdir(images_folder):
raise FileNotFoundError(f"图像文件夹不存在: {images_folder}")
if not 0 <= similarity_threshold <= 1:
raise ValueError("相似度阈值必须在0到1之间")
# 读取目标图像
def _read_image(image_path):
try:
# 使用PIL读取图像,然后转换为OpenCV格式,这样可以更好地处理中文路径
img_pil = Image.open(image_path)
img_np = np.array(img_pil)
# 如果图像是RGB格式,转换为BGR (OpenCV使用BGR)
if len(img_np.shape) == 3 and img_np.shape[2] == 3:
img_np = cv2.cvtColor(img_np, cv2.COLOR_RGB2BGR)
return img_np
except Exception as e:
raise ValueError(f"读取图像时出错: {str(e)}")
# 计算两张图像的相似度
def _calculate_similarity(img1, img2):
try:
# 调整图像大小以便比较
height = 200 # 可以根据需要调整
width = 200
img1_resized = cv2.resize(img1, (width, height))
img2_resized = cv2.resize(img2, (width, height))
# 确保图像是3通道的,如果不是则转换
if len(img1_resized.shape) == 2:
img1_resized = cv2.cvtColor(img1_resized, cv2.COLOR_GRAY2BGR)
if len(img2_resized.shape) == 2:
img2_resized = cv2.cvtColor(img2_resized, cv2.COLOR_GRAY2BGR)
# 转换为灰度图像
img1_gray = cv2.cvtColor(img1_resized, cv2.COLOR_BGR2GRAY)
img2_gray = cv2.cvtColor(img2_resized, cv2.COLOR_BGR2GRAY)
# 使用均方误差(MSE)作为相似度度量
err = np.sum((img1_gray.astype("float") - img2_gray.astype("float")) ** 2)
err /= float(img1_gray.shape[0] * img1_gray.shape[1])
# 将MSE转换为相似度分数 (0-1)
similarity = 1 - (err / 255**2)
return similarity
except Exception as e:
raise ValueError(f"计算相似度时出错: {str(e)}")
# 主处理逻辑
try:
target_img = _read_image(target_image)
except Exception as e:
raise ValueError(f"无法读取目标图像: {target_image}, 错误: {str(e)}")
result = {
'found': False,
'similar_image': None,
'similarity': 0
}
# 获取文件夹中的所有图像文件
image_extensions = ['.jpg', '.jpeg', '.png', '.bmp', '.gif', '.tiff']
try:
image_files = [f for f in os.listdir(images_folder)
if os.path.isfile(os.path.join(images_folder, f)) and
os.path.splitext(f.lower())[1] in image_extensions]
except Exception as e:
raise ValueError(f"无法读取文件夹内容: {images_folder}, 错误: {str(e)}")
if not image_files:
print(f"警告: 文件夹 {images_folder} 中没有找到图像文件")
return result
# 比较目标图像与文件夹中的每张图像
highest_similarity = 0
most_similar_image = None
for image_file in image_files:
image_path = os.path.join(images_folder, image_file)
try:
img = _read_image(image_path)
similarity = _calculate_similarity(target_img, img)
if similarity > highest_similarity:
highest_similarity = similarity
most_similar_image = image_file
if similarity >= similarity_threshold:
result['found'] = True
result['similar_image'] = image_file
result['similarity'] = similarity
return result
except Exception as e:
print(f"处理图像 {image_file} 时出错: {str(e)}")
continue
# 如果没有找到超过阈值的相似图像,返回最相似的一个
if most_similar_image:
result['similar_image'] = most_similar_image
result['similarity'] = highest_similarity
return result
影刀指令说明
