如何使用OpenCV裁剪单张图像内多个对象对应的边界框区域
问题原因与修复方案
报错核心原因
OpenCV抛出
!_img.empty() in function 'imwrite'错误,本质是待写入的裁剪图像为空数组,未通过合法性校验。
触发问题的核心诱因
- 边界框坐标非法:你提供的CSV样例中第二行x_min为-442,属于超出图像左边界的负值,OpenCV做数组切片时如果坐标超出图像尺寸范围、或者出现x_min>x_max/y_min>y_max的情况,都会返回空数组。
- 冗余读图+潜在路径错误:当前代码中同一张图片对应多个边界框时,会重复读取多次,既浪费性能,也容易因为相对路径匹配问题导致
cv2.imread返回None,后续切片自然为空。
修复代码
import pandas as pd import cv2 import os # 替换为你的图片所在文件夹绝对路径,避免读取失败 img_root = "./" df = pd.read_csv("Camera_1.csv") # 按图片名分组,同一张图仅读取一次 for img_name, group in df.groupby("Name"): img_path = os.path.join(img_root, img_name) img = cv2.imread(img_path) if img is None: print(f"警告:图像{img_name}读取失败,跳过处理") continue h, w = img.shape[:2] # 批量处理当前图像的所有边界框 for idx, row in group.iterrows(): xmin, xmax, ymin, ymax = row['x_min'], row['x_max'], row['y_min'], row['y_max'] # 坐标合法性钳位:保证坐标在图像范围内,且最小值小于最大值 xmin = max(0, min(xmin, w-1)) xmax = max(xmin+1, min(xmax, w)) ymin = max(0, min(ymin, h-1)) ymax = max(ymin+1, min(ymax, h)) # 画框+裁剪 cv2.rectangle(img, (xmin, ymin), (xmax, ymax), (0,255,0), 2) cropped_img = img[ymin:ymax, xmin:xmax] if cropped_img.size == 0: print(f"警告:图像{img_name}的第{idx}个框裁剪结果为空,跳过保存") continue # 按规则命名保存 save_name = f"{row['Labels']}_labels_{idx}.png" cv2.imwrite(save_name, cropped_img)
额外注意事项
- 读取CSV时建议明确指定分隔符,确保pandas正确识别x_min、x_max等字段,避免字段错位导致坐标异常。
- 如果边界框是由中心点+宽高格式转换得到,建议提前校验转换逻辑,避免出现坐标大小反转的逻辑错误。
内容的提问来源于stack exchange,提问作者Ahmed900
相关产品推荐
相关产品推荐

