首页 > 解决方案 > 函数多、文件类型不同时出现“UnboundLocalError”如何解决?

问题描述

我的问题与另一个问题有关: 当文本文件位于不同文件夹中并与其他类型的文件混合时,如何使用 python 读取文本文件的内容?

我正在修改此处的代码:Classify_image with Coral dev board 它执行以下操作:

但是必须手动插入所有这些文件的路径。像这样:

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

标签: python-3.x

解决方案


看起来是以文档提到os.walk的未指定顺序迭代文件。因此,看起来它正在选择文件在使用之前不被遍历的顺序,因此变量在使用之前不会被初始化。.tfliteinterpreter

看起来有一个类似的错误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


推荐阅读