【问题标题】:Python: Automatically reconnect IP cameraPython:自动重新连接网络摄像机
【发布时间】:2018-05-10 03:52:48
【问题描述】:

我的网络摄像机似乎有点不稳定,并且随机断开连接。我希望我的脚本能够确定它何时断开连接并尝试重新连接几次,可能在尝试之间等待 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()

编辑:我还希望脚本在我的网络暂时中断或类似情况下尝试重新连接到相机。

【问题讨论】:

  • 什么不起作用?有错误吗?
  • 实际上我不知道解决方案,但我认为你必须修复你的网络摄像头我从未见过随机断开的网络摄像头
  • 这是一款便宜的相机。我无法控制它的固件或导致它断开连接的任何东西。即使问题不是相机,我也希望脚本能够在因任何其他原因断开连接时恢复与相机的连接。
  • 你试过什么?你说“几件事”?问题出在延迟还是重新连接本身?看起来您已经确定了一种检查相机是否断开连接的方法,所以我猜这不是您要问的吗?最好不要使用 While True,而是将 if cv2.waitKey 合并到 While 检查中。
  • 问题是重新连接。我尝试创建一个调用cv2.VideoCapture() 的函数。当cap.read()if not ret: 中没有返回任何内容时,将调用该函数

标签: python python-3.x opencv surveillance


【解决方案1】:

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

这实际上是一个更复杂脚本的外壳,它具有在检测到运动时进行运动检测和视频录制的逻辑。尽管我仍在进行测试,但一切都与这个基本逻辑(以及我糟糕的 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

【讨论】:

    【解决方案2】:

    更详细的说明:

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

    写了一个类来处理IP摄像头随机断开连接。主要思想是检查 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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-12-07
      • 2014-03-10
      • 2016-09-23
      • 1970-01-01
      • 2013-07-15
      • 2012-12-20
      • 1970-01-01
      相关资源
      最近更新 更多