繁体   English   中英

Package cv2 一段时间后崩溃

[英]Package cv2 crashes after a while

我有一个网络摄像头正在拍摄我的水表和一个覆盆子上的 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 - 异常处理。 但它不起作用。 如果出现错误,我该怎么做才能使脚本不会崩溃? 是否会有类似“如果出现错误,等待 30 秒重新启动整个 python 代码”之类的解决方案? 或另一种解决方案,如果出现错误,只需重新连接网络摄像头 ZF7B44CFFAFD5C52223D5498196C8A2E7BZ 并尝试此操作,只要它再次工作即可。

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

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你有几个选择:继续 while 循环,休眠一段时间,终止程序,释放视频捕获并重新创建它,等等。你也可以组合它们。

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

        ret, frame = vcap.read()

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM