Question about data exchange between threads

Issue

I am trying to make a motor control system using Object Detection. I have two threads, one for object detection and one for GUI.

Here is the code for object detection

#execute object detection model in real time
def tfod_window():
    global coordinates, class_name, named_coordinates

    category_index = label_map_util.create_category_index_from_labelmap(files['LABELMAP'])


    while cap.isOpened(): 
        ret, frame = cap.read()
        image_np = np.array(frame)
        
        input_tensor = tf.convert_to_tensor(np.expand_dims(image_np, 0), dtype=tf.float32)
        detections = detect_fn(input_tensor)
        
        num_detections = int(detections.pop('num_detections'))
        detections = {key: value[0, :num_detections].numpy()
                      for key, value in detections.items()}
        detections['num_detections'] = num_detections

        # detection_classes should be ints.
        detections['detection_classes'] = detections['detection_classes'].astype(np.int64)

        label_id_offset = 1
        image_np_with_detections = image_np.copy()

        viz_utils.visualize_boxes_and_labels_on_image_array(
                    image_np_with_detections,
                    detections['detection_boxes'],
                    detections['detection_classes']+label_id_offset,
                    detections['detection_scores'],
                    category_index,
                    use_normalized_coordinates=True,
                    max_boxes_to_draw=5,
                    min_score_thresh=.8,
                    agnostic_mode=False)

        cv2.imshow('object detection',  cv2.resize(image_np_with_detections, (800, 600)))

        #get the coordinates of the detection boxes
        boxes = detections['detection_boxes']
        max_boxes_to_draw = boxes.shape[0]
        scores = detections['detection_scores']
        min_score_thresh=.8

        coordinates=[]
        class_name=[]
        named_coordinates=[]

        for i in range(min(max_boxes_to_draw, boxes.shape[0])):
            if scores[i] > min_score_thresh:
                class_id = int(detections['detection_classes'][i] + 1)
                coordinates.append(boxes[i])
                class_name.append(category_index[class_id]["name"])
                named_coordinates.append({
                                "box": boxes[i],
                                "class_name": category_index[class_id]["name"],
                            })

        if cv2.waitKey(10) & 0xFF == ord('q'):
            cap.release()      
            cv2.destroyAllWindows()
            break

However when I want to use coordinates in another thread, it shows ”’NameError: name ‘class_name’ is not defined”’.

The code for another thread is

def GUI():
    while cap.isOpened():
        if len(class_name) > 0:
            print(class_name)

t1 = Thread(target=tfod)
t2 = Thread(target=GUI)

t1.start()
t2.start() 

Please Help!! Thank you!!

Solution

From the comments: class_name was not declared/initialized before the t2 thread tried to access it.

You can place a single initial line of code defining class_name near the top of the program, and this will avoid this error.

For those who may see this page, the error is not super relevant to the title, but here is a post that does discuss how to properly share data between threads.

Answered By – M Z

This Answer collected from stackoverflow, is licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply

(*) Required, Your email will not be published