numpy报IndexError: index 589越界错误如何排查修复
问题诊断
- 代码里
All_Images = np.zeros((589,imgDWTsize,imgDWTsize))的参数589是手动硬编码的、预分配给NumPy三维数组的第一维度长度,也就是预设的最多可以存储的图像总数量,数组后两个维度对应单张图像的高、宽(和设置的imgDWTsize=100匹配)。 - 索引越界的根因非常明确:实际遍历
PATH目录读取到的图片总数量,超过了硬编码的589上限。NumPy数组创建后大小固定,第一维度的合法索引范围是0~588,当循环里的count变量累加到589时,执行All_Images[count,:,:] = NewImg3就会直接触发越界错误。
589属于无依据的魔法值,没有和实际数据集的图片总数做绑定,只要数据集图片总数大于这个值,报错是必然结果。
- 额外隐患:当前代码没有过滤
os.listdir()返回的非目录文件、也没有判断cv2.imread()是否读取成功,遇到隐藏文件、损坏图片时还会触发其他类型报错。
修复方案
方案1:提前统计图片总数再预分配数组(性能优,适合大数据集)
先遍历统计数据集下的有效图片总数,用实际统计值替换硬编码的589,再执行后续读取逻辑:
import os import numpy as np import cv2 imgResize = 100 imgDWTsize = 100 # 替换成实际的数据集路径 PATH = "your_dataset_path" classesNames = os.listdir(PATH) # 先统计有效图片总数 total_img = 0 for className in classesNames: classPath = os.path.join(PATH, className) # 过滤非目录文件 if os.path.isdir(classPath): total_img += len(os.listdir(classPath)) # 用实际总数替换硬编码589 All_Images = np.zeros((total_img, imgDWTsize, imgDWTsize)) All_Images_Label = [] count = 0 for className in classesNames: classPath = os.path.join(PATH, className) if not os.path.isdir(classPath): continue img_names = os.listdir(classPath) for ImgN in img_names: ImgPath = os.path.join(classPath, ImgN) img = cv2.imread(ImgPath) # 过滤读取失败的损坏图片 if img is None: continue img1 = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) img1 = cv2.resize(img1, (imgResize, imgResize)) img1 = np.float32(img1) img1 /= 255 NewImg3 = img1 All_Images[count,:,:] = NewImg3 Label = int(className) - 1 All_Images_Label.append(Label) count +=1 if count % 50 == 0: print(count) print('X_data shape:', All_Images.shape)
方案2:列表动态追加(写法简单,适合小数据集)
如果数据集规模不大,可以不用提前预分配固定大小的NumPy数组,先用列表动态存储读取到的图片,全部读取完成后再转成NumPy数组,完全不需要提前计算图片总数,从根源避免索引越界:
import os import numpy as np import cv2 imgResize = 100 imgDWTsize = 100 # 替换成实际的数据集路径 PATH = "your_dataset_path" All_Images = [] All_Images_Label = [] classesNames = os.listdir(PATH) for className in classesNames: classPath = os.path.join(PATH, className) if not os.path.isdir(classPath): continue img_names = os.listdir(classPath) for ImgN in img_names: ImgPath = os.path.join(classPath, ImgN) img = cv2.imread(ImgPath) if img is None: continue img1 = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) img1 = cv2.resize(img1, (imgResize, imgResize)) img1 = np.float32(img1) img1 /= 255 NewImg3 = img1 # 直接追加到列表,不需要维护count索引 All_Images.append(NewImg3) Label = int(className) - 1 All_Images_Label.append(Label) # 全部读取完成后转NumPy数组 All_Images = np.array(All_Images) print('X_data shape:', All_Images.shape)
内容的提问来源于stack exchange,提问作者diseased dates
相关产品推荐
相关产品推荐

