使用pickle保存skimage.regionprops加载遇递归错误,求保存方案
如何保存skimage的regionprops结果到磁盘?
你遇到的RecursionError是scikit-image的已知问题,regionprops返回的对象无法直接通过pickle完成序列化与反序列化,核心原因是对象内部的属性引用在反序列化过程中触发了无限递归。
下面提供几种可行的解决方案:
方案1:提取所需属性保存(推荐)
直接从regionprops对象中提取你实际需要的属性,存入普通字典后再序列化。这种方式既避免了对象序列化的问题,又能减少存储体积。
import numpy as np import pickle from skimage.draw import ellipse from skimage.measure import label, regionprops from skimage.transform import rotate # 生成测试图像 image = np.zeros((600, 600)) rr, cc = ellipse(300, 350, 100, 220) image[rr, cc] = 1 image = rotate(image, angle=15, order=0) rr, cc = ellipse(100, 100, 60, 50) image[rr, cc] = 1 label_img = label(image) regions = regionprops(label_img, image) # 提取需要的属性到字典列表 props_list = [] for region in regions: props = { 'area': region.area, 'centroid': region.centroid, 'bbox': region.bbox, 'major_axis_length': region.major_axis_length, 'minor_axis_length': region.minor_axis_length, # 根据需求添加其他属性 } props_list.append(props) # 保存到文件 with open('region_props.sav', 'wb') as f: pickle.dump(props_list, f) # 加载使用 with open('region_props.sav', 'rb') as f: loaded_props = pickle.load(f) # 示例:访问加载后的属性 for prop in loaded_props: print(f"区域面积:{prop['area']},质心:{prop['centroid']}")
方案2:保存原始数据,重新生成regionprops
如果需要保留regionprops的完整功能,可以保存label图像和原始强度图像,后续加载后重新计算属性:
# 保存label图像和原始图像 np.save('label_img.npy', label_img) np.save('original_image.npy', image) # 后续加载并重新生成regionprops loaded_label = np.load('label_img.npy') loaded_image = np.load('original_image.npy') saved_regions = regionprops(loaded_label, loaded_image)
方案3:临时hack解决序列化问题(版本依赖)
针对该bug,可在保存前手动解除regionprops对象内部的循环引用,但这种方法可能随scikit-image版本更新失效:
# 保存前处理每个region对象 for region in regions: region._intensity_image = None region._label_image = None # 序列化保存 with open('test.sav', 'wb') as f: pickle.dump(regions, f) # 加载后重新关联图像(若需要强度相关属性) loaded_image = np.load('original_image.npy') loaded_label = np.load('label_img.npy') with open('test.sav', 'rb') as f: saved_regions = pickle.load(f) for region in saved_regions: region._intensity_image = loaded_image region._label_image = loaded_label
内容的提问来源于stack exchange,提问作者toto
相关产品推荐
相关产品推荐

