GtkImage 没有更新,opencv 也不会释放图像

GtkImage isn't updating and opencv won't free images

本文关键字:释放 图像 opencv 更新 GtkImage      更新时间:2023-10-16

我正在尝试显示来自网络摄像头的视频。我使用opencv从网络摄像头上捕捉图像,然后尝试在GtkImage上显示它们。

这是我的代码,它在一个单独的线程中运行。

  gpointer View::updateView(gpointer v)
{
    IplImage *image;
    CvCapture *camera;
    GMutex *mutex;
    View *view;
    view=(View*)v;
    camera=view->camera;
    mutex=view->cameraMutex;
    while(1)
    {
        g_mutex_lock(view->cameraMutex);
        image=cvQueryFrame(camera);
        g_mutex_unlock(view->cameraMutex);
        if(image==NULL) continue;
        cvCvtColor(image,image,CV_BGR2RGB);
        GDK_THREADS_ENTER();
        g_object_unref(view->pixbuf);
        view->pixbuf=gdk_pixbuf_new_from_data((guchar*)image->imageData,GDK_COLORSPACE_RGB,FALSE,image->depth,image->width,image->height,image->widthStep,NULL,NULL);
        gtk_image_set_from_pixbuf(GTK_IMAGE(view->image),view->pixbuf);
        gtk_widget_queue_draw(view->image);
        GDK_THREADS_LEAVE();
        usleep(10000);
    }
}

发生的情况是,从网络摄像头上拍摄一张图像并显示,然后GtkImage停止更新。

此外,当我尝试使用cvReleaseImage时,我会得到一个seg错误,它说free被传递了一个无效的指针。

GTK是一个事件驱动的工具包,与许多其他工具包一样。你所做的是将新图像排队绘制成无限循环,但永远不要给GTK绘制它们的机会。消息泵不是这样工作的。您需要将手交回GTK,以便它可以绘制更新的图像。gtk_events_pending文档中解释了执行此操作的方法。

此外,为每个图像分配/绘制/取消分配gdk像素是次优的。只需在循环结束后分配缓冲区,在循环中绘制缓冲区(它将覆盖以前的内容),然后显示它。只有当图像大小发生变化时,才需要重新分配新的缓冲区。

我不知道如何使用GtkImgae,但我的猜测是,您没有将更新的图像传递到窗口。您需要一些类似于原生cvShowImage的东西来在循环中执行。如果不是,我不知道。

此外,您不应该发布用于捕获的图像。OpenCV自己分配和解除分配。

编辑:尝试使用OpenCV函数查看图像,看看问题是否仍然存在。