英文:
How to speed up Video Recording with Python cv2.VideoWriter on Jetson Nano
问题
以下是您要翻译的部分:
"I am trying to do video recording on Jetson Nano. I found that when the cv2.VideoWriter
using write()
the program becomes slow. How can I speed up the cv2.VideoWriter
? Maybe use Gstreamer
or GPU
or nvidia-component
can speed up the FPS.
My Code:
import os
import time
import cv2
width = 2560
height = 1440
framerate = 30
video_path = 'fps_test.mp4';
gs_pipeline = f"v4l2src device=/dev/video0 io-mode=2 " \
f"! image/jpeg, width={width}, height={height}, framerate={framerate}/1, format=MJPG " \
f"! nvv4l2decoder mjpeg=1 " \
f"! nvvidconv flip-method=4 " \
f"! video/x-raw, format=BGRx " \
f"! videoconvert " \
f"! video/x-raw, format=BGR " \
f"! appsink drop=1"
gs_pipeline = gs_pipeline
print(f"gst-launch-1.0 {gs_pipeline}\n")
v_cap = v_writer = None
...
Console:
```python
FPS = 0.000
FPS = 2.438
FPS = 3.606
FPS = 2.805
FPS = 2.741
FPS = 3.265
FPS = 3.603
FPS = 3.524
FPS = 3.290
如果您需要进一步的帮助,请随时提出。
英文:
I am trying to do video recording on Jetson Nano. I found that when the cv2.VideoWriter
using write()
the program becomes slow. How can I speed up the cv2.VideoWriter
? Maybe use Gstreamer
or GPU
or nvidia-component
can speed up the FPS.
My Code:
import os
import time
import cv2
width = 2560
height = 1440
framerate = 30
video_path = 'fps_test.mp4'
gs_pipeline = f"v4l2src device=/dev/video0 io-mode=2 " \
f"! image/jpeg, width={width}, height={height}, framerate={framerate}/1, format=MJPG " \
f"! nvv4l2decoder mjpeg=1 " \
f"! nvvidconv flip-method=4 " \
f"! video/x-raw, format=BGRx " \
f"! videoconvert " \
f"! video/x-raw, format=BGR " \
f"! appsink drop=1"
gs_pipeline = gs_pipeline
print(f"gst-launch-1.0 {gs_pipeline}\n")
v_cap = v_writer = None
def main():
global v_cap, v_writer
codec = cv2.VideoWriter_fourcc(*'mp4v')
v_writer = cv2.VideoWriter(video_path, codec, 20, (width, height))
v_cap = cv2.VideoCapture(gs_pipeline, cv2.CAP_GSTREAMER)
prev_frame_fetched_time = 0
while v_cap.isOpened():
ret_val, frame = v_cap.read()
if not ret_val:
break
v_writer.write(frame)
curr_frame_fetched_time = time.time()
curr_fps = 1 / (curr_frame_fetched_time - prev_frame_fetched_time)
prev_frame_fetched_time = curr_frame_fetched_time
print(f"FPS = {curr_fps:.3f}")
v_cap.release()
cv2.destroyAllWindows()
if __name__ == '__main__':
try:
main()
except KeyboardInterrupt: # If CTRL+C is pressed, exit cleanly:
pass
finally:
v_cap.release()
cv2.destroyAllWindows()
if os.path.exists(video_path):
os.remove(video_path)
Console:
FPS = 0.000
FPS = 2.438
FPS = 3.606
FPS = 2.805
FPS = 2.741
FPS = 3.265
FPS = 3.603
FPS = 3.524
FPS = 3.290
答案1
得分: 1
你可以首先尝试使用纯GStreamer录制,使用以下命令:
gst-launch-1.0 -ev v4l2src device=/dev/video0 io-mode=2 ! image/jpeg, width={width}, height={height}, framerate={framerate}/1, format=MJPG ! nvv4l2decoder mjpeg=1 ! nvvidconv flip-method=2 ! nvv4l2h264enc ! h264parse ! qtmux ! filesink location={video_path}
如果这个方法有效,你可以尝试将其拆分为OpenCV的VideoCapture和VideoWriter,假设你正在处理BGR帧:
v_cap_str = f"v4l2src device=/dev/video0 io-mode=2 " \
f"! image/jpeg, width={width}, height={height}, framerate={framerate}/1, format=MJPG " \
f"! nvv4l2decoder mjpeg=1 " \
f"! nvvidconv flip-method=2 ! video/x-raw,format=BGRx " \
f"! videoconvert ! video/x-raw,format=BGR " \
f"! queue ! appsink drop=1 "
v_cap = cv2.VideoCapture(v_cap_str, cv2.CAP_GSTREAMER)
以及VideoWriter:
v_wrt_str = f"appsrc ! video/x-raw, format=BGR ! queue " \
f"! videoconvert ! video/x-raw,format=BGRx " \
f"! nvvidconv ! video/x-raw(memory:NVMM),format=NV12 " \
f"! nvv4l2h264enc " \
f"! h264parse " \
f"! qtmux " \
f"! filesink location={video_path}"
v_wrt = cv2.VideoWriter(v_wrt_str, cv2.CAP_GSTREAMER, 0, {framerate as float}, ({width as int}, {height as int}))
确保捕获和写入两者都已打开,然后在循环中从捕获中读取帧并将其推送到写入器中。
英文:
You may first try a pure gstreamer recording with:
gst-launch-1.0 -ev v4l2src device=/dev/video0 io-mode=2 ! image/jpeg, width={width}, height={height}, framerate={framerate}/1, format=MJPG ! nvv4l2decoder mjpeg=1 ! nvvidconv flip-method=2 ! nvv4l2h264enc ! h264parse ! qtmux ! filesink location={video_path}
If this works, you may try to split into opencv VideoCapture and VideoWriter, assuming you're processing BGR frames:
v_cap_str = f"v4l2src device=/dev/video0 io-mode=2 " \
f"! image/jpeg, width={width}, height={height}, framerate={framerate}/1, format=MJPG " \
f"! nvv4l2decoder mjpeg=1 " \
f"! nvvidconv flip-method=2 ! video/x-raw,format=BGRx " \
f"! videoconvert ! video/x-raw,format=BGR " \
f"! queue ! appsink drop=1 "
v_cap = cv2.VideoCapture(v_cap_str, cv2.CAP_GSTREAMER)
and VideoWriter:
v_wrt_str = f"appsrc ! video/x-raw, format=BGR ! queue " \
f"! videoconvert ! video/x-raw,format=BGRx " \
f"! nvvidconv ! video/x-raw(memory:NVMM),format=NV12 " \
f"! nvv4l2h264enc " \
f"! h264parse " \
f"! qtmux " \
f"! filesink location={video_path}"
v_wrt = cv2.VideoWriter(v_wrt_str, cv2.CAP_GSTREAMER, 0, {framerate as float}, ({width as int}, {height as int}))
Check that both capture and writer are opened, then in loop read frames from capture and push these into writer.
答案2
得分: 0
一种可能加速使用cv2.VideoWriter进行视频录制的方法是通过NVIDIA Video Codec SDK利用硬件加速。您可以尝试使用nvv4l2h264enc GStreamer元素与OpenCV的cv2.VideoWriter,使用Jetson Nano上的硬件编码器将视频编码为H.264格式。
import os
import time
import cv2
width = 2560
height = 1440
framerate = 30
video_path = 'fps_test.mp4'
gs_pipeline = f"v4l2src device=/dev/video0 io-mode=2 " \
f"! image/jpeg, width={width}, height={height}, framerate={framerate}/1, format=MJPG " \
f"! nvv4l2decoder mjpeg=1 " \
f"! nvvidconv flip-method=4 " \
f"! video/x-raw, format=BGRx " \
f"! videoconvert " \
f"! video/x-raw, format=BGR " \
f"! nvvidconv " \
f"! 'video/x-raw(memory:NVMM), format=I420' " \
f"! nvv4l2h264enc " \
f"! h264parse " \
f"! mp4mux " \
f"! filesink location={video_path}"
print(f"gst-launch-1.0 {gs_pipeline}\n")
v_cap = v_writer = None
def main():
global v_cap, v_writer
v_cap = cv2.VideoCapture(gs_pipeline, cv2.CAP_GSTREAMER)
while v_cap.isOpened():
ret_val, frame = v_cap.read()
if not ret_val:
break
cv2.imshow('frame', frame)
key = cv2.waitKey(1)
v_cap.release()
cv2.destroyAllWindows()
if __name__ == '__main__':
try:
main()
except KeyboardInterrupt:
pass
finally:
v_cap.release()
cv2.destroyAllWindows()
if os.path.exists(video_path):
os.remove(video_path)
英文:
One way to potentially speed up the video recording with cv2.VideoWriter is to use hardware acceleration through the NVIDIA Video Codec SDK. You can try using the nvv4l2h264enc GStreamer element with OpenCV's cv2.VideoWriter to encode the video in H.264 format using the hardware encoder on the Jetson Nano.
import os
import time
import cv2
width = 2560
height = 1440
framerate = 30
video_path = 'fps_test.mp4'
gs_pipeline = f"v4l2src device=/dev/video0 io-mode=2 " \
f"! image/jpeg, width={width}, height={height}, framerate={framerate}/1, format=MJPG " \
f"! nvv4l2decoder mjpeg=1 " \
f"! nvvidconv flip-method=4 " \
f"! video/x-raw, format=BGRx " \
f"! videoconvert " \
f"! video/x-raw, format=BGR " \
f"! nvvidconv " \
f"! 'video/x-raw(memory:NVMM), format=I420' " \
f"! nvv4l2h264enc " \
f"! h264parse " \
f"! mp4mux " \
f"! filesink location={video_path}"
print(f"gst-launch-1.0 {gs_pipeline}\n")
v_cap = v_writer = None
def main():
global v_cap, v_writer
v_cap = cv2.VideoCapture(gs_pipeline, cv2.CAP_GSTREAMER)
while v_cap.isOpened():
ret_val, frame = v_cap.read()
if not ret_val:
break
cv2.imshow('frame', frame)
key = cv2.waitKey(1)
v_cap.release()
cv2.destroyAllWindows()
if __name__ == '__main__':
try:
main()
except KeyboardInterrupt:
pass
finally:
v_cap.release()
cv2.destroyAllWindows()
if os.path.exists(video_path):
os.remove(video_path)
答案3
得分: 0
你可以进行多线程操作。因此有一个线程负责获取摄像机帧,另一个线程负责写入帧。由于这两个线程将独立运行,因此不应出现延迟或减速。
英文:
You can multi-threading. So one thread for getting camera frames and another one writing the frames. As both the thread will be running independently there should be no lag/slow down.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论