1

我的 IP 摄像机似乎有点不稳定并且随机断开连接。我希望我的脚本能够确定它何时断开连接并尝试重新连接几次,可能在尝试之间等待 5-10 秒。我已经尝试了一些东西,但没有任何效果。

这是我的基本脚本,当 ret 为 false 时脚本结束:

#!/usr/local/bin/python3

import cv2
import time
import datetime

print("start time: " + datetime.datetime.now().strftime("%A %d %B %Y %I:%M:%S%p"))

cap = cv2.VideoCapture('rtsp://<ip><port>/live0.264')

while(True):
    # Capture frame-by-frame
    ret, frame = cap.read()

    # Confirm we have a valid image returned
    if not ret:
        print("disconnected!")
        break

    # Our operations on the frame come here
    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2BGRA)

    # Display the resulting frame
    cv2.imshow('frame', gray)
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

print("end time: " + time.strftime("%X"))
# When everything is done, release the capture
cap.release()
cv2.destroyAllWindows()

编辑:如果我的网络暂时出现故障或类似情况,我还希望脚本尝试重新连接到相机。

4

2 回答 2

4

我终于能够自己解决这个问题。希望这对其他想要做同样事情的人有用。

这实际上是一个更复杂脚本的外壳,它具有在检测到运动时进行运动检测和视频录制的逻辑。尽管我仍在进行测试,但一切都与这个基本逻辑(以及我糟糕的 IP 摄像头)配合得很好。

#!/usr/local/bin/python3

import cv2
import datetime
import time


def reset_attempts():
    return 50


def process_video(attempts):

    while(True):
        (grabbed, frame) = camera.read()

        if not grabbed:
            print("disconnected!")
            camera.release()

            if attempts > 0:
                time.sleep(5)
                return True
            else:
                return False


recall = True
attempts = reset_attempts()

while(recall):
    camera = cv2.VideoCapture("rtsp://<ip><port>/live0.264")

    if camera.isOpened():
        print("[INFO] Camera connected at " +
              datetime.datetime.now().strftime("%m-%d-%Y %I:%M:%S%p"))
        attempts = reset_attempts()
        recall = process_video(attempts)
    else:
        print("Camera not opened " +
              datetime.datetime.now().strftime("%m-%d-%Y %I:%M:%S%p"))
        camera.release()
        attempts -= 1
        print("attempts: " + str(attempts))

        # give the camera some time to recover
        time.sleep(5)
        continue
于 2017-12-03T01:25:23.270 回答
1

更详细的说明:

https://github.com/Combinacijus/various-code-samples/tree/master/Python/OpenCV/ip_cam_reconnecting

写了一个类来处理IP camera随机断线。主要思想是检查 cap.read() 是否返回一个帧,如果没有,它会尝试重新连接到相机。

import cv2
import requests  # NOTE: Only used for forceful reconnection
import time  # NOTE: Only used for throttling down printing when connection is lost


class IPVideoCapture:
    def __init__(self, cam_address, cam_force_address=None, blocking=False):
        """
        :param cam_address: ip address of the camera feed
        :param cam_force_address: ip address to disconnect other clients (forcefully take over)
        :param blocking: if true read() and reconnect_camera() methods blocks until ip camera is reconnected
        """

        self.cam_address = cam_address
        self.cam_force_address = cam_force_address
        self.blocking = blocking
        self.capture = None

        self.RECONNECTION_PERIOD = 0.5  # NOTE: Can be changed. Used to throttle down printing

        self.reconnect_camera()

    def reconnect_camera(self):
        while True:
            try:
                if self.cam_force_address is not None:
                    requests.get(self.cam_force_address)

                self.capture = cv2.VideoCapture(self.cam_address)

                if not self.capture.isOpened():
                    raise Exception("Could not connect to a camera: {0}".format(self.cam_address))

                print("Connected to a camera: {}".format(self.cam_address))

                break
            except Exception as e:
                print(e)

                if self.blocking is False:
                    break

                time.sleep(self.RECONNECTION_PERIOD)

    def read(self):
        """
        Reads frame and if frame is not received tries to reconnect the camera

        :return: ret - bool witch specifies if frame was read successfully
                 frame - opencv image from the camera
        """

        ret, frame = self.capture.read()

        if ret is False:
            self.reconnect_camera()

        return ret, frame


if __name__ == "__main__":
    CAM_ADDRESS = "http://192.168.8.102:4747/video"  # NOTE: Change
    CAM_FORCE_ADDRESS = "http://192.168.8.102:4747/override"  # NOTE: Change or omit
    cap = IPVideoCapture(CAM_ADDRESS, CAM_FORCE_ADDRESS, blocking=True)
    # cap = IPVideoCapture(CAM_ADDRESS)  # Minimal init example

    while True:
        ret, frame = cap.read()

        if ret is True:
            cv2.imshow(CAM_ADDRESS, frame)

        if cv2.waitKey(1) == ord("q"):
            break
于 2020-07-11T19:49:03.520 回答