AttributeError: 'NoneType'无shape属性——单图与多图SSIM对比故障排查
问题分析与修复
你的错误根源是读取图片时用了文件名而非完整路径:
你已经用os.path.join生成了正确的完整路径f_path和f2_path,但在读取imageA和imageB时,错误传入了仅含文件名的first_file和second_file,导致cv2.imread找不到文件、返回None,最终触发AttributeError: 'NoneType' object has no attribute 'shape'。
修复后的完整脚本
from skimage.metrics import structural_similarity as ssim import cv2 import os first_dir = r'C:\Users\xx\Downloads\Sample images\subject' second_dir = r'C:\Users\xx\Downloads\Sample images\noise' results = [] # 初始化结果存储列表 # 遍历subject文件夹中的图片 for first_file in os.listdir(first_dir): f_path = os.path.join(first_dir, first_file) if not f_path.endswith(".png"): continue # 跳过非PNG文件 # 读取基准图片(完整路径) imageA = cv2.imread(f_path, 0) if imageA is None: print(f"无法读取图片:{f_path}") continue # 遍历noise文件夹中的图片对比 for second_file in os.listdir(second_dir): f2_path = os.path.join(second_dir, second_file) if not f2_path.endswith(".png"): continue # 读取对比图片(完整路径) imageB = cv2.imread(f2_path, 0) if imageB is None: print(f"无法读取图片:{f2_path}") continue # 确保两张图片尺寸一致(SSIM要求输入尺寸相同) if imageA.shape != imageB.shape: imageB = cv2.resize(imageB, (imageA.shape[1], imageA.shape[0])) print(f"已调整图片 {f2_path} 尺寸匹配 {f_path}") # 计算SSIM score, diff = ssim(imageA, imageB, full=True) results.append((first_file, second_file, score)) print(f"{first_file} vs {second_file} SSIM值: {score:.4f}") # 打印所有结果 print("\n所有对比结果:") for res in results: print(f"{res[0]} 和 {res[1]} 的SSIM值:{res[2]:.4f}")
关键修复点
- 使用完整路径读取图片:将
imageA = cv2.imread(first_file, 0)改为imageA = cv2.imread(f_path, 0),imageB同理使用f2_path。 - 增加图片读取校验:判断
imageA/imageB是否为None,避免后续流程报错。 - 确保图片尺寸一致:SSIM要求两张输入图片尺寸完全相同,补充尺寸校验与调整逻辑。
- 初始化结果列表:原脚本中
results.append前未定义列表,补充初始化步骤。
额外说明
如果想改用PIL.Image.open方法,只需把cv2.imread替换为np.array(PIL.Image.open(path).convert('L'))(转为灰度图数组),核心逻辑保持一致即可。
内容的提问来源于stack exchange,提问作者Expired_rice
相关产品推荐
相关产品推荐

