import cv2
import numpy as np
import os
def calculate_black_pixels_in_sectors(image,sector):
# 将图像转换为二值图像
_, image = cv2.threshold(image, 127, 255, cv2.THRESH_BINARY_INV)
# 获取图像尺寸
height, width = image.shape
# 计算几何中心
center_x, center_y = width // 2, height // 2
# 定义角度间隔
angle_step = 360 / sector
# 存储每个扇区的黑色像素数量
black_pixel_counts = np.zeros(sector)
# 循环遍历36个扇区
for i in range(sector):
# 计算当前扇区的角度范围
start_angle = np.deg2rad(i * angle_step)
end_angle = np.deg2rad((i + 1) * angle_step)
# 创建一个掩码,用于提取当前扇区内的像素
y, x = np.ogrid[:height, :width]
mask = ((x - center_x) * np.cos(start_angle) + (y - center_y) * np.sin(start_angle) >= 0) & \
((x - center_x) * np.cos(end_angle) + (y - center_y) * np.sin(end_angle) <= 0)
# 计算当前扇区内的黑色像素数量
black_pixel_counts[i] = np.sum(image[mask] == 0)
return black_pixel_counts
def compare_images(image_path1, image_path2, pixel_threshold, sector_threshold,sector):
# 读取图像并转换为灰度
image1 = cv2.imread(image_path1, cv2.IMREAD_GRAYSCALE)
image2 = cv2.imread(image_path2, cv2.IMREAD_GRAYSCALE)
# 计算两张图像每个扇区的黑色像素数量
black_pixels1 = calculate_black_pixels_in_sectors(image1,sector)
black_pixels2 = calculate_black_pixels_in_sectors(image2,sector)
# 比较两个图像的黑色像素分布
diff = np.abs(black_pixels1 - black_pixels2)
# 检查有多少个扇区的差异没有超过像素阈值
num_similar_sectors = np.sum(diff <= pixel_threshold)
# 计算相似扇区的百分比
similarity_percentage = (num_similar_sectors / len(black_pixels1)) * 100
# 检查超过像素阈值的扇区数量是否超过了数量阈值
num_exceeding_sectors = np.sum(diff > pixel_threshold)
is_within_sector_threshold = num_exceeding_sectors <= sector_threshold
return similarity_percentage, is_within_sector_threshold
def compare_directories(dirA, dirB, pixel_threshold, sector_threshold,similarity_threshold):
# 确保两个目录存在
if not os.path.exists(dirA) or not os.path.exists(dirB):
raise ValueError("One or both directories do not exist.")
# 获取目录列表
dirsA = os.listdir(dirA)
dirsB = os.listdir(dirB)
# 只保留两个目录共有的子目录名称
common_dirs = list(set(dirsA).intersection(set(dirsB)))
results = {}
unmatched_files_A = {}
unmatched_files_B = {}
high_similarity_pairs = []
for common_dir in common_dirs:
pathA = os.path.join(dirA, common_dir)
pathB = os.path.join(dirB, common_dir)
# 获取两个子目录下的文件列表
filesA = os.listdir(pathA)
filesB = os.listdir(pathB)
# 只保留两个子目录共有的文件名称
common_files = list(set(filesA).intersection(set(filesB)))
for file_name in common_files:
img_path_A = os.path.join(pathA, file_name)
img_path_B = os.path.join(pathB, file_name)
# 调用 compare_images 函数
similarity, within_threshold = compare_images(img_path_A, img_path_B, pixel_threshold, sector_threshold,sector)
# 保存结果
if common_dir not in results:
results[common_dir] = {}
results[common_dir][file_name] = {'similarity': similarity, 'within_threshold': within_threshold}
# 检查相似度是否超过阈值
if similarity >= similarity_threshold:
high_similarity_pairs.append((img_path_A, img_path_B, similarity))
# 统计未匹配的文件
unmatched_files_A[common_dir] = list(set(filesA) - set(common_files))
unmatched_files_B[common_dir] = list(set(filesB) - set(common_files))
# 添加未匹配文件的统计结果
results['unmatched_files_A'] = unmatched_files_A
results['unmatched_files_B'] = unmatched_files_B
# 将高相似度的图片对路径添加到结果中
results['high_similarity_pairs'] = high_similarity_pairs
return results
# # 使用函数
# image_path1 = r'imgB/01_1.jpg'
# image_path2 = r'imgB/03_3.jpg'
# pixel_threshold = 100 # 单个扇区像素差异阈值
# sector_threshold = 5 # 超过像素差异阈值的扇区数量阈值
# similarity, within_threshold = compare_images(image_path1, image_path2, pixel_threshold, sector_threshold)
# if within_threshold:
# print(f"Images are {similarity:.2f}% similar in their black pixel distribution and the number of exceeding sectors is within the threshold.")
# else:
# print(f"Images are {similarity:.2f}% similar in their black pixel distribution but the number of exceeding sectors exceeds the threshold.")
# 使用函数
dirA = 'imgA'
dirB = 'imgB'
pixel_threshold = 50
sector_threshold = 5
sector=72
similarity_threshold = 70
# 使用函数
results = compare_directories(dirA, dirB, pixel_threshold, sector_threshold,similarity_threshold)
# 输出结果
for dir_name, files in results.items():
# 如果当前项是字典类型并且不是unmatched_files_A或unmatched_files_B
if isinstance(files, dict) and dir_name not in ('unmatched_files_A', 'unmatched_files_B'):
print(f"Directory: {dir_name}")
for file_name, info in files.items():
print(f" File: {file_name}, Similarity: {info['similarity']:.2f}%, Within Threshold: {info['within_threshold']}")
# 输出未匹配的文件
if 'unmatched_files_A' in results:
print("\nUnmatched files in imgA:")
for dir_name, files in results['unmatched_files_A'].items():
print(f" Directory: {dir_name}")
for file_name in files:
print(f" File: {file_name}")
if 'unmatched_files_B' in results:
print("\nUnmatched files in imgB:")
for dir_name, files in results['unmatched_files_B'].items():
print(f" Directory: {dir_name}")
for file_name in files:
print(f" File: {file_name}")
# 输出高相似度的图片对
if 'high_similarity_pairs' in results:
print("\nHigh Similarity Pairs:")
for imgA, imgB, sim in results['high_similarity_pairs']:
print(f" Pair: {os.path.basename(imgA)} and {os.path.basename(imgB)}, Similarity: {sim}%")
标签:files,name,similarity,python,results,unmatched,版本,threshold,对比
From: https://www.cnblogs.com/DINGJINXING/p/18288933