包cv2在一段时间后崩溃

2024-10-01 00:28:29 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个摄像头在拍摄我的水表,一个树莓上的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()

Tags: inimportsendtime错误cv2frame摄像头
1条回答
网友
1楼 · 发布于 2024-10-01 00:28:29

我认为您应该做的第一件事是检查ret。从this tutorial

cap.read() returns a bool (True/False). If the frame is read correctly, it will be True

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

释放视频捕获并再次创建的示例:

        ret, frame = vcap.read()

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

相关问题 更多 >