首页 > 解决方案 > 我可以从 Python 中的后台线程渲染 openCV 动画吗?

问题描述

我可以从 Python 中的后台线程渲染 openCV 动画吗?

这是我的尝试:

import cv2
import numpy as np
from time import sleep

bitmap = np.zeros((512,512,3),np.uint8)

import threading
import time

def update_bitmap():
    for i in range(512):
        bitmap[i,i,:] = 128
        sleep(1/32)

threading.Thread(target=update_bitmap).start()

def refresh_gui():
    hz = 30
    delta_t = 1 / hz
    t = time.time()
    while True:
        sleep(0.001)
        if time.time() > t+delta_t:
            t += delta_t
            cv2.imshow("Color Image", bitmap)
            cv2.waitKey(1)

threading.Thread(target=refresh_gui).start()

try:
    while True:
        print('tick')
        sleep(1)
except KeyboardInterrupt:
    cv2.destroyAllWindows()
    exit(0)

但是它失败了:

> python test.py
tick
2021-03-14 17:01:37.474 python[38483:2301820] WARNING: NSWindow drag regions should only be invalidated on the Main Thread! This will throw an exception in the future. Called from (
        0   AppKit                              0x00007fff22c7347f -[NSWindow(NSWindow_Theme) _postWindowNeedsToResetDragMarginsUnlessPostingDisabled] + 352
        1   AppKit                              0x00007fff22c5e121 -[NSWindow _initContent:styleMask:backing:defer:contentView:] + 1375
        2   AppKit                              0x00007fff22c5dbbb -[NSWindow initWithContentRect:styleMask:backing:defer:] + 42
        3   AppKit                              0x00007fff22f681f4 -[NSWindow initWithContentRect:styleMask:backing:defer:screen:] + 52
        4   cv2.cpython-37m-darwin.so           0x00000001084cc4f5 cvNamedWindow + 677
        5   cv2.cpython-37m-darwin.so           0x00000001084cbdbc cvShowImage + 188
        6   cv2.cpython-37m-darwin.so           0x00000001084ca286 _ZN2cv6imshowERKNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEERKNS_11_InputArrayE + 230
        7   cv2.cpython-37m-darwin.so           0x000000010749515e _ZL18pyopencv_cv_imshowP7_objectS0_S0_ + 302
        8   python                              0x0000000106fcd4e8 _PyMethodDef_RawFastCallKeywords + 392
        9   python                              0x0000000107109ce2 call_function + 306
        10  python                              0x0000000107106a83 _PyEval_EvalFrameDefault + 42243
        11  python                              0x0000000106fccbe5 function_code_fastcall + 117
        12  python                              0x0000000107107bf2 _PyEval_EvalFrameDefault + 46706
        13  python                              0x0000000106fccbe5 function_code_fastcall + 117
        14  python                              0x0000000107109c67 call_function + 183
        15  python                              0x00000001071069ed _PyEval_EvalFrameDefault + 42093
        16  python                              0x0000000106fccbe5 function_code_fastcall + 117
        17  python                              0x0000000107109c67 call_function + 183
        18  python                              0x00000001071069ed _PyEval_EvalFrameDefault + 42093
        19  python                              0x0000000106fccbe5 function_code_fastcall + 117
        20  python                              0x0000000106fd0002 method_call + 130
        21  python                              0x0000000106fcda82 PyObject_Call + 130
        22  python                              0x00000001071eb89b t_bootstrap + 123
        23  python                              0x0000000107172937 pythread_wrapper + 39
        24  libsystem_pthread.dylib             0x00007fff20332950 _pthread_start + 224
        25  libsystem_pthread.dylib             0x00007fff2032e47b thread_start + 15
)
2021-03-14 17:01:37.482 python[38483:2301820] WARNING: nextEventMatchingMask should only be called from the Main Thread! This will throw an exception in the future.
tick
tick
tick
tick
tick
tick
tick
tick
tick
tick
tick
^C^CException ignored in: <module 'threading' from '/usr/local/anaconda3/lib/python3.7/threading.py'>
Traceback (most recent call last):
  File "/usr/local/anaconda3/lib/python3.7/threading.py", line 1308, in _shutdown
    lock.acquire()
KeyboardInterrupt

我真的希望我的渲染器在一个单独的线程中。干净多了!可以做到吗?

标签: pythonmultithreadingopencvanimationimshow

解决方案


这不能回答问题,但可以解决问题:

import cv2
import numpy as np
from time import sleep


import threading
import time

bitmap = np.zeros((512,512,3),np.uint8)
def update_bitmap():
    for i in range(512):
        bitmap[i,i,:] = 128
        sleep(1/32)


def main():
    threading.Thread(target=update_bitmap).start()

    hz = 30
    delta_t = 1 / hz
    t = time.time()
    try:
        while True:
            sleep(0.001)
            if time.time() > t+delta_t:
                t += delta_t
                cv2.imshow("Color Image", bitmap)
                cv2.waitKey(1)

    except KeyboardInterrupt:
        cv2.destroyAllWindows()
        exit(0)

main()

推荐阅读