'How do I return a value outside of a thread?

I'm trying to return a continuous stream of frames to perform object detection. I want this continuous stream of frames to run at the same time as a number of other GUI interactions and detections, I tried using both concurrent.futures and multiprocessing and ran into road-blocks with both pointed out by members of stack. I'm now trying to use threading to achieve this.

The below code will correctly return a continuous stream of frames and display those frames.

I can print and interact with those frames from within main but I can't seem to return frame to use it outside of main

How do I return main outside of my thread?

def videoLoop():
    # Grab window and find size and crop it
    window = pygetwindow.getWindowsWithTitle('Notepad')[0]
    x1 = window.left
    y1 = window.top
    height = window.height
    width = window.width
    x2 = x1 + width
    y2 = y1 + height
    # Actual Video Loop, cropped down to the specific window,
    # resized to 1/2 size, and converted to BGR for OpenCV
    haystack_img = ImageGrab.grab(bbox=(x1, y1, x2, y2))
    crop = haystack_img.crop((750,30,1150,78))
    haystack_img_np = np.array(crop)
    haystack = cv.cvtColor(haystack_img_np, cv.COLOR_BGR2GRAY)
    cv.imshow("Detection", haystack)
    cv.waitKey(1)
    return haystack


class VideoCaptureThread(threading.Thread):
    def __init__(self, result_queue: queue.Queue) -> None:
        super().__init__()
        self.exit_signal = threading.Event()
        self.result_queue = result_queue

    def run(self) -> None:
        while not self.exit_signal.wait(0.05):
            try:
                result = videoLoop()
                self.result_queue.put(result)
            except Exception as exc:
                print(f"Failed capture: {exc}")

def main():
    result_queue = queue.Queue()
    thread = VideoCaptureThread(result_queue=result_queue)
    thread.start()
    while True:
        frame = result_queue.get()
        print(frame)
        return frame


if __name__ == "__main__":
    main()



def shipDetection(image_list, threshold, haystack, a):
    # Object Detection
    for x in range (0, a):
        for i in image_list:
            cv.imshow("Ship Detection", haystack)
            cv.waitKey(1)
            needle_img = i[0]
            needle_name = i[1]
            sliced_name = needle_name.split("\\")[-1]
            result = cv.matchTemplate(haystack, needle_img, cv.TM_CCORR_NORMED)

            # Get the best match position
            min_val, max_val, min_loc, max_loc = cv.minMaxLoc(result)
            percentage_max_val = round(max_val*100, 2)

            # Define top left and bottom right and threshold
            (H, W) = i[0].shape[:2] 
            top_left = max_loc
            bottom_right = (top_left[0] + W, top_left[1] + H)

            # If something has been detected click keep looking code
            if max_val >= threshold:
                cv.rectangle(haystack, top_left, bottom_right, 255, 2)
                cv.imshow("Ship Detection", haystack)
                cv.waitKey(1)
                keep_looking(sliced_name, percentage_max_val)
                print(sliced_name, percentage_max_val)
                return True
        return False

enter image description here



Solution 1:[1]

Not an answer, because I don't understand the question yet, but I can't put code snippets into a comment. I have two comments:


(1) This is a common pattern in Python code:

if __name__ == "__main__":
    ...

Whenever a Python source code file is executed as a script, the global variable, __name__ will equal "__main__", and the ... will be executed. If the same file is loaded as a package, __name__ will equal the name of the package, and the ... will not be executed.

If your code is executed as a script, it will call main() and then it will throw away the return value. You say you are having trouble returning a value from main(), but if you want a return value from main(), then why do you throw away the return value at the call site?

Is your code meant to be executed as a script? or is it meant to be used as a package, and is main() merely test code? If it's test code, then what is the test supposed to prove? If it's a script, then what is the script supposed to do? (e.g., print() all of the frames?)


(2) This can't be right:

while True:
    ...
    return frame

You put an unconditional return statement inside a loop. The body of that loop can never be executed more than one time because the very first iteration will always return from main().

So, why did you try to make it loop? What were you trying to accomplish?

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1