使用OpenCV时,GTK应用程序不刷新UI

时间:2014-12-02 06:03:58

标签: c opencv gtk raspberry-pi

我在C中为RaspBerry PI编写了一个简单的GUI应用程序,同时使用GTK + 2.0来处理实际的UI渲染。到目前为止,应用程序非常简单,只需几个按钮即可测试我编写的简单函数。一个按钮导致线程被唤醒,其将文本打印到控制台,然后返回睡眠状态,而另一个按钮通过锁定互斥锁,更改状态变量,然后再次解锁互斥锁来提前停止此操作。到目前为止相当简单的东西。使用这种线程方法的目的是让我在长时间的函数调用期间不会“锁定”UI,迫使用户在UI再次可用之前完成I / O操作的阻塞。

如果我在线程的处理循环中调用以下函数,我会遇到很多问题。

#include <opencv2/objdetect/objdetect.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>

#include <stdio.h>
#include <errno.h>

using namespace std;
using namespace cv;

#define PROJECT_NAME       "CAMERA_MODULE" // Include before liblog
#include <log.h>

int cameraAcquireImage(char* pathToImage) {
   if (!pathToImage) {
      logError("Invalid input");
      return (-EINVAL);
   }
   int iErr = 0;
   CvCapture *capture = NULL;
   IplImage *frame, *img;

   //0=default, -1=any camera, 1..99=your camera
   capture = cvCaptureFromCAM(CV_CAP_ANY);
   if(!capture) {
      logError("No camera interface detected");
      iErr = (-EIO);
   }
   if (!iErr) {
      if ((frame = cvQueryFrame(capture)) == NULL) {
         logError("ERROR: frame is null...");
         iErr = (-EIO);
      }
   }
   if (!iErr) {
      CvSize size = cvSize(100, 100);
      if ((img = cvCreateImage(size, IPL_DEPTH_16S, 1)) != NULL) {
         img = frame;
         cvSaveImage(pathToImage, img);
      }
   }
   if (capture) {
      cvReleaseCapture(&capture);
   }
   return 0;
}

该功能使用一些简单的OpenCV代码,通过连接到我的Raspberry PI的网络摄像头拍摄快照。它向控制台发出VIDIOC_QUERYMENU: Invalid argument警告,但仍设法获取图像并将其保存到文件中。但是,我的GUI变得迟钝,有时会挂起。如果它没有完全挂起,则窗口变为空白,我必须在UI区域上随机点击,直到我点击按钮通常位于的位置,并且UI最终再次重新渲染而不是显示白色空布局。

我该如何解决这个问题?当使用它作为Gtk + 2.0应用程序的一部分时,这是OpenCv中的一些怪癖吗?我最初将我的项目设置为GTK3.0应用程序,但由于GTK中的某些检查阻止了多个版本被包含在单个应用程序中,因此它无法运行,而且似乎OpenCv是GTK + 2.0的扩展。 / p>

谢谢。

2 个答案:

答案 0 :(得分:1)

你没有忘记释放img指针吗?

另外,我过去曾在磁盘上存储过未压缩图像的应用程序,过去常常变得迟钝。事实上,花费时间的是将图像存储在磁盘上,因为它超出了文件系统层可以处理的最大带宽。

因此,请尝试查看是否可以存储压缩图像(交换一些CPU以节省带宽),或将图像存储在队列中的RAM中并在之后保存(在单独的线程中或在空闲处理程序中)。当然,如果您捕获的视频太长,您最终可能会遇到内存不足的情况。我只有几秒钟的序列存储,所以这就行了。

答案 1 :(得分:1)

这里有一些很糟糕的事情:

  CvSize size = cvSize(100, 100);
  if ((img = cvCreateImage(size, IPL_DEPTH_16S, 1)) != NULL) {
     img = frame;
     cvSaveImage(pathToImage, img);
  }

首先,你创建一个无用的16位图像(为什么甚至?),然后你重新指定(别名)指针到原始图像,然后你不要cvReleaseImage它(memleak)。

请停止使用opencv弃用的c-api。请。

另外,你只能以这种方式使用~30%的opencv功能(opencv1.0设置)

请再次停止使用opencv弃用的c-api。请。