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、地址格式分段含义说明:
rtsp://[username]:[password]@[address]:[port]/cam/realmonitor?channel=[id]&subtype=[type]rtsp:// => 协议格式头username => 用户名,例如:adminpassword => 密码,例如:123456address => IPC设备的网络地址,例如:192.168.1.65port => IPC设备的RTSP输出端口,默认为554,若为默认可不填写id => 通道号,起始为1。例如通道2,则为channel=2type => 码流类型,主码流为0(即subtype=0),辅码流为1(即subtype=1)。
2、示例,拉取大华网络摄像机通道1的RTSP地址:
通道1,主码流:rtsp://admin:123456@192.168.1.65:554/cam/realmonitor?channel=1&subtype=0通道1,子码流:rtsp://admin:123456@192.168.1.65:554/cam/realmonitor?channel=1&subtype=1
海康
1、地址格式分段含义说明:
rtsp://[username]:[password]@[address]:[port]/Streaming/Channels/[id]?transportmode=[type]rtsp:// => 协议格式头username => 用户名,例如:adminpassword => 密码,例如:123456address => IPC设备的网络地址,例如:192.168.1.65port => IPC设备的RTSP输出端口,默认为554,若为默认可不填写id => 通道号&码流类型101:通道1主码流 201通道2主码流102:通道1子码流 202通道2子码流103:通道1第三码流1201:通道17主码流001:通道0主码流type => 可选参数,拉流模式,默认为unicast,若为默认可以不填写unicast:单播模式拉流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()

浙公网安备 33010602011771号