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

时间:2012-03-26 04:31:07

标签: c++ c opencv gtk

我正在尝试从网络摄像头显示视频。我使用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已经传递了无效的指针。

2 个答案:

答案 0 :(得分:2)

GTK是一个事件驱动的工具包,与许多其他工具包一样。你正在做的是将新图像排队以无限循环绘制,但绝不让GTK有机会绘制它们。这不是message pump的工作原理。你需要回到GTK,这样它就可以绘制更新的图像。 gtk_events_pending文档中解释了执行此操作的方法。

此外,为每个图像分配/绘制/解除分配gdk-pixpuf是次优的。只需在循环中分配一次缓冲区,在循环中绘制它(它将覆盖以前的内容),然后显示它。如果图像大小发生变化,您只需要重新分配新的缓冲区。

答案 1 :(得分:0)

我不知道如何使用GtkImgae,但我的猜测是你没有将新图像传递到窗口。您需要在循环内部执行类似本机cvShowImage的操作。如果不是我不知道。

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

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