使用Python OpenCV访问IP摄像头

41

我该如何访问我的IP摄像头视频流?

用于显示标准网络摄像头视频流的代码为:

import cv2
import numpy as np

cap = cv2.VideoCapture(0)

while(True):
    ret, frame = cap.read()
    cv2.imshow('frame',frame)
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

cap.release()
cv2.destroyAllWindows()

如何使用IP摄像头完成完全相同的操作?

我的系统:

  • Python 2.7.14
  • OpenCV 2.4.9
  • Teledyne Dalsa Genie Nano XL 摄像头

您可以使用视频捕获对象,例如:

camera = cv2.VideoCapture("IP:PORT/video")

1
可能是使用OpenCV访问IP摄像头的重复问题。 - Klaus D.
你的IP摄像头有用户名和密码吗? - sgarizvi
嗨,看看这篇关于IP摄像头和OpenCv的博客吧.. http://benhowell.github.io/guide/2015/03/09/opencv-and-web-cam-streaming - bbartling
我正在研究同样的事情,你能告诉我进展如何吗?另外,你知道是否有最简单的品牌和方法吗?(流式传输mpeg / jpeg等)谢谢! - bbartling
12个回答

49
cv2.VideoCapture("rtsp://192.168.1.64/1")
capture = cv2.VideoCapture('rtsp://192.168.1.64/1')

大多数IP摄像头需要用户名和密码才能访问视频。在这种情况下,凭据必须作为流媒体URL的一部分提供:

capture = cv2.VideoCapture('rtsp://username:password@192.168.1.64/1')

3
@sqarizvi 我该如何找到摄像头的URL?它安装在我的本地网络中,直接连接到路由器。有没有办法从Python代码中扫描网络并找到URL? - StewieGGriffin
1
@Abhishek... 你可以使用一些网络扫描工具(如Linux上的arp-scan)来查找摄像头的IP地址。摄像头手册或随摄像头提供的软件/移动应用程序中应该可以找到URL的更多详细信息,例如“协议”、“凭据”和“通道”。 - sgarizvi
谢谢回复。我可以通过访问我的路由器轻松找到相机的URL。但是,由于我的互联网使用动态IP,如果发生停电或类似情况,相机的IP / URL会不断更改。因此,我想知道是否存在Python中的某些东西,可以扫描网络并找到相机的IP,以便我可以将相机的URL用作变量而不是硬编码。 - StewieGGriffin
1
@Abhishek,我认为你可以尝试使用静态IP配置。这样,你就可以拥有固定的IP地址,而不是动态分配的IP地址。 - Dinusha Thilakarathna
推荐使用RTSP还是HTTP? - Josh
@sgarizvi,这个协议能够投入生产吗?使用RTSP是否会有任何数据包丢失?我已经使用了Kinesis Video的GStreamer,我的背景不是很擅长视频流,所以想知道如果我不想使用云服务,如何最好地利用开源技术实现Python中稳定的视频流方案。 - Aakash Basu

14

这适用于我的IP摄像头:

import cv2

#print("Before URL")
cap = cv2.VideoCapture('rtsp://admin:123456@192.168.1.216/H264?ch=1&subtype=0')
#print("After URL")

while True:

    #print('About to start the Read command')
    ret, frame = cap.read()
    #print('About to show frame of Video.')
    cv2.imshow("Capturing",frame)
    #print('Running..')

    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

cap.release()
cv2.destroyAllWindows()

我在相机的设置界面中找到了流媒体URL: IP Camera Setup Screen

请注意,在URL中加入相机的用户名(admin)和密码(123456),并在IP地址之前以@符号结束(admin:123456@)。


你能分享一下你使用的相机是什么吗? - Pratik Khadloya
1
商用2兆像素安全摄像头。大多数使用相同或类似的固件和设置。我从UNIX CCTV购买。https://www.unixcctv.com/product-category/ip-cameras-nvr/ip-cameras/ - John Harris
谢谢分享。我很好奇,因为我无法在Vivotek相机上做同样的事情。 - Pratik Khadloya
我试过的几乎所有兼容ONVIF的摄像机都是这样工作的。如果您找到了如何在您的Vivotek相机上使其工作的方法,请在此处发布,以防将来我遇到与您相同的情况。谢谢。 - John Harris
@PratikKhadloya 您的Vivotek相机可能需要进行格式化,类似于这样:('rtsp://192.168.1.216/H264?ch=1&subtype=0?user=admin&pwd=123456')。 - John Harris
显示剩余3条评论

13

通过IP摄像头流式传输视频的最简单方法!

我刚刚编辑了你的示例。您必须替换您的IP并在链接中添加/video。然后继续进行您的项目。

import cv2

cap = cv2.VideoCapture('http://192.168.18.37:8090/video')

while(True):
    ret, frame = cap.read()
    cv2.imshow('frame',frame)
    if cv2.waitKey(1) & 0xFF == ord('q'):
        cv2.destroyAllWindows()
        break

摄像头的端口8090对于所有IP摄像头都是一样的吗?如果不是,我们从哪里可以获取端口号? - S Andrew
1
嗨,安德鲁,我提到的链接是从IP CAMERA应用程序中获取的。因此,如果您正在使用Android手机,则可以从Google Store下载此应用程序。然后向下滚动并找到“启动服务器”。按下它。您将看到上面相同类型的链接。祝你好运。 - Jimmy
我正在使用来自Google Play商店的IP Webcam从手机上获取视频,这对我很有效。 - socm_

9
首先找到你的IP摄像机的流媒体URL,比如是RTSP/HTTP等。
代码更改将如下所示:
cap = cv2.VideoCapture("ipcam_streaming_url")

例如:

cap = cv2.VideoCapture("http://192.168.18.37:8090/test.mjpeg")

我遇到了一个问题,我有两个摄像头,一个通过RTSP连接,另一个通过HTTP连接。在Ubuntu上,它们都能正常工作。但是当我将相同的代码转移到树莓派上时,HTTP摄像头无法返回任何帧。 - amitnair92
@amitnair92建议您将其作为独立问题发布。 - Venkatesh Wadawadagi
我在这里发布了问题,但是没有得到任何解决方案。https://raspberrypi.stackexchange.com/questions/84708/http-ip-camera-not-working-on-pi-but-working-on-ubuntu - amitnair92

8
我回答自己的问题,报告了在Python OpenCV中访问IP摄像头的最全面的过程。
给定一个IP摄像头:
  • 找到您的摄像头IP地址
  • 找到访问IP地址的端口
  • 查找摄像头提供商指定的协议(HTTP/RTSP等)
然后,如果您的摄像头受到保护,请继续找出:
  • 您的用户名
  • 您的密码
然后使用您的数据运行以下脚本:
"""Access IP Camera in Python OpenCV"""

import cv2

stream = cv2.VideoCapture('protocol://IP:port/1')

# Use the next line if your camera has a username and password
# stream = cv2.VideoCapture('protocol://username:password@IP:port/1')  

while True:

    r, f = stream.read()
    cv2.imshow('IP Camera stream',f)

    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

cv2.destroyAllWindows()

注意: 在我的原始问题中,我指定使用 Teledyne Dalsa Genie Nano XL相机。不幸的是,对于这种类型的相机,访问IP相机视频流的正常方式不起作用,必须使用 Sapera SDK 从设备中获取帧。


当我们在VideoCapture中指定“port”时,会打开哪个本地端口?我有两个具有相同端口号的流链接,当第二个链接打开时,我会收到端口已在使用错误的提示。 - mrtpk

8

要访问IP摄像头,首先我建议您像使用标准应用程序一样安装它,不使用任何代码,使用普通软件。

之后,您需要知道对于不同的相机,我们有不同的代码。有一个网站可以查看您可以使用哪些代码来访问它们:

https://www.ispyconnect.com/sources.aspx

但是要小心,对于我的相机(Intelbras S3020),它不起作用。正确的方法是向您的相机公司询问,如果他们是一家好公司,他们会提供它。

当您知道您的代码后,只需添加如下内容:

cap = cv2.VideoCapture("http://LOGIN:PASSWORD@IP/cgi-bin/mjpg/video.cgi?&subtype=1")

你需要输入你的登录名和密码,登录名请填写LOGIN,密码请填写PASSWORD。

要查找摄像机的IP地址,有很多软件可以下载并提供IP地址。我使用Intelbras的软件,但我也推荐EseeCloud,因为它们适用于我购买的几乎所有摄像机:

https://eseecloud.software.informer.com/1.2/

在此示例中,显示了使用http协议访问IP摄像机,但是您也可以使用rstp,这取决于摄像机,正如我所说的那样。

如果您有任何进一步的问题,请告诉我。


这段代码正在运行,谢谢。 - Ramesh

5
你可以使用以下方法访问大多数IP摄像头。
import cv2 

# insert the HTTP(S)/RSTP feed from the camera
url = "http://username:password@your_ip:your_port/tmpfs/auto.jpg"

# open the feed
cap = cv2.VideoCapture(url)

while True:
    # read next frame
     ret, frame = cap.read()
    
    # show frame to user
     cv2.imshow('frame', frame)
    
    # if user presses q quit program
     if cv2.waitKey(1) & 0xFF == ord("q"):
        break

# close the connection and close all windows
cap.release()
cv2.destroyAllWindows()

1
这对我来说非常有效,使用远程的树莓派作为视频源运行mjpg-streamer。谢谢! - Peter Lunk

3

获取IP摄像机视频链接的方法:

  1. 在浏览器中打开具有给定IP和端口的IP摄像机。
  2. 右键单击视频,选择“复制图像地址”。
  3. 使用该地址来捕获视频。

1
我最近遇到了这个问题,最终通过使用Firefox的“检查元素”功能解决了它。我想,仅仅查看图像地址可能会更简单。因此,这是一种更有效的找到摄像头流确切URI的方法。 - R.S.

2
import cv2
from threading import Thread
  
class Webcam:
  
    def __init__(self):
        # using video stream from IP Webcam for Android
        url = "http://your_ip:8080/video"
        self.video_capture = cv2.VideoCapture(url)
        self.current_frame = self.video_capture.read()[1]
          
    # create thread for capturing images
    def start(self):
        Thread(target=self._update_frame, args=()).start()
  
    def _update_frame(self):
        while(True):
            try:
                self.current_frame = self.video_capture.read()[1]
            except:
                pass
                  
    # get the current frame
    def get_current_frame(self):
        return self.current_frame

然后

from webcam import Webcam
# get image from webcam
image = self.webcam.get_current_frame()

2
Pycharm中,我编写了访问IP摄像头的代码,如下所示:
import cv2

cap=VideoCapture("rtsp://user_name:password@IP_address:port_number")

ret, frame=cap.read()

您需要用合适的值替换user_namepasswordIPport


如果您没有正确处理流和中断情况(就像上面的答案所做的那样),那么您将会遇到一些悲伤! - Blairg23

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接