PIL ImageChops返回错误结果求助:图片分块对比代码异常
问题分析与修复方案
我看了你的代码,发现几个核心错误导致ImageChops的对比结果不符合预期,咱们一步步来梳理和修复:
1. 图像尺寸顺序搞反了
PIL中Image.size返回的是**(宽度, 高度)**,也就是正确的赋值应该是width, height = im1.size,但你写成了height,width = im1.size,这直接导致后续循环范围、裁剪区域全错,是最关键的问题。
2. 循环步长与裁剪参数错误
range()的步长必须是整数,你用height/25这类浮点数会触发报错,得转成整数类型。Image.crop()的参数格式是(left, upper, right, lower),你写的(h,w,height/25,height/25)完全不符合规则,正确的裁剪区域应该是从(h,w)开始,向右扩展块宽度、向下扩展块高度,也就是(h, w, h + 块宽, w + 块高)。
3. 重复创建Draw对象
你在循环里每次都重新创建draw = ImageDraw.Draw(im2),既没必要又降低效率,应该把这行代码移到循环外面。
修正后的完整代码
from PIL import Image, ImageDraw, ImageChops img1_path = r'/Users/siddharth/image1.png' img2_path = r'/Users/siddharth/image2.png' # 打开两张图片 im1 = Image.open(img1_path) # 原图 im2 = Image.open(img2_path) # 爬取的图片 # 正确获取宽高:size返回(width, height) width, height = im1.size # 定义分块的大小 block_width = int(width / 25) block_height = int(height / 20) # 只创建一次Draw对象,提升效率 draw = ImageDraw.Draw(im2) # 遍历所有块的左上角坐标 for h in range(0, width, block_width): # 处理最后一块可能不足block_width的情况,避免越界 current_block_width = block_width if h + block_width <= width else width - h for w in range(0, height, block_height): # 处理最后一块可能不足block_height的情况 current_block_height = block_height if w + block_height <= height else height - w # 裁剪对应区域 c_img1 = im1.crop((h, w, h + current_block_width, w + current_block_height)) c_img2 = im2.crop((h, w, h + current_block_width, w + current_block_height)) # 对比两个块,如果完全相同就绘制矩形 if ImageChops.difference(c_img1, c_img2).getbbox() is None: # 用红色边框标记相同区域,可自行调整颜色和线宽 draw.rectangle((h, w, h + current_block_width, w + current_block_height), outline="red", width=2) # 保存标记后的图片 im2.save('/Users/siddharth/marked_identical_regions.png')
补充说明:
- 我加了越界处理逻辑,避免最后一行/最后一列的块超出图片范围。
- 绘制矩形时指定了
outline和width参数,让标记边框更清晰,你可以根据需求调整颜色和线宽。
内容的提问来源于stack exchange,提问作者Siddharth Sonone
相关产品推荐
相关产品推荐

