opencv读取视频和摄像头,写视频

 https://docs.opencv.org/3.0-beta/doc/py_tutorials/py_gui/py_video_display/py_video_display.html

https://zhuanlan.zhihu.com/p/38136322

当我们需要读取网络摄像头的时候,我们可以对 cap = cv2.VideoCapture(括号里面的东西进行修改),填写上我们想要读取的视频流,它可以是:

  • 数字0,代表计算机的默认摄像头(例如上面提及的笔记本前置摄像头)
  • video.avi 视频文件的路径,支持其他格式的视频文件
  • rtsp路径(不同品牌的路径一般是不同的,如下面举出的海康与大华,详细情况查看 附录的「关于rtsp协议」)
user, pwd, ip, channel = "admin", "admin123456", "172.20.114.26", 1

video_stream_path = 0  # local camera (e.g. the front camera of laptop)
video_stream_path = 'video.avi'  # the path of video file
video_stream_path = "rtsp://%s:%s@%s/h265/ch%s/main/av_stream" % (user, pwd, ip, channel)  # HIKIVISION old version 2015
video_stream_path = "rtsp://%s:%s@%s//Streaming/Channels/%d" % (user, pwd, ip, channel)  # HIKIVISION new version 2017
video_stream_path = "rtsp://%s:%s@%s/cam/realmonitor?channel=%d&subtype=0" % (user, pwd, ip, channel)  # dahua

cap = cv2.VideoCapture(video_stream_path)

 

rtsp视频流

https://blog.csdn.net/hpuhjl/article/details/80685572

大华:

1、地址格式分段含义说明:

  1. rtsp://[username]:[password]@[address]:[port]/cam/realmonitor?channel=[id]&subtype=[type]
  2. rtsp:// => 协议格式头
  3. username => 用户名,例如:admin
  4. password => 密码,例如:123456
  5. address => IPC设备的网络地址,例如:192.168.1.65
  6. port => IPC设备的RTSP输出端口,默认为554,若为默认可不填写
  7. id => 通道号,起始为1。例如通道2,则为channel=2
  8. type => 码流类型,主码流为0(即subtype=0),辅码流为1(即subtype=1)。

2、示例,拉取大华网络摄像机通道1的RTSP地址:

  1. 通道1,主码流:
    rtsp://admin:123456@192.168.1.65:554/cam/realmonitor?channel=1&subtype=0
  2. 通道1,子码流:
    rtsp://admin:123456@192.168.1.65:554/cam/realmonitor?channel=1&subtype=1

海康

1、地址格式分段含义说明:

    1. rtsp://[username]:[password]@[address]:[port]/Streaming/Channels/[id]?transportmode=[type]
    2. rtsp:// => 协议格式头
    3. username => 用户名,例如:admin
    4. password => 密码,例如:123456
    5. address => IPC设备的网络地址,例如:192.168.1.65
    6. port => IPC设备的RTSP输出端口,默认为554,若为默认可不填写
    7. id => 通道号&码流类型
    8. 101:通道1主码流 201通道2主码流
    9. 102:通道1子码流 202通道2子码流
    10. 103:通道1第三码流
    11. 1201:通道17主码流
    12. 001:通道0主码流
    13. type => 可选参数,拉流模式,默认为unicast,若为默认可以不填写
    14. unicast:单播模式拉流
    15. multicast:组播模式拉流

将多张图片合成视频

import cv2
import os
from bs4 import BeautifulSoup


def parse_xml(xml_file):
    soup = BeautifulSoup(open(xml_file, "r", encoding="utf-8"), 'xml')
    tags = soup('object')
    lines = []
    width = int(soup.size.width.string)
    height = int(soup.size.height.string)
    for each in tags:
        line = []
        name = each.find('name').string.strip()
        # if name == "boat":
        if name == "boat":
            xmin = int(each.bndbox.xmin.string)
            ymin = int(each.bndbox.ymin.string)
            xmax = int(each.bndbox.xmax.string)
            ymax = int(each.bndbox.ymax.string)
            # Todo: 预测坐标中会有负数
            if (xmax < xmin) or (xmax > width) or (xmin < 0):
                print("xmin, xmax value not valid {} {} in {}".format(xmin, xmax, xml_file))
                # raise Exception("xmin, xmax value not valid {} {} in {}".format(xmin, xmax, xml_file))
            if (ymax < ymin) or (ymax > height) or (ymin < 0):
                print(("ymin, ymax value not valid {} {} in {}".format(ymin, ymax, xml_file)))
                # raise Exception("ymin, ymax value not valid {} {} in xml_file".format(ymin, ymax, xml_file))
            # 处理坐标边界
            xmin = 0 if xmin < 0 else xmin
            xmax = width if xmax > width else xmax
            ymin = 0 if ymin < 0 else ymin
            ymax = height if ymax > height else ymax
            line.append(xmin)
            line.append(ymin)
            line.append(xmax)
            line.append(ymax)
            lines.append(line)
        else:
            print(("Invalid name: {} in file {}".format(name, xml_file)))
            # raise Exception("Invalid name: {} in file {}".format(name, xml_file))
    return lines


def images_to_video():
    fps = 10  # 帧率
    img_width = 1920
    img_height = 1080
    out = cv2.VideoWriter(r'F:\tmp\nanhang_detect.mp4', cv2.VideoWriter_fourcc(*'mp4v'), fps, (img_width, img_height))
    path = r"F:\tmp\temp"
    for file_name in os.listdir(path):
        if file_name.endswith(".jpg"):
            img_file = os.path.join(path, file_name)
            xml_file = img_file.replace(".jpg", ".xml")
            img = cv2.imread(img_file)
            if os.path.exists(xml_file):
                lines = parse_xml(xml_file)
                for line in lines:
                    # print(line)
                    xmin, ymin,xmax, ymax= line
                    cv2.rectangle(img, (xmin,ymin), (xmax, ymax), (0, 255, 0), 2)
            # cv2.namedWindow("img", cv2.WINDOW_NORMAL)
            # cv2.resizeWindow("img", 960, 540)
            # cv2.imshow("img", img)
            # cv2.waitKey(0)
            # cv2.destroyAllWindows()
            out.write(img)
    out.release()

images_to_video()
合成视频

 

posted @ 2024-09-21 13:10  silence_cho  阅读(368)  评论(0)    收藏  举报