Python:自动重新连接IP摄像头
我的IP摄像头似乎有点不稳定,随机断开。我希望我的脚本能够确定何时断开连接,并尝试重新连接几次,可能在尝试之间等待5-10秒。我试过一些方法,但都不管用 这是我的基本脚本,当ret为false时,脚本结束:Python:自动重新连接IP摄像头,python,python-3.x,opencv,surveillance,Python,Python 3.x,Opencv,Surveillance,我的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"
#!/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()
#/usr/local/bin/python3
进口cv2
导入时间
导入日期时间
打印(“开始时间:+datetime.datetime.now().strftime(“%A%d%B%Y%I:%M:%S%p”))
cap=cv2.VideoCapture('rtsp:///live0.264')
虽然(正确):
#逐帧捕获
ret,frame=cap.read()
#确认我们已返回有效的图像
如果不是ret:
打印(“断开连接!”)
打破
#我们在框架上的行动就在这里
灰色=cv2.CVT颜色(帧,cv2.COLOR\u BGR2BGRA)
#显示结果帧
cv2.imshow(“帧”,灰色)
如果cv2.waitKey(1)&0xFF==ord('q'):
打破
打印(“结束时间:+time.strftime(“%X”))
#完成所有操作后,释放捕获
第1章释放()
cv2.destroyAllWindows()
编辑:我还希望脚本在网络暂时中断或类似情况下尝试重新连接到相机 我终于自己解决了这个问题。希望这对任何想做同样事情的人都有用 这实际上是一个更复杂脚本的外壳,当检测到运动时,它具有用于运动检测和视频记录的逻辑。尽管我仍在进行测试,但使用这个基本逻辑(以及我糟糕的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
#/usr/local/bin/python3
进口cv2
导入日期时间
导入时间
def reset_尝试次数():
返回50
def过程_视频(尝试次数):
虽然(正确):
(抓取,帧)=照相机。读取()
如果没有抓到:
打印(“断开连接!”)
摄影机。释放()
如果尝试次数>0:
时间。睡眠(5)
返回真值
其他:
返回错误
回忆=真实
尝试次数=重置尝试次数()
而(回忆):
摄像机=cv2.视频捕获(“rtsp:///live0.264")
如果摄影机.isOpened():
打印(“[INFO]摄像头已连接到”+
datetime.datetime.now().strftime(“%m-%d-%Y%I:%m:%S%p”))
尝试次数=重置尝试次数()
召回=处理视频(尝试)
其他:
打印(“相机未打开”+
datetime.datetime.now().strftime(“%m-%d-%Y%I:%m:%S%p”))
摄影机。释放()
尝试次数-=1
打印(“尝试次数:+str(尝试次数))
#给相机一些时间恢复
时间。睡眠(5)
持续
我终于自己解决了这个问题。希望这对任何想做同样事情的人都有用
这实际上是一个更复杂脚本的外壳,当检测到运动时,它具有用于运动检测和视频记录的逻辑。尽管我仍在进行测试,但使用这个基本逻辑(以及我糟糕的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
#/usr/local/bin/python3
进口cv2
导入日期时间
导入时间
def reset_尝试次数():
返回50
def过程_视频(尝试次数):
虽然(正确):
(抓取,帧)=照相机。读取()
如果没有抓到:
打印(“断开连接!”)
摄影机。释放()
如果尝试次数>0:
时间。睡眠(5)
返回真值
其他:
返回错误
回忆=真实
尝试次数=重置尝试次数()
而(回忆):
摄像机=cv2.视频捕获(“rtsp:///live0.264")
如果摄影机.isOpened():
打印(“[INFO]摄像头已连接到”+
datetime.datetime.now().strftime(“%m-%d-%Y%I:%m:%S%p”))
尝试次数=重置尝试次数()
召回=处理视频(尝试)
其他:
打印(“相机未打开”+
datetime.datetime.now().strftime(“%m-%d-%Y%I:%m:%S%p”))
摄影机。释放()
尝试次数-=1
打印(“尝试次数:+str(尝试次数))
#给相机一些时间恢复
时间。睡眠(5)
持续
更详细的说明:
写了一个类来处理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
更详细的说明: 写了一个类来处理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
什么不起作用?有错误吗?实际上我不知道解决方案,但我认为你必须修复你的ip摄像头我以前从未见过随机断开的ip摄像头这是一个便宜的摄像头。我无法控制它的固件或导致它断开连接的任何东西。即使问题不是摄像机,我希望脚本能够在摄像机因任何其他原因断开连接时恢复与摄像机的连接。您尝试过什么?你说“几件事”?问题是延迟还是重新连接本身?看起来你已经找到了让它检查摄像机是否断开的方法,所以我猜这不是你要问的?最好不要使用While True,而是将
if cv2.waitKey
合并到While检查中。问题是重新连接。我尝试创建一个调用cv2.VideoCapture()
的函数。当if not ret:
中的cap.read()
没有返回任何内容时,将调用该函数?有错误吗?实际上我不知道解决方案,但我认为你必须修复你的ip摄像头我以前从未见过随机断开的ip摄像头这是一个便宜的摄像头。我无法控制它的固件或导致它断开连接的任何东西。即使问题不是摄像机,我希望脚本能够在摄像机因任何其他原因断开连接时恢复与摄像机的连接。您尝试过什么?尤萨