正如标题所示,我正在从我的网络摄像头读取帧(使用 openCV,我想用它做一些后续特征检测)并想将结果写入 pyGTK3 DrawableArea 小部件。正在关注this答案,为方便起见我将引用:
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?
所以我现在使用:
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
是一个形状为 (m,n,3)
的 numpy 数组。
不幸的是,我在声明中得到了一个段错误
:
Gdk.cairo_set_source_pixbuf(context, self.pixbuf, 0, 0)
从对上述答案的评论中可以看出,这显然发生在更多成员身上,但是没有提供解决方案,快速谷歌搜索也没有结果。
更新 1: 从文件加载 pixbuf 按预期工作,即
def _image2pixbuf(self):
filename = 'some_test_image.jpg'
return GdkPixbuf.Pixbuf.new_from_file(filename)
除了对 ._image2pixbuf
的更改外,对 _on_drawablearea_draw
的调用相同,可在 DrawableArea 小部件中完美呈现 some_test_image.jpg
。
更新 2: 转换为字节并从字节创建 pixbuf 对我有用,即
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)
但它增加了将帧数据转换为字节的“不必要的”(?)额外步骤。
问题:
在
GdkPixbuf.Pixbuf.new_from_data
的情况下,如何修复这个段错误?现在在我看来,函数的参数选择不当。此外,正如上面引用的答案还问:这是将网络摄像头的框架写入 DrawableArea 小部件的首选方式吗?
最佳答案
要回答您的第一个问题,问题是 new_from_data()不会复制您传递给它的图像数据,它会直接使用它,在您的情况下,图像数据包含在 frame_in_bytes
中_frame2pixbuf
的局部变量功能。因此,一旦您离开 _frame2pixbuf
,该图像数据可能会被释放并且不再有效。功能范围。
当您使用 new_from_file
时情况并非如此分配图像内存本身的功能;也不在 new_from_bytes
的情况下因为您在堆上创建了一个新的 Bytes 对象,当您离开函数范围时该对象不会被释放。
使用new_from_data()
,您必须确保您的图像数据在 Gdk.cairo_set_source_pixbuf()
之前不会失效。叫做。我认为一种方法是将您的 _frame2pixbuf
的内容放入在你的 _on_drawablearea_draw
中发挥作用函数使得 frame_in_bytes
var 在该上下文中仍然有效。
关于python - 在 pygtk3 中从网络摄像头绘制帧到 DrawableArea 时出现段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40327001/