Skip to main content
Version: 2.0.0

draw

개요

이미지 처리 결과 metadata를 이미지 상에 출력하기 위한 element입니다.
buffer에서 metadata 추출하여 이미지에 출력합니다.
반드시 draw element는 모든 nufi element들 이후에 위치해야합니다.

상세 설명

  • draw element는 nufi element에서 model에 의해 이미지가 처리되고 반환되는 metadata를 이미지에 그리는 element입니다.
  • nufi element에서 기본적으로 제공되는 nufi.models 하위 객체를 이용한다면 metadata를 바로 그릴 수 있습니다.
  • nufi element에서 커스텀하게 구현된 객체를 이용한다면 draw에서 반환되는 metadata를 그리기 위해선 metadata의 type이 NufiResult이어야 합니다.

사용 예시

  • draw element를 이용한 간단한 추론 파이프라인 예시 코드입니다.
    • 타겟 영상 파일을 프레임 단위로 추론하여 객체 탐지 결과 영상을 저장하는 코드입니다.
  • draw element는 모든 추론 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 = Gst.ElementFactory.make("nufi", "yolo")
# - draw element 생성
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

출력 예시

  • draw element를 이용하여 추론 결과 metadata를 출력한 결과 영상입니다.
추론 전 영상추론 후 영상
thiland-beforethiland-result