2012-03-26 50 views
1

我试图从网络摄像头显示视频。我使用opencv从网络摄像头捕捉图像,然后尝试在GtkImage上显示它们。GtkImage未更新,opencv也不会释放图像

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

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

与许多其他GTK一样,GTK是一个事件驱动的工具包。你正在做的是排队新的图像绘制一个无限循环,但从不给GTK一个绘制它们的机会。这不是message pump的工作原理。您需要将手放回GTK,以便绘制更新后的图像。在gtk_events_pending文档中说明了解决问题的方法。

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

0

我不知道如何使用GtkImgae,但我的猜测是你没有将新图像传递给窗口。你需要像本地cvShowImage这样的东西在循环内执行。如果不是我不知道。

另外您不应该释放用于捕获的图像。 OpenCV自己分配和释放它。

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

相关问题