forked from maxsitt/insect-detect
-
Notifications
You must be signed in to change notification settings - Fork 0
/
video_capture.py
118 lines (95 loc) · 4.63 KB
/
video_capture.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
#!/usr/bin/env python3
'''
Author: Maximilian Sittinger (https://github.com/maxsitt)
Website: https://maxsitt.github.io/insect-detect-docs/
License: GNU GPLv3 (https://choosealicense.com/licenses/gpl-3.0/)
This Python script does the following:
- save encoded HQ frames (1080p or 4K resolution) with H.265 (HEVC) compression to .mp4 video file
- optional arguments:
"-min [min]" (default = 2) set recording time in minutes
-> e.g. "-min 5" for 5 min recording time
"-4k" (default = 1080p) record video in 4K resolution (3840x2160 px)
"-fps [fps]" (default = 25) set frame rate (frames per second) for video capture
-> e.g. "-fps 20" to decrease video file size
based on open source scripts available at https://github.com/luxonis
'''
import argparse
import time
from datetime import datetime
from fractions import Fraction
from pathlib import Path
import av
import depthai as dai
import psutil
# Define optional arguments
parser = argparse.ArgumentParser()
parser.add_argument("-min", "--min_rec_time", type=int, choices=range(1, 61), default=2,
help="set record time in minutes")
parser.add_argument("-4k", "--four_k_resolution", action="store_true",
help="record video in 4K resolution (3840x2160 px); default = 1080p")
parser.add_argument("-fps", "--frames_per_second", type=int, choices=range(1, 31), default=25,
help="set frame rate (frames per second) for video capture")
args = parser.parse_args()
# Get frame rate (frames per second) from optional argument (default: 25)
FPS = args.frames_per_second
# Create depthai pipeline
pipeline = dai.Pipeline()
# Create and configure camera node
cam_rgb = pipeline.create(dai.node.ColorCamera)
#cam_rgb.setImageOrientation(dai.CameraImageOrientation.ROTATE_180_DEG)
cam_rgb.setResolution(dai.ColorCameraProperties.SensorResolution.THE_4_K)
if not args.four_k_resolution:
cam_rgb.setIspScale(1, 2) # downscale 4K to 1080p HQ frames (1920x1080 px)
cam_rgb.setFps(FPS) # frames per second available for focus/exposure
# Create and configure video encoder node and define input + output
video_enc = pipeline.create(dai.node.VideoEncoder)
video_enc.setDefaultProfilePreset(FPS, dai.VideoEncoderProperties.Profile.H265_MAIN)
cam_rgb.video.link(video_enc.input)
xout_vid = pipeline.create(dai.node.XLinkOut)
xout_vid.setStreamName("video")
video_enc.bitstream.link(xout_vid.input)
# Connect to OAK device and start pipeline
with dai.Device(pipeline, maxUsbSpeed=dai.UsbSpeed.HIGH) as device:
# Create output queue to get the encoded frames from the output defined above
q_video = device.getOutputQueue(name="video", maxSize=30, blocking=True)
# Create folder to save the videos
rec_start = datetime.now().strftime("%Y%m%d")
save_path = f"insect-detect/videos/{rec_start}"
Path(f"{save_path}").mkdir(parents=True, exist_ok=True)
# Create .mp4 container with H.265 (HEVC) compression
timestamp = datetime.now().strftime("%Y%m%d_%H-%M-%S")
RES = "1080p"
if args.four_k_resolution:
RES = "4K"
with av.open(f"{save_path}/{timestamp}_{FPS}fps_{RES}_video.mp4", "w") as container:
stream = container.add_stream("hevc", rate=FPS)
stream.time_base = Fraction(1, 1000 * 1000)
stream.width = 1920
stream.height = 1080
if args.four_k_resolution:
stream.width = 3840
stream.height = 2160
# Create start_time variable to set recording time
start_time = time.monotonic()
# Get recording time in min from optional argument (default: 2)
rec_time = args.min_rec_time * 60
print(f"Recording time: {args.min_rec_time} min\n")
# Get free disk space (MB)
disk_free = round(psutil.disk_usage("/").free / 1048576)
# Record until recording time is finished or free disk space drops below threshold
while time.monotonic() < start_time + rec_time and disk_free > 200:
# Update free disk space (MB)
disk_free = round(psutil.disk_usage("/").free / 1048576)
# Get encoded video frames and save to packet
enc_video = q_video.get().getData()
packet = av.Packet(enc_video)
packet.dts = int((time.monotonic() - start_time) * 1000 * 1000)
packet.pts = int((time.monotonic() - start_time) * 1000 * 1000)
# Mux packet into the .mp4 container
container.mux_one(packet)
# Print duration, fps and path of saved video + free disk space to console
if args.four_k_resolution:
print(f"\nSaved {args.min_rec_time} min 4K video with {args.frames_per_second} fps to {save_path}.")
else:
print(f"\nSaved {args.min_rec_time} min 1080p video with {args.frames_per_second} fps to {save_path}.")
print(f"Free disk space left: {disk_free} MB")