2012-03-26 45 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功能查看圖像,看看問題是否仍然存在。