nufi
개요
NuFiStreamer의 핵심 element입니다.
nufi element는 model property에 설정된 객체들을 이용해 이미지 프레임 데이터들을 처리하는 element입니다.
처리된 결과 metadata를 buffer에 입력하여 link된 다음 element로 전달합니다.
NuFiStreamer에서는 기본적으로 model property에 설정할 수 있는 객체들을 제공하고 있습니다. (Models 정보)
제공하는 추론 모델과 같이 nufi element에 설정할 수 있는 모델을 만들고 싶다면 커스텀 모델 이용하기 튜토리얼을 참고해주세요.
상세 설명
- nufi elements는 내부적으로 model property에 설정된 객체들을 이용해서 이미지 프레임 데이터들을 Multi threading으로 processing합니다.
- 처리된 결과 metadata(NufiResult)를 buffer에 쓰고 해당 buffer를 저장했다면 이후의 모든 element에서 이 값을 읽거나 수정할 수 있습니다.
Properties
- model: 필수 입력사항입니다. 추론 시 이용할 model 객체 list를 넣습니다.
- framerate: 초당 추론할 프레임 개수를 넣습니다. int, float, string(ex. "5 / 1")으로 표현합니다.
- direct-push: 추론하지 않는 프레임들이 추론하는 프레임을 기다리지 않고 즉시 push 됩니다. boolean으로 표현합니다.
사용 예시
- nufi element를 이용한 간단한 추론 파이프라인 예시 코드입니다.
- 타겟 영상 파일을 프레임 단위로 추론하여 객체 탐지 결과 영상을 저장하는 코드입니다.
- nufi.models 하위에 존재하는 inference class 객체를 생성하여 models property에 삽입합니다.
run_sdstreamer(video_path, result_file_path)
함수를 이용하여 추론 파이프라인을 생성하고 이를 실행합니다.- video_path: 추론에 이용할 타겟 영상 파일 path를 의미합니다.
- result_file_path: 추론된 결과 영상 파일이 저장될 path를 의미합니다.
- NuFiStreamer elements를 제외한 다른 elements에 대한 정보가 궁금하다면 Gstreamer docs를 참고해주세요.
import logging as log
import os
import sys
from gi.repository import GLib, Gst
import nufi
from nufi.models.yolo import Yolo
nufi.init()
def bus_call(_, message, loop):
t = message.type
if t == Gst.MessageType.EOS:
log.info("End-of-stream")
loop.quit()
elif t == Gst.MessageType.WARNING:
err, debug = message.parse_warning()
log.warning("Warning: %s: %s", err, debug)
elif t == Gst.MessageType.ERROR:
err, debug = message.parse_error()
log.error("Error: %s: %s", err, debug)
loop.quit()
return True
def run_sdstreamer(video_path, result_file_path):
# 1. Elements 생성
filesrc = Gst.ElementFactory.make("filesrc", "filesrc")
decodebin = Gst.ElementFactory.make("decodebin", "decodebin")
videoconvert1 = Gst.ElementFactory.make("videoconvert", "videoconvert1")
queue = Gst.ElementFactory.make("queue", "queue")
# - nufi element 생성
nufi = Gst.ElementFactory.make("nufi", "yolo")
draw = Gst.ElementFactory.make("draw", "draw")
qos = Gst.ElementFactory.make("qos", "qos")
videoconvert2 = Gst.ElementFactory.make("videoconvert", "videoconvert2")
x264enc = Gst.ElementFactory.make("x264enc", "x264enc")
mp4mux = Gst.ElementFactory.make("mp4mux", "mp4mux")
sink = Gst.ElementFactory.make("filesink", "filesink")
elements = [
filesrc,
decodebin,
videoconvert1,
queue,
nufi,
draw,
qos,
videoconvert2,
x264enc,
mp4mux,
sink,
]
if not all(elements):
log.error("Unable to create Elements")
sys.exit(-1)
# 2. Elements properties 설정
filesrc.set_property("location", video_path)
videoconvert1.set_property("n-threads", 16)
videoconvert2.set_property("n-threads", 16)
sink.set_property("location", result_file_path)
# - nufi element models 설정
models = [Yolo() for _ in range(1)] # multi processing 이용 시 range iteration 횟수 변경
nufi.set_property("model", models)
# 3. 파이프라인 생성
pipeline = Gst.Pipeline()
pipeline.add(*elements)
for i in range(len(elements) - 1):
if elements[i].name != "decodebin":
if not Gst.Element.link(elements[i], elements[i + 1]):
# if not elements[i].link(elements[i + 1]):
log.error(
"Elements %s and %s could not be linked.",
elements[i].get_name(),
elements[i + 1].get_name(),
)
sys.exit(-1)
loop = GLib.MainLoop()
bus = pipeline.get_bus()
bus.add_signal_watch()
bus.connect("message", bus_call, loop)
def on_demuxer_pad_added(_, pad):
if not pad.has_current_caps():
log.error("Pad %s has no caps, can't link", pad.get_name())
sys.exit(-1)
caps = pad.get_current_caps()
struct = caps.get_structure(0)
if struct.get_name().startswith("video"):
pad.link(videoconvert1.get_static_pad("sink"))
decodebin.connect("pad-added", on_demuxer_pad_added)
# 4. 파이프라인 시작
ret = pipeline.set_state(Gst.State.PLAYING)
if ret == Gst.StateChangeReturn.FAILURE:
log.error("Unable to set the pipeline to the playing state.")
sys.exit(-1)
try:
loop.run()
except Exception as e:
log.error("App finished : %s", e)
loop.quit()
pipeline.set_state(Gst.State.NULL)
return result_file_path
출력 예시
- nufi element에 설정된 Yolo model을 이용하여 추론한 결과 영상입니다.
추론 전 영상 | 추론 후 영상 |
---|---|