使用OpenCV访问IP摄像头

9

无法访问视频流。请有人帮我获取视频流。我已在谷歌上搜索解决方案,并在Stack Overflow上发布了另一个问题,但不幸的是没有解决问题。

import cv2
cap = cv2.VideoCapture()
cap.open('http://192.168.4.133:80/videostream.cgi?user=admin&pwd=admin')
while(cap.isOpened()):
    ret, frame = cap.read()
    cv2.imshow('frame', frame)
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break
cap.release()
cv2.destroyAllWindows()

发生了什么事情? - AMC
也许这会对找到这个帖子的任何人有所帮助?如何使用OpenCV捕获视频并使用线程以实现更高的帧率和减少延迟 https://dev59.com/g1MI5IYBdhLWcg3wlMlZ - brianlmerritt
6个回答

5

使用以下代码直接通过OpenCV访问IP摄像机。将VideoCapture中的URL替换为您特定的摄像机RTSP URL。通常给出的一个适用于我使用过的大多数摄像机。

import cv2

cap = cv2.VideoCapture("rtsp://[username]:[pass]@[ip address]/media/video1")

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

3

您可以使用此代码在浏览器中获取实时视频流。

如果要访问除笔记本电脑的网络摄像头以外的摄像头,您可以使用如下所示的RTSP链接:

rtsp://admin:12345@192.168.1.1:554/h264/ch1/main/av_stream"

其中

   username:admin
   password:12345
   your camera ip address and port
   ch1 is first camera on that DVR

replace cv2.VideoCamera(0) with this link like this for your camera and it will work

camera.py

import cv2

class VideoCamera(object):
    def __init__(self):
        # Using OpenCV to capture from device 0. If you have trouble capturing
        # from a webcam, comment the line below out and use a video file
        # instead.
        self.video = cv2.VideoCapture(0)
        # If you decide to use video.mp4, you must have this file in the folder
        # as the main.py.
        # self.video = cv2.VideoCapture('video.mp4')

    def __del__(self):
        self.video.release()

    def get_frame(self):
        success, image = self.video.read()
        # We are using Motion JPEG, but OpenCV defaults to capture raw images,
        # so we must encode it into JPEG in order to correctly display the
        # video stream.
        ret, jpeg = cv2.imencode('.jpg', image)
        return jpeg.tobytes()

main.py

from flask import Flask, render_template, Response
from camera import VideoCamera

app = Flask(__name__)

@app.route('/')
def index():
    return render_template('index.html')

def gen(camera):
    while True:
        frame = camera.get_frame()
        yield (b'--frame\r\n'
               b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n\r\n')

@app.route('/video_feed')
def video_feed():
    return Response(gen(VideoCamera()),
                    mimetype='multipart/x-mixed-replace; boundary=frame')

if __name__ == '__main__':
    app.run(host='0.0.0.0', debug=True)

如果您想提高视频流的帧率,可以参照这篇博客


3
您可以使用urllib从视频流中读取帧。
import cv2
import urllib
import numpy as np

stream = urllib.urlopen('http://192.168.100.128:5000/video_feed')
bytes = ''
while True:
    bytes += stream.read(1024)
    a = bytes.find(b'\xff\xd8')
    b = bytes.find(b'\xff\xd9')
    if a != -1 and b != -1:
        jpg = bytes[a:b+2]
        bytes = bytes[b+2:]
        img = cv2.imdecode(np.fromstring(jpg, dtype=np.uint8), cv2.IMREAD_COLOR)
        cv2.imshow('Video', img)
        if cv2.waitKey(1) == 27:
            exit(0)

如果你想从你的电脑的网络摄像头中流视频,请查看此内容。 https://github.com/shehzi-khan/video-streaming


urlliburllib2在Python 3.x上不可用。 - Aashish Kumar

2
您可以使用RTSP替代直接视频源。
每个IP摄像头都有RTSP以流式传输实时视频。
因此,您可以使用RTSP链接而不是视频源。

2

如果使用Python 3,您可能需要使用bytearray而不是字符串来进行操作。(修改当前的最初回答)

with urllib.request.urlopen('http://192.168.100.128:5000/video_feed') as stream:

    bytes = bytearray()

    while True:
        bytes += stream.read(1024)
        a = bytes.find(b'\xff\xd8')
        b = bytes.find(b'\xff\xd9')
        if a != -1 and b != -1:
            jpg = bytes[a:b+2]
            bytes = bytes[b+2:]
            img = cv2.imdecode(np.frombuffer(jpg, dtype=np.uint8), cv2.IMREAD_COLOR)
            cv2.imshow('Video', img)
            if cv2.waitKey(1) & 0xFF == ord('q'):
                break

cv2.destroyAllWindows()

2

谢谢。也许现在urlopen不在utllib中了,而是在urllib.request.urlopen中。我使用的代码如下:

import cv2
from urllib.request import urlopen
import numpy as np

stream = urlopen('http://192.168.4.133:80/video_feed')
bytes = ''
while True:
    bytes += stream.read(1024)
    a = bytes.find(b'\xff\xd8')
    b = bytes.find(b'\xff\xd9')
    if a != -1 and b != -1:
        jpg = bytes[a:b+2]
        bytes = bytes[b+2:]
        img = cv2.imdecode(np.fromstring(jpg, dtype=np.uint8), cv2.IMREAD_COLOR)
        cv2.imshow('Video', img)
        if cv2.waitKey(1) == 27:
            exit(0)

1
这在Python 3上不起作用:“TypeError: Can't convert 'bytes' object to str implicitly” - Ghasem
urlliburllib2在Python 3.x上不可用。 - Aashish Kumar

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