python - 在 pygtk3 中从网络摄像头绘制帧到 DrawableArea 时出现段错误

标签 python opencv pygtk gtk3 pygobject

正如标题所示,我正在从我的网络摄像头读取帧(使用 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)

但它增加了将帧数据转换为字节的“不必要的”(?)额外步骤。

问题:

  1. GdkPixbuf.Pixbuf.new_from_data 的情况下,如何修复这个段错误?现在在我看来,函数的参数选择不当。

  2. 此外,正如上面引用的答案还问:这是将网络摄像头的框架写入 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/

相关文章:

python - 如何使用 NLTK 和 Python 标记和分块法语文本?

python - 使用 loc 删除索引过滤的数据框

Python 交互式控制台在 matplotlib 期间挂起?

python - 如何使用不同的形状将一个轮廓分成两个?

c - 暂时用其他容器替换容器

python-2.7 - Python子进程: Know when a command has finished

Python:用txt文件中的 float 替换字符串

c - 如何将 CvMat 从类型 CV_AA 转换为 CV_32F

python - opencv python中图像倾斜检测的代码

python - 在 PyGTK/GObject 中使用枚举属性