mak47
mak47

Reputation: 303

How do I run video detection with multiprocessing?

I'm doing object detection and GUI interactions on an application window with python and OpenCV.

Currently, my script runs in series, it takes a screenshot, runs detection, takes a screenshot, runs detection ad infinitum or until stopped manually. This happens at around 45 fps which is more than adequate for my purposes.

I've reached a point where the GUI interactions are becoming tricky running things in series. I'm now trying to use the multiprocessing module to run my videoLoop function.

However, I'm getting the error:

C:\Users/AppData/Local/Programs/Python/Python39/python.exe c:/test_object_detection.py
Traceback (most recent call last):
  File "c:\test_object_detection.py", line 106, in <module>
    detection(image_list, haystack)
NameError: name 'haystack' is not defined
Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "C:\Users\AppData\Local\Programs\Python\Python39\lib\multiprocessing\spawn.py", line 116, in spawn_main
    exitcode = _main(fd, parent_sentinel)
  File "C:\Users\AppData\Local\Programs\Python\Python39\lib\multiprocessing\spawn.py", line 125, in _main
    prepare(preparation_data)
  File "C:\Users\AppData\Local\Programs\Python\Python39\lib\multiprocessing\spawn.py", line 236, in prepare
    _fixup_main_from_path(data['init_main_from_path'])
  File "C:\Users\AppData\Local\Programs\Python\Python39\lib\multiprocessing\spawn.py", line 287, in _fixup_main_from_path
    main_content = runpy.run_path(main_path,
  File "C:\Users\AppData\Local\Programs\Python\Python39\lib\runpy.py", line 268, in run_path
    return _run_module_code(code, init_globals, run_name,
  File "C:\Users\AppData\Local\Programs\Python\Python39\lib\runpy.py", line 97, in _run_module_code
    _run_code(code, mod_globals, init_globals,
  File "C:\Users\AppData\Local\Programs\Python\Python39\lib\runpy.py", line 87, in _run_code
    exec(code, run_globals)
  File "c:\Users\test_object_detection.py", line 106, in <module>
    detection(image_list, haystack)
NameError: name 'haystack' is not defined

My object detection needs a needle and haystack variable.

    def objectDetection(needle, haystack):
        result = cv.matchTemplate(haystack, needle, cv.TM_CCORR_NORMED)
        # Get the best match position
        min_val, max_val, min_loc, max_loc = cv.minMaxLoc(result)
        # Define top left and bottom right and threshold
        (H, W) = needle[0].shape[:2] 
        top_left = max_loc
        bottom_right = (top_left[0] + W, top_left[1] + H)
        cv.rectangle(haystack, top_left, bottom_right, 255, 2)
        cv.imshow("objectDetection", haystack)
        cv.waitKey(1)

When I run videoLoop normally as a function it returns an array for haystack

def videoLoop():
    while True:
        img = ImageGrab.grab(bbox=(500, 50, 600, 60))
        img_np = np.array(img )
        DetectionWindow= cv.cvtColor(img_np, cv.COLOR_BGR2GRAY)
        return DetectionWindow

array([[193, 193, 189, ...,  75,  75,  76],
       [120,  91,  91, ...,  75,  77,  77],
       [191, 183, 183, ...,  77,  76,  75],
       ...,
       [ 82,  81,  81, ...,  60,  60,  60],
       [ 81,  81,  81, ...,  60,  60,  60],
       [ 81,  81,  81, ...,  61,  61,  60]], dtype=uint8)

I can't seem to find a return variable. p shows as <Process name='Process-1' pid=27064 parent=29280 started>

if __name__=='__main__':
    p = multiprocessing.Process(target=videoLoop)
    p.start()

needle = 'example.jpg'
haystack = DetectionWindow
objectDetection(needle, haystack)
       

If I strip everything out and just leave the multiprocessing code, it runs once then closes immediately. How do I run videoLoop with multiprocessing

Upvotes: 1

Views: 124

Answers (1)

Roland Smith
Roland Smith

Reputation: 43533

A multiprocessing.Process does not return a value after it has run.

You could use a Queue inside your function to return data to the parent process.

Also note that multiprocessing.Pool workers can return values.

Upvotes: 1

Related Questions