opencv - 在 Gtk Widget 中显示 OpenCV 图像时出现内存泄漏

标签 opencv python-3.x gtk glib gdk

我正在尝试创建一个 Gtk 小部件,您可以将 OpenCV 图像传递给该小部件,然后将其显示出来。我创建了一个继承自 Gtk.Image 的类,用于显示图像。您可以使用 show_frame 方法将 OpenCV 图像传递给此类,然后该方法会更新 Gtk.Image 以显示该图像。

我已经对此进行了测试,它工作正常,即当调用 show_frame 方法时,图像可以正确显示和更新。然而,每次更新图像时,使用的内存都会增加,直到内存不足而程序崩溃。

我认为这是由于图像未正确释放的内存造成的。然而我无法弄清楚如何解决这个问题。我尝试在收到新帧后取消引用gbytes,但这没有帮助。仅当调用 set_from_pixbuf 函数时才会建立内存。如果将此注释掉,内存使用量将保持在恒定水平。

class OpenCVImageViewer(Gtk.Image):
    def __init__(self):
        Gtk.Image.__init__(self)

    def show_frame(self, frame):
        # Convert to opencv BGR to Gtk RGB
        rgb_image = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)

        # Get details about frame in order to set up pixbuffer
        height = rgb_image.shape[0]
        width = rgb_image.shape[1]
        nChannels = rgb_image.shape[2]

        gbytes = GLib.Bytes.new(rgb_image.tostring())
        pixbuf = GdkPixbuf.Pixbuf.new_from_bytes(gbytes, GdkPixbuf.Colorspace.RGB, False,
                                                 8, width, height, width*nChannels)

        # Add Gtk to main thread loop for thread safety
        GLib.idle_add(self.set_from_pixbuf, pixbuf)
        GLib.idle_add(self.queue_draw)

最佳答案

嗯,

我找到了一个解决方案,但我不明白它为什么有效:使用 pixbuffer 的副本设置图像。

 imageWidget.set_from_pixbuf(pixbuffer.copy())

在观察到缩放pixbuffer的内存泄漏消失后(即pixbuffer.scale_simple的结果),我得出了这个解决方案。

关于opencv - 在 Gtk Widget 中显示 OpenCV 图像时出现内存泄漏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30624988/

相关文章:

opencv - ImportError : No module named pyimagesearch. 人脸检测器

python-3.x - 只批处理读取/将最后一张图像保存在文件夹中

python - 如何为 Python 3 安装 `cv`?

Haskell GTK 和 Monad 变压器

opencv - 如何通过多个摄像头跟踪人物?

OpenCV 级联分类器训练

python - 通过在 youtube 中搜索,使用 Python 打开第一个视频

python - 使用 Python 3 创建具有唯一名称的临时文件?

gtk - 在 Rust 中处理 GTK+ 事件的替代方法

gtk - 抑制 Gtk.ToggleButton.set_active 上的信号