使用OpenCV对zip压缩包内图像做自适应阈值时出现medianBlur断言错误
报错原因排查
这个错误(-215:Assertion failed) !_src0.empty() in function 'cv::medianBlur'的核心是传入cv2.medianBlur的图像变量是空值,OpenCV没有读取到有效图像内容,具体触发原因如下:
- 代码逻辑结构错误:你将图像转换、滤波、阈值处理的逻辑全部写在了
for循环外部,循环仅执行了读取图像的赋值操作,循环结束后img仅保留最后一个文件的读取结果,一旦最后一个条目不是有效图像就会触发报错。 - 读取到非图像文件:
os.listdir会遍历目标路径下的所有条目,包括压缩包解压常见的附属文件夹(如__MACOSX)、系统缓存文件(如Thumbs.db)、子目录等,cv2.imread读取非图像内容时不会主动抛出异常,只会返回空值None。 - 隐藏格式问题:
cv2.adaptiveThreshold要求输入为单通道灰度图,你当前直接传入cv2.imread默认读取的三通道BGR图像,即使解决空图问题后续也会触发格式报错。
解决方法
按照以下步骤修改代码即可解决问题:
- 将所有图像处理逻辑移入
for循环内部,逐张处理图像 - 读取文件前先校验文件后缀,过滤非图像文件和子目录
- 图像读取后新增空值判断,跳过读取失败的损坏文件
- 三通道图像转灰度图后再执行阈值处理
修正后完整代码
from zipfile import ZipFile import os import cv2 file = "C:/Users/User/Downloads/cyc001_reg002.zip" image_file = "C:/Users/User/Downloads/images" # 支持的图像后缀 IMG_EXT = ['.jpg', '.jpeg', '.png', '.bmp', '.tif', '.tiff'] # 解压压缩包 with ZipFile(file, 'r') as z: z.extractall(image_file) # 逐张处理图像 for i in os.listdir(image_file): img_path = os.path.join(image_file, i) # 跳过子目录 if not os.path.isfile(img_path): continue # 跳过非图像后缀文件 ext = os.path.splitext(i)[-1].lower() if ext not in IMG_EXT: print(f"跳过非图像文件:{i}") continue # 读取图像,加参数0直接读取为灰度图 img = cv2.imread(img_path, 0) # 空图判断 if img is None or img.size == 0: print(f"读取失败,跳过损坏文件:{i}") continue # 图像处理流程 img = cv2.convertScaleAbs(img) img = cv2.medianBlur(img, 5) ret, th1 = cv2.threshold(img, 127, 255, cv2.THRESH_BINARY) th2 = cv2.adaptiveThreshold(img, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 11, 2) th3 = cv2.adaptiveThreshold(img, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 11, 2) # 此处可新增结果保存、展示逻辑 # cv2.imwrite(os.path.join(image_file, f"result_{i}"), th3)
内容的提问来源于stack exchange,提问作者melololo
相关产品推荐
相关产品推荐

