How to parse mjpeg http stream from ip camera?

后端 未结 5 1698
天命终不由人
天命终不由人 2020-11-27 10:44

Given below is the code written for getting live stream from an IP Camera.

from cv2 import *
from cv2 import cv
import urllib
import numpy as np
k=0
capture=         


        
5条回答
  •  情歌与酒
    2020-11-27 11:01

    I don't think the first anwser is fine with other format image data, eg png. So I write the following code, which can handle other type of images

    """
    MJPEG format
    
    Content-Type: multipart/x-mixed-replace; boundary=--BoundaryString
    --BoundaryString
    Content-type: image/jpg
    Content-Length: 12390
    
    ... image-data here ...
    
    
    --BoundaryString
    Content-type: image/jpg
    Content-Length: 12390
    
    ... image-data here ...
    """
    import io
    import requests
    import cv2
    import numpy as np
    
    
    class MjpegReader():
        def __init__(self, url: str):
            self._url = url
    
        def iter_content(self):
            """
            Raises:
                RuntimeError
            """
            r = requests.get(self._url, stream=True)
    
            # parse boundary
            content_type = r.headers['content-type']
            index = content_type.rfind("boundary=")
            assert index != 1
            boundary = content_type[index+len("boundary="):] + "\r\n"
            boundary = boundary.encode('utf-8')
    
            rd = io.BufferedReader(r.raw)
            while True:
                self._skip_to_boundary(rd, boundary)
                length = self._parse_length(rd)
                yield rd.read(length)
    
        def _parse_length(self, rd) -> int:
            length = 0
            while True:
                line = rd.readline()
                if line == b'\r\n':
                    return length
                if line.startswith(b"Content-Length"):
                    length = int(line.decode('utf-8').split(": ")[1])
                    assert length > 0
    
    
        def _skip_to_boundary(self, rd, boundary: bytes):
            for _ in range(10):
                if boundary in rd.readline():
                    break
            else:
                raise RuntimeError("Boundary not detected:", boundary)
    
    mr = MjpegReader("http://127.0.0.1/mjpeg.cgi")
    for content in mr.iter_content():
        i = cv2.imdecode(np.frombuffer(content, dtype=np.uint8), cv2.IMREAD_COLOR)
        cv2.imshow('i', i)
        if cv2.waitKey(1) == 27:
            break
    

提交回复
热议问题