树莓派运行cv2调用摄像头拍照线程多次运行之后程序异常中止

写了一个使用opencv调用摄像头拍照的功能,但是循环运行一段时间之后出现这个报错。
图片如下:

img

猜测是因为摄像头调用的时候出现问题导致python程序在外部被强制中断,但不知道该如何解决

代码如下:

# 打开摄像头并拍照
def photograph(num):
    cap = cv2.VideoCapture(num, cv2.CAP_DSHOW)  # 打开摄像头
    while 1:
        ret, frame = cap.read()
        frame = cv2.flip(frame, 1)  # 将图像左右调换回来正常显示
        frame_name = 'cap' + str(num)
        # cv2.imshow(frame_name, frame)  # 生成摄像头窗口
        # add = os.path.dirname(os.path.abspath(__file__)) + '\\'
        # time_name = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(time.time()))
        pic_name = str(num) + '.jpg'
        print(pic_name)
        # 丢弃9帧调整摄像头
        for i in range(9):
            success, frame = cap.read()
            if not success:
                exit(1)
        cv2.imwrite(pic_name, frame)
        break
        # if time.sleep(2):  # 如果按下q 就截图保存并退出

        # cv2.imwrite(pic_name, frame)  # 保存路径
    cap.release()
    cv2.destroyAllWindows()


# 拍照线程
def th():
    threading.Thread(target=photograph, args=[0]).start()
    threading.Thread(target=photograph, args=[2]).start()

从代码上看,你的线程只运行一次就会退出,然后你不断开启线程,可能导致了不可预料的结果,我建议是使用线程池,不要这么频繁地启动线程

1.所有需要跟外部IO通信的应用,都应该加try,except捕捉错误,你自己的代码产生错误可以避免,外部IO有错误是不能避免的,只能让出错的时候别直接崩溃
2.使用with块来包裹cap,这样 with cap = cv2.VideoCapture(num, cv2.CAP_DSHOW):
这样出了with块,cap对象会自动释放,不要手动调用release方法,会因为各种原因导致这句代码不被调用,造成内存泄漏或IO死锁

开两个线程,你这是有两个摄像头同时读取并保存图片吗

img


这个退出判定有点太严格了,偶尔漏一帧应该是不影响的