variable inside function not defined despite having it defined globally

Question:

I define my dictionary ‘frame_dict’ outside my for loop. However, when it gets to my forFrame function, despite setting it has a global variable, I get an error saying that frame_dict is not defined. Any help?

import os
from imageai.Detection import VideoObjectDetection
import pickle


PATH_TO_STORE_VIDEOS = "/Users/jaime.pereira/Library/CloudStorage/OneDrive-OneWorkplace/Benchmark_Project/Videos"

tv_commercial_videos = os.listdir('Videos/')


def yolo_neural_network(path_to_videos, tv_commercials):

        execution_path = os.getcwd()
        frame_dict = {}

        for tv_c in tv_commercials:
            frame_dict.setdefault(tv_c,[])

            # Use pre trained neural network to label things in videos
            vid_obj_detect = VideoObjectDetection()
            # Set and load Yolo model
            vid_obj_detect.setModelTypeAsYOLOv3()
            vid_obj_detect.setModelPath(os.path.join(execution_path,"yolov3.pt"))
            vid_obj_detect.loadModel()

            input_file_path = os.path.join(path_to_videos, tv_c)

            if not os.path.exists("output_from_model_yolov3/"):
                os.makedirs("output_from_model_yolov3/")
            output_file_path = os.path.join(execution_path,"output_from_model_yolov3/", "model_yolov3_output_" + tv_c)


            def forFrame(frame_number, output_array, output_count):
                global frame_dict
                frame_dict[tv_c].append(output_count)
                return frame_dict
            
            vid_obj_detect.detectObjectsFromVideo(
                            input_file_path=input_file_path,
                            output_file_path=output_file_path,
                            log_progress=True,
                            frame_detection_interval= 60,
                            minimum_percentage_probability=70,
                            per_frame_function=forFrame,
                            save_detected_video=True
                            )

        # save dictionary
        f = open("yolo_dict.pkl", "wb")

        # write dict to pickle file
        pickle.dump(frame_dict, f)

        # close file
        f.close()   

        return frame_dict

yolo = yolo_neural_network(PATH_TO_STORE_VIDEOS, tv_commercial_videos)
Exception has occurred: ValueError
An error occured. It may be that your input video is invalid. Ensure you specified a proper string value for 'output_file_path' is 'save_detected_video' is not False. Also ensure your per_frame, per_second, per_minute or video_complete_analysis function is properly configured to receive the right parameters. 
  File "/Users/jaime.pereira/Library/CloudStorage/OneDrive-OneWorkplace/Benchmark_Project/debug.py", line 35, in forFrame
    frame_dict[tv_c].append(output_count)
NameError: name 'frame_dict' is not defined

During handling of the above exception, another exception occurred:

  File "/Users/jaime.pereira/Library/CloudStorage/OneDrive-OneWorkplace/Benchmark_Project/debug.py", line 38, in yolo_neural_network
    vid_obj_detect.detectObjectsFromVideo(
  File "/Users/jaime.pereira/Library/CloudStorage/OneDrive-OneWorkplace/Benchmark_Project/debug.py", line 59, in <module>

I tried setting my frame_dict variable as global inside the forframe function expecting it to recognise it.

Asked By: Jaime Ken Pereira

||

Answers:

The problem you are facing is that frame_dict is actually not a global variable. It is defined inside of yolo_neural_network. While this is indeed outside forFrame, it is not a global variable.

In this scenario, you should simply remove the global statement, because it is not a global variable you are importing.

Answered By: Berlm

frame_dict is not a global, it is just in an outer scope, remove global keyword

Since you mutate the object, you don’t need to do anything more:

            def forFrame(frame_number, output_array, output_count):
                frame_dict[tv_c].append(output_count)
                return frame_dict

Since you don’t assign anything to frame_dict, even if the variable were a global variable, you wouldn’t need to add the global keyword if you mutate the object. global is useful only if you need to assign a new value to the variable.

Answered By: Dorian Turba
Categories: questions Tags:
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.