python-3.x - 函数多、文件类型不同时出现“UnboundLocalError”如何解决?
问题描述
我的问题与另一个问题有关: 当文本文件位于不同文件夹中并与其他类型的文件混合时,如何使用 python 读取文本文件的内容?
我正在修改此处的代码:Classify_image with Coral dev board 它执行以下操作:
它接收 AI 算法的路径(一个 .tflite 文件,又名模型),
要分类的图像(.jpg 文件又名输入)的路径和
标签的路径(一个 .txt 文件又名标签)。
- 对图像进行分类并打印性能结果和时间。
但是必须手动插入所有这些文件的路径。像这样:
python3 classify_image.py \
--model models/mobilenet_v2_insect/mobilenet_v2_1.0_224_inat_insect_quant_edgetpu.tflite \
--labels models/mobilenet_v2_insect/inat_insect_labels.txt \
--input images/insect.jpg
我想执行许多模型(.tflite 文件)。每个模型都有不同的标签(.txt 文件)。并且每个模型都需要对不同的图像进行分类(.jgp 文件)。所以基本上我希望脚本顺序执行许多模型。我只会将文件放在不同的目录中(就像之前链接的问题一样)。最后,我想制作这样的情节:
到目前为止,我已经这样做了:
count = 2
rootdir = os.getcwd()
print(rootdir, "\n")
def load_label(path):
with open(path, 'r', encoding='utf-8') as f:
lines = f.readlines()
ret = {} #creates an empty dictionary
for row_number, content in enumerate(lines):
pair = re.split(r'[:\s]+', content.strip(), maxsplit=1)
#If there are only 2 elements AND the first one is a number:
#a) then store the number in the dictionary (as a "key" and convert it to an integer)
#and assign to it the other element as a "value"
#If the first element is not a number, then store the row's number as a key.
if len(pair) == 2 and pair[0].strip().isdigit():
ret[int(pair[0])] = pair[1].strip()
else:
ret[row_number] = pair[0].strip()
return ret
def make_interpreter(model_file):
model_file, *device = model_file.split('@')
return tflite.Interpreter(
model_path=model_file,
experimental_delegates=[
tflite.load_delegate(EDGETPU_SHARED_LIB,
{'device': device[0]} if device else {})
])
def main():
for root, subdirs, files in os.walk(rootdir):
for file in files:
#print(os.path.join(root, file), "\n")
filepath = os.path.join(root, file)
if filepath.endswith(".txt"):
#print(filepath, "\n")
labels = load_label(filepath)
#print(labels)
if filepath.endswith(".jpg"):
#print(filepath, "\n")
size = classify.input_size(interpreter)
image = Image.open(filepath).convert('RGB').resize(size, Image.ANTIALIAS)
classify.set_input(interpreter, image)
if filepath.endswith(".tflite"):
#print(filepath, "\n")
interpreter = make_interpreter(filepath)
interpreter.allocate_tensors()
print('----INFERENCE TIME----')
print('Note: The first inference on Edge TPU is slow because it includes',
'loading the model into Edge TPU memory.')
for _ in range(count):
start = time.perf_counter()
interpreter.invoke()
inference_time = time.perf_counter() - start
classes = classify.get_output(interpreter, top_k, threshold)
print('%.1fms' % (inference_time * 1000))
print('-------RESULTS--------')
for klass in classes:
print('%s: %.5f' % (labels.get(klass.id, klass.id), klass.score))
if __name__ == '__main__':
main()
我不知道如何解决它。我读到解决方案可能正在使用全局变量。或者也许创建另一个函数。
非常感谢任何见解。
#编辑
如果我将“解释器”作为全局变量:
def main():
global interpreter
for root, subdirs, files in os.walk(rootdir):
for file in files:
#print(os.path.join(root, file), "\n")
filepath = os.path.join(root, file)
我得到的错误是:
----INFERENCE TIME----
Note: The first inference on Edge TPU is slow because it includes loading the model into Edge TPU memory.
Traceback (most recent call last):
File "auto_benchmark_out.py", line 89, in <module>
main()
File "auto_benchmark_out.py", line 77, in main
interpreter.invoke()
NameError: name 'interpreter' is not defined
解决方案
看起来是以文档提到os.walk
的未指定顺序迭代文件。因此,看起来它正在选择文件在使用之前不被遍历的顺序,因此变量在使用之前不会被初始化。.tflite
interpreter
看起来有一个类似的错误classify
。
您可以尝试使用glob.glob
来获取以特定扩展名结尾的所有文件,但具有预期的顺序,例如
import glob
import os
def model_paths():
# All tflite files in the current directory
tflite_files = glob.glob("*.tflite")
# initialize before use
interpreter = make_interpreter(tflite_files[0])
# Or automatically grab other files from the directory of each tflite:
# This gets all tflite files in current directory and subdirectories
for tflite_path in glob.glob("**/*.tflite"):
current_directory = os.path.dirname(tflite_path)
# look for other files
# get the first text file in the same directory as the current tflite file
text_glob = os.path.join(current_directory, "*.txt")
text_path = glob.glob(text_glob)[0]
# get the first jpg file that matches the same criteria
jpg_glob = os.path.join(current_directory, "*.jpg")
jpg_path = glob.glob(jpg_glob)[0]
# do something with jpg_path, text_path, tflite_path
yield tflite_path, text_path, jpg_path
def main():
for tflite_path, text_path, jpg_path in model_paths():
pass # insert your processing code here
只需使用比本质上随机的行为更可靠的行为(如os.walk
)
推荐阅读
- javascript - 从 CSV 转换为 JSON 时如何从字符串更改为整数?
- c - 如何找到待处理的传入 UDP 数据包的数量?(网络相关)
- dataframe - 使用单个函数执行多个操作
- python - 从树数据结构中提取所有链
- javascript - 如何在打开modelDialog之前验证表单
- vba - 计算一个值在列中出现的次数并将该值返回到不同的工作表
- http - 如何在 Apollo GraphQl 中传递多个标头
- c# - 如何将此表达式转换为 LINQ
- javascript - toDoList 和搜索添加的项目后的问题,当输入为空时应该回到上一个索引位置
- powershell - 使用 Powershell 枚举 Azure 存储帐户