循环处理多列表:numpy shape调用需索引?求优化实现方案
优化方案说明
首先要提一句:你那个能运行的代码其实有隐藏bug——每次循环都会把x重置为0,所以不管读多少张图,needle_widths和needle_heights里存的都是第一张图的尺寸,只是可能你测试用的图尺寸相同没发现而已。
你最初的写法报错,是因为self.needle_images是Python列表,没有shape属性——shape是OpenCV读取返回的numpy数组才有的属性,得先拿到单张图片的数组再取尺寸。
下面给你几种更合理的实现方式:
方案1:最直观的修正(推荐新手优先用)
每次读取图片后先存在变量里,再分别添加到各个列表,完全不用操作列表索引,清晰又避免错误:
for item_template in ItemTemplates: img = cv.imread(item_template, cv.IMREAD_UNCHANGED) self.needle_images.append(img) self.needle_widths.append(img.shape[1]) self.needle_heights.append(img.shape[0])
(顺便提下:Python惯例里变量名用小写蛇形命名,ItemTemplate改成item_template更规范)
方案2:更Pythonic的简洁写法
把加载逻辑封装成函数,用生成器配合zip一次性构建三个列表,减少循环里的重复代码:
def load_template(path): img = cv.imread(path, cv.IMREAD_UNCHANGED) return img, img.shape[1], img.shape[0] # 一次性解包生成三个序列(默认是元组,需要列表的话转一下) self.needle_images, self.needle_widths, self.needle_heights = zip(*(load_template(p) for p in ItemTemplates)) self.needle_images = list(self.needle_images) self.needle_widths = list(self.needle_widths) self.needle_heights = list(self.needle_heights)
方案3:用数据类统一存储(可选)
如果后续需要把图片和它的宽高绑定使用,用dataclasses会更清晰,避免维护三个独立列表的麻烦:
from dataclasses import dataclass @dataclass class NeedleTemplate: image: any width: int height: int self.needle_templates = [] for item_template in ItemTemplates: img = cv.imread(item_template, cv.IMREAD_UNCHANGED) self.needle_templates.append(NeedleTemplate(img, img.shape[1], img.shape[0]))
之后取宽高直接用template.width、template.height,比单独维护三个列表更不容易出错。
内容的提问来源于stack exchange,提问作者Busta
相关产品推荐
相关产品推荐

