包cv2在一段时间后崩溃



我有一个摄像头在拍摄我的水表,在树莓上的Python脚本在几个步骤中转换了这张照片,这样我就可以读出用水量了。

现在是我的问题。过了一会儿(有时它运行了几个星期,有时几个小时,今天有时几分钟),我得到这个错误:
^CTraceback (most recent call last):
  File "/home/pi/backup/water.py", line 26, in <module>
frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
cv2.error: OpenCV(4.4.0) /tmp/pip-wheel-b0jd8w40/opencv-contrib-python/opencv/modules/imgproc/src/color.cpp:182: error: (-215:Assertion failed) !_src.empty() in function 'cvtColor'

我读到这可能是由网络摄像头连接中断引起的。

我用try - exception处理进行了尝试。但这行不通。我能做什么,脚本不崩溃,如果有一个错误?是否有像"如果有错误,等待30秒,重新启动整个python代码"这样的解决方案?或者类似的东西?或者另一种解决方案,如果有错误,只要它能再次工作,就重新连接网络摄像头流。

包括我最后一次尝试处理这个问题的整个代码如下:

import numpy as np
import cv2
from datetime import datetime
from influxdb import InfluxDBClient
import time
vcap = cv2.VideoCapture("rtsp://syno:xxxx@xxxx:554/Sms=3.unicast")
client = InfluxDBClient(host="xxxx", port=8086,
                        username="xxxx", password="xxxx", ssl=False, verify_ssl=False)
send_water = 0
while (True):
    try:
        ret, frame = vcap.read()
        cv2.circle(frame, (485, 255), 5, (0, 0, 255), -1)
        cv2.circle(frame, (600, 250), 5, (0, 0, 255), -1)
        cv2.circle(frame, (480, 390), 5, (0, 0, 255), -1)
        cv2.circle(frame, (600, 390), 5, (0, 0, 255), -1)
        pts1 = np.float32([[485, 255], [600, 250], [480, 390], [600, 390]])
        pts2 = np.float32([[0, 0], [300, 0], [0, 300], [300, 300]])
        frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
        (thresh, frame) = cv2.threshold(frame, 180, 255, cv2.THRESH_BINARY)
        matrix = cv2.getPerspectiveTransform(pts1, pts2)
        frame = cv2.warpPerspective(frame, matrix, (300, 300))
        cv2.circle(frame, (148, 142), 5, (0, 0, 255), -1)
        frame = cv2.warpPolar(frame, (100, 200), (148, 142),
                              frame.shape[1] * .4, cv2.WARP_POLAR_LINEAR)
        waterlevel = frame.sum(axis=1).argmax()
        if not "last_water" in locals():
            last_water = waterlevel
        if waterlevel - last_water >= 0:
            waterdif = 10 * (waterlevel - last_water) / 200
            last_water = waterlevel
        elif waterlevel < last_water & last_water - waterlevel < 171:
            waterdif = 10 * (200 + waterlevel - last_water) / 200
            last_water = waterlevel
        else:
            waterdif = 0
        send_water = send_water + waterdif
        if send_water >= 0.25:
            current_time = datetime.utcnow().strftime('%Y-%m-%dT%H:%M:%SZ')
            client.switch_database("water")
            json_body = [
                {
                    "measurement": "Consump",
                    "time": current_time,
                    "fields": {
                        "Current_Consump": send_water
                    }
                }
            ]
            client.write_points(json_body)
            print(send_water)
            send_water = 0
        cv2.imshow('Video', frame)
        cv2.waitKey(1)
    except:
        print("Error!")
        cv2.destroyAllWindows()
        time.sleep(10)
        pass
cv2.destroyAllWindows()

我认为你应该做的第一件事是检查ret。从本教程:

cap.read()返回一个bool (True/False)。如果帧被正确读取,它将为True

如果它是False,你有几个选择:继续while循环,睡眠一段时间,终止程序,释放视频捕获并再次创建它,等等。您也可以将它们组合。

释放视频捕获并重新创建的示例:

        ret, frame = vcap.read()
        if not ret:
            vcap.release()
            vcap = cv2.VideoCapture("rtsp://syno:xxxx@xxxx:554/Sms=3.unicast")
            continue

最新更新