|
I'm trying to get numpy frames from an appsink pipeline so I can process the frames in python using opencv and what not.
Using farious sources I pieced together some code:
import time
import gi
import numpy as np
gi.require_version("Gst", "1.0")
gi.require_version("GstApp", "1.0")
from gi.repository import Gst, GstApp, GLib
_ = GstApp
def on_new_sample(app_sink):
sample = app_sink.pull_sample()
caps = sample.get_caps()
height = caps.get_structure(0).get_value("height")
width = caps.get_structure(0).get_value("width")
buffer = sample.get_buffer()
data = buffer.extract_dup(0, buffer.get_size())
numpy_frame = np.ndarray(
shape=(height, width, 3),
buffer=data,
dtype=np.uint8)
Gst.init(None)
pipeline = Gst.parse_launch("videotestsrc ! video/x-raw, width=240, height=320 ! queue ! videoconvert ! " +
"video/x-raw, width=240, height=320, format=BGR ! appsink sync=true max-buffers=1 drop=true name=sink emit-signals=true")
t_start = time.time()
main_loop = GLib.MainLoop()
appsink = pipeline.get_by_name("sink")
appsink.set_property("emit-signals", True)
pipeline.set_state(Gst.State.PLAYING)
handler_id = appsink.connect("new-sample", on_new_sample)
time.sleep(30)
pipeline.set_state(Gst.State.NULL)
main_loop.quit()
The problem is that it seems that numpy is unable to piece together a frame from the data it reads from the buffer. The error I get is:
TypeError: can't convert return value to desired type
I know numpy can decode the data from the buffer into a frame fine because using the following piece of code I nabbed from another thread works just fine:
for i in range(100):
pipeline.set_state(Gst.State.PLAYING)
smp = appsink.emit('pull-preroll')
caps = smp.get_caps()
height = caps.get_structure(0).get_value("height")
width = caps.get_structure(0).get_value("width")
buf = smp.get_buffer()
data=buf.extract_dup(0, buf.get_size())
frame = np.ndarray(
shape=(height, width, 3),
buffer=data ,
dtype=np.uint8)
frame = cv2.resize(frame,(0,0),fx=0.2,fy=0.2)
cv2.imshow('frame',frame)
cv2.waitKey(50)
pipeline.set_state(Gst.State.PAUSED)
Why does converting the data from the buffer into an numpy array give an error when using appsink.connect(), while it works fine using appsink.emit('pull-preroll')?
|