一张 1080x9600 的订单长截图,按高 1600 切成 6 块,块间重叠 100 像素,模型返回 bbox 坐标,映射回原图后越往下偏得越多,最后一块偏了 80 像素,标注框整体压到下一行。

一开始怀疑是「最后一块高度不足 1600,裁剪起点算错」,查了一圈,方向不对。

这类报错背后常见的原因有几处,逐个排除就行。还原时直接把块内坐标加上固定步长,忽略了重叠部分。也可能是模型输入做了等比缩放,返回坐标基于缩放后的尺寸。

不容易想到的是,把重叠区的内容重复计入行数。

动手时先记录每一块的真实裁剪框

python -c "H=9600;h=1600;ov=100;[print(i, i*(h-ov), min(i*(h-ov)+h,H)) for i in range(6)]"

再往下确认模型输入是否被缩放

python -c "from PIL import Image;im=Image.open('tile_0.png');print(im.size)"

然后按偏移加缩放比例还原坐标

python -c "def back(y,off,scale): return int(y*scale)+off;print([back(120,i*1500,1.0) for i in range(3)])"

末了把还原后的框画回原图抽查

python -c "from PIL import Image,ImageDraw;im=Image.open('long.png');d=ImageDraw.Draw(im);d.rectangle([10,1600,300,1700],outline='red');im.crop((0,1500,1080,1900)).save('check.png')"

改完先别撤,确认这几项。六个块的标注框在拼回的长图上位置连续,跨块的行不被截断,最后一块的偏移量与其他块一致。

容易忽略的是,切片方案要连坐标映射一起设计,偏移、重叠、缩放三个量任何一个漏掉都会累加放大,越靠后的块错得越明显。监控比日志更早给出信号,事后回看经常能提前半小时发现异常。

作者 9823189