0
votes

I have a simple GUI application I wrote in C for the RaspBerry PI while using GTK+2.0 to handle the actual UI rendering. The application so far is pretty simple, with just a few pushbuttons for testing simple functions I wrote. One button causes a thread to be woken up which prints text to the console, and goes back to sleep, while another button stops this operation early by locking a mutex, changing a status variable, then unlocking the mutex again. Fairly simple stuff so far. The point of using this threaded approach is so that I don't ever "lock up" the UI during a long function call, forcing the user to be blocked on the I/O operations completing before the UI is usable again.

If I call the following function in my thread's processing loop, I encounter a number of issues.

#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;
}

The function uses some simple OpenCV code to take a snapshot with a webcam connected to my Raspberry PI. It issues warnings of VIDIOC_QUERYMENU: Invalid argument to the console, but still manages to acquire the images and save them to a file for me. However, my GUI becomes sluggish, and sometimes hangs. If it doesn't outright hang, then the window goes blank, and I have to randomly click all over the UI area until I click on where a pushbutton would normally be located, and the UI finally re-renders again rather than showing a white empty layout.

How do I go about resolving this? Is this some quirk in OpenCv when using it as part of a Gtk+2.0 application? I had originally had my project setup as a GTK3.0 application, but it wouldn't run due to some check in GTK preventing multiple versions from being included in a single application, and it seems OpenCv is an extension of GTK+2.0.

Thank you.

2

2 Answers

1
votes

Didn't you forget to free the img pointer ?

Also, I did in the past an app that stored uncompressed images on the disk, and things used to become sluggish. In fact, what was taking time was storing the images on the disk, as it was exceeding the max bandwidth of what the filesystem layer could handle.

So try to see is you can store compressed images instead (trading some CPU to save bandwidth), or store your images in RAM in a queue and save them afterwards (in a separate thread, or in an idle handler). Of course, if the video you capture is too long, you may end up with an Out Of Memory condition. I only had sequences of a few seconds to store, so that did the trick.

1
votes

there is something quite broken here:

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

first, you create a useless 16-bit image (why even?), then you reassign(alias) that pointer to your original image, and then you don't cvReleaseImage it (memleak).

please, stop using opencv's deprecated c-api. please.

any noob will shoot into his foot using this (one of the main reasons to get rid of it)

also, you can only use ~30% of opencv's functionality this way (the opencv1.0 set)

again, please, stop using opencv's deprecated c-api. please.