简体   繁体   English

Python - 分配错误之前引用的局部变量

[英]Python - Local variable referenced before assignment error

I am trying to adopt mask_rcnn original code to my dataset.The original code takes xml files and I just modified my code to accept json format.我正在尝试将 mask_rcnn 原始代码用于我的数据集。原始代码采用 xml 文件,我只是修改了我的代码以接受 json 格式。 Here is the code这是代码


   def load_mask(self, image_id, xml=False):
        # get details of image
        info = self.image_info[image_id]

        if xml:
            # define anntation  file location
            path = info['annotation']
            # load XML
            boxes, w, h = self.extract_boxes(path, xml=True)
        else:
            with open('D:\Mask_RCNN\Mask_RCNN\dataset\\annots\\annotations.json', 'r') as f:
                annots = json.load(f)
                found = False
                for value in annots.values():
                    if 'image' in value and value['instance_list']:
                        if value['image']['original_filename'][:-3] == info['id']:
                            boxes, w, h = self.extract_boxes(value)
                            found = True
                            break

        if found:
            # create one array for all masks, each on a different channel
            masks = zeros([h, w, len(boxes)], dtype='uint8')
        else:
            stop = "here"

                if found:
            # create one array for all masks, each on a different channel
            masks = zeros([h, w, len(boxes)], dtype='uint8')
        else:
            stop = "here"

        # create masks
        class_ids = list()
        for i in range(len(boxes)):
            box = boxes[i]
            row_s, row_e = box[1], box[3]
            col_s, col_e = box[0], box[2]
            masks[row_s:row_e, col_s:col_e, i] = 1
            class_ids.append(self.class_names.index('Penquins'))
        return masks, asarray(class_ids, dtype='int32')

    # load an image reference
        #"""Return the path of the image."""
    def image_reference(self, image_id):
            info = self.image_info[image_id]
            print(info)
            return info['path']

It gives me the error它给了我错误

File "C:/PycharmProjects/Mask_RCNN/Mask_RCNN/objects.py", line 197, in load_mask文件“C:/PycharmProjects/Mask_RCNN/Mask_RCNN/objects.py”,第 197 行,在 load_mask
for i in range(len(boxes)): UnboundLocalError: local variable 'boxes' referenced before assignment for i in range(len(boxes)): UnboundLocalError: 局部变量“boxes”在赋值前被引用

I tried to debug the code,its throwing an error before creating masks but I am not able to figure out whats wrong.我试图调试代码,它在创建掩码之前抛出错误,但我无法弄清楚出了什么问题。 Any idea?任何的想法?

Only if xml is true, it is guaranteed, that boxes gets a value.只有当xml为真时,才能保证 box 获得一个值。 Otherwise additional conditions have to be fulfilled, which does not seem to be the case.否则必须满足附加条件,这似乎并非如此。

boxes is initialized in some of the scenarios in load_mask 's first if else block, which means it might not exists when you reach if found: .load_mask的第一个if else块中的一些场景中, boxes被初始化,这意味着当你到达if found:时它可能不存在。 Just declare it in the beginning一开始就声明

def load_mask(self, image_id, xml=False):
    # get details of image
    info = self.image_info[image_id]
    boxes = []

It means that you are trying to iterate over the number of boxes , but your if statements above are constructed in such a way that boxes might not exit by the time this statement gets executed.这意味着您正在尝试遍历boxes的数量,但是上面的 if 语句的构造方式使得在执行此语句时boxes可能不会退出。

try this simple example:试试这个简单的例子:

user_input = "no"

if user_input =="yes":
    boxes = [1,2,3,4]
else:
    pass

print(boxes)

This will result in the same error as you are seeing.这将导致与您所看到的相同的错误。 Your problem is that both of these if statements must pass before boxes is defined:您的问题是这两个 if 语句都必须在定义boxes之前通过:

           if 'image' in value and value['instance_list']:
                if value['image']['original_filename'][:-3] == info['id']:

Likely you either need additional logic that ensures the iteration only occurs if certain conditions are met.您可能需要额外的逻辑来确保仅在满足某些条件时才会进行迭代。 Or, if boxes is a list you could start your code by defining boxes=[] .或者,如果boxes是一个列表,您可以通过定义boxes=[]来开始您的代码。 In that case the iteration will simply pass over without doing anything as the length of boxes is zero in that case在这种情况下,迭代将简单地跳过而不做任何事情,因为在这种情况下boxes的长度为零

The problem is that boxes isnt getting declared in line of this for loop, so define boxes as an empty list in the first part of the function问题是在此 for 循环的行中未声明框,因此在函数的第一部分中将框定义为空列表

def load_mask(self, image_id, xml=False):
    boxes = []
    #do all the other stuff here

Then when you do the for loop it should now be declared (unless one of the functions don't return the boxes and give you something else)然后当你执行 for 循环时,它现在应该被声明(除非其中一个函数不返回框并给你其他东西)

Quick tip when doing the for loop, you can do执行 for 循环时的快速提示,您可以执行

for i, box in enumerate(boxes):
    ...

which will not make you define box inside the loop (i will be 0 to len(boxes)-1 and box will be the box with that index)这不会让你在循环内定义框(我将是 0 到 len(boxes)-1 并且框将是具有该索引的框)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM