批量处理文件夹图片边缘检测(Canny/Laplacian/HOG)报错求助
批量图片边缘检测与特征提取报错解决
问题描述
尝试对文件夹中的多张图片批量执行边缘检测,并应用Laplacian、HOG算子进行特征提取,但处理时触发错误。已将目录图片存入列表,执行Canny边缘检测时抛出断言错误。
原始代码
图片读取与预处理代码
import numpy as np import cv2 import os import matplotlib.pyplot as plt def resize(): data = [] img_size = 244 data_dir = r'C:\technocolab project2\testing' for img in os.listdir(data_dir): try: imgPath = os.path.join(data_dir,img) global images images = cv2.imread(imgPath, cv2.IMREAD_GRAYSCALE) global image_resized image_resized = cv2.resize(images,(img_size,img_size)) data.append(image_resized) except: pass return data data = resize() for i in range(len(data)): data[i]=data[i].astype('float32')
数据集划分与边缘检测代码
training = data[:int(0.2*len(data))] validation = data[int(0.2*len(data)):int(0.4*len(data))] testing = data[int(0.4*len(data)):int(0.5*len(data))] train_norm =[] valid_norm = [] test_norm = [] for a in range(len(training)): train_norm.append(training[a]/255) print(train_norm[0]) for b in range(len(validation)): valid_norm.append(validation[b]/255) print(valid_norm[0]) for c in range(len(testing)): test_norm.append(testing[c]/255) print(test_norm[0]) train_edge = [] for e in range(len(train_norm)): train_edge.append(cv2.Canny(train_norm[e],90,300))
报错信息(翻译后)
OpenCV(4.6.0) D:\a\opencv-python\opencv-python\opencv\modules\imgproc\src\canny.cpp:829: 错误: (-215:断言失败) _src.depth() == CV_8U in function 'cv::Canny'
错误原因
cv2.Canny函数要求输入图像的深度必须为CV_8U(8位无符号整数,像素值范围0-255),但代码中先将图像转换为float32类型,再归一化到0-1区间,传入Canny的是浮点型图像,不符合函数的输入要求。
解决方案
方案1:调整处理顺序(推荐)
先对原始8位灰度图执行边缘检测,再按需做归一化处理,避免类型不匹配问题:
# 修改resize函数,移除不必要的global变量,保留uint8类型图像 def resize(): data = [] img_size = 244 data_dir = r'C:\technocolab project2\testing' for img in os.listdir(data_dir): try: imgPath = os.path.join(data_dir,img) images = cv2.imread(imgPath, cv2.IMREAD_GRAYSCALE) image_resized = cv2.resize(images,(img_size,img_size)) data.append(image_resized) # 保留uint8类型 except Exception as e: print(e) # 打印错误信息,方便排查异常图片 return data data = resize() # 数据集划分 training = data[:int(0.2*len(data))] validation = data[int(0.2*len(data)):int(0.4*len(data))] testing = data[int(0.4*len(data)):int(0.5*len(data))] # 先执行边缘检测 train_edge = [] for img in training: train_edge.append(cv2.Canny(img, 90, 300)) # 再对原始图像和边缘检测结果做归一化(如果后续模型需要) train_norm = [img / 255.0 for img in training] train_edge_norm = [edge / 255.0 for edge in train_edge]
方案2:转换归一化后的图像类型
如果必须先做归一化,可将浮点型图像转换回8位无符号整数后再传入Canny:
# 针对已有的train_norm列表修改 train_edge = [] for img in train_norm: # 将0-1的浮点图像转换为0-255的8位整数图像 img_8u = (img * 255).astype('uint8') train_edge.append(cv2.Canny(img_8u, 90, 300))
额外优化点
- 移除代码中不必要的
global变量,避免全局变量污染,提升代码可读性。 - 异常处理时打印具体错误信息,方便排查无法读取的图片问题。
内容的提问来源于stack exchange,提问作者user19606377
相关产品推荐
相关产品推荐

