As title suggests I am reading frames from my webcam (using openCV, i want to do some follow up feature detection with it) and want to write the result to a pyGTK3 DrawableArea widget. Following this answer, which i will quote for convenience:
The following seems to do the job:
def draw(self, widget, context):
Gdk.cairo_set_source_pixbuf(context, self.pixbuf, 0, 0)
context.paint()
One question still remains: Is this the preferred way of doing things?
So i am now using:
def _on_drawablearea_draw(self, canvas, context):
frame = self.stream.read()
self.pixbuf = self._frame2pixbuf(frame)
Gdk.cairo_set_source_pixbuf(context, self.pixbuf, 0, 0)
context.paint()
def _frame2pixbuf(self, frame):
height, width, rgb_stride = frame.shape
frame_to_list = frame.flatten() # must become list
return GdkPixbuf.Pixbuf.new_from_data(frame_to_list,
GdkPixbuf.Colorspace.RGB,
False, 8,
width, height, rgb_stride * width)
frame
is a numpy array of shape (m,n,3)
.
Unfortunately, I get a segmentation fault
at the statement:
Gdk.cairo_set_source_pixbuf(context, self.pixbuf, 0, 0)
This apparantly happened to more members as seen in the comments to the above quoted answer, however no solution was provided and a quick google search yields no results.
Update 1: Loading pixbuf from file is working as expected, i.e.
def _image2pixbuf(self):
filename = 'some_test_image.jpg'
return GdkPixbuf.Pixbuf.new_from_file(filename)
with the same call to _on_drawablearea_draw
except for the change to ._image2pixbuf
renders some_test_image.jpg
perfectly in the DrawableArea widget.
Update 2: Converting to bytes and creating the pixbuf from bytes works for me, i.e.
def _frame2pixbuf(self, frame):
height, width, rgb_stride = frame.shape
frame_in_bytes = GLib.Bytes.new(frame.tobytes())
return GdkPixbuf.Pixbuf.new_from_bytes(frame_in_bytes,
GdkPixbuf.Colorspace.RGB,
False, 8,
width, height, rgb_stride * width)
but it adds an 'unnecessary' (?) additional step of converting the frame data to bytes.
Questions:
How do i fix this segmentation fault in the case of
GdkPixbuf.Pixbuf.new_from_data
? It seems to me now that the arguments to the function are badly chosen.Furthermore, as the above quoted answer also asks: is this the preferred way of writing a frame from a webcam to a DrawableArea widget?