views:

880

answers:

2

Hi all,

I am working on a school project with OpenCV. A major part of the program will be a comparison of histograms. There will be a database of histograms and new histograms will be created from a live video feed then compared to the histograms in the database. Right now I am just trying to get the histograms created correctly from the video feed. My problem is that the program crashes or slows down dramatically at random intervals. So my question is how do I prevent the program from crashing or slowing down? OpenCV has always been kind of flaky for me, so I'm not sure if it is an issue with my code or if it is just the nature of OpenCV. If it is to do with my code I think the issue might have something to do with the frame rates (a guess/gut feeling). I am useing "cvWaitKey" to "pace" the loading of frames, but the "Learning OpenCV" book has this to say about "cvWaitKey"

c = cvWaitKey(33); if( c == 27 ) break; Once we have displayed the frame, we then wait for 33 ms. If the user hits a key, then c will be set to the ASCII value of that key; if not, then it will be set to –1. If the user hits the Esc key (ASCII 27), then we will exit the read loop. Otherwise, 33 ms will pass and we will just execute the loop again. It is worth noting that, in this simple example, we are not explicitly controlling the speed of the video in any intelligent way. We are relying solely on the timer in cvWaitKey() to pace the loading of frames. In a more sophisticated application it would be wise to read the actual frame rate from the CvCapture structure (from the AVI) and behave accordingly!

You will see in my code below (modified from here) that I my loop waits 10ms before starting the next execution. Often times the program will run with no issues at all, but sometimes it will crash less than a minute in, or five minutes in, there really is not pattern that I can detect. Any suggestions on how this crash( or slow down) can be prevented would be welcomed. Also I should add that I am using OpenCV 1.1 (can't ever get OpenCV 2.0 to work right), I am using Visual Studio 2008, and I create an .MSI installer package everytime I modify my code, that is, I do not debug in Visual Studio. Dependencies are cv110.dll, cxcore110.dll, and highgui110.dll. My code is below:

// SLC (Histogram).cpp : Defines the entry point for the console application.

#include "stdafx.h"
#include <cxcore.h>
#include <cv.h>
#include <cvaux.h>
#include <highgui.h>
#include <stdio.h>
#include <sstream>
#include <iostream>

using namespace std;

int main(){

    CvCapture* capture = cvCaptureFromCAM(0);

    if(!cvQueryFrame(capture)){
        cout<<"Video capture failed, please check the camera."<<endl;
    }

    else{
        cout<<"Video camera capture successful!"<<endl;
    };

    CvSize sz = cvGetSize(cvQueryFrame(capture));

    IplImage* image = cvCreateImage(sz, 8, 3);
    IplImage* imgHistogram = 0;
    IplImage* gray = 0;
    CvHistogram* hist;

    cvNamedWindow("Image Source",1);
    cvNamedWindow("Histogram",1);

    for(;;){

        image = cvQueryFrame(capture);

        //Size of the histogram -1D histogram
        int bins = 256;
        int hsize[] = {bins};

        //Max and min value of the histogram
        float max_value = 0, min_value = 0;

        //Value and normalized value
        float value;
        int normalized;

        //Ranges - grayscale 0 to 256
        float xranges[] = {0, 256};
        float* ranges[] = {xranges};

        //Create an 8 bit single channel image to hold a grayscale version of the original picture
        gray = cvCreateImage(cvGetSize(image), 8, 1);
        cvCvtColor(image, gray, CV_BGR2GRAY);

        //Planes to obtain the histogram, in this case just one
        IplImage* planes[] = {gray};

        //Get the histogram and some info about it
        hist = cvCreateHist(1, hsize, CV_HIST_ARRAY, ranges,1);
        cvCalcHist(planes, hist, 0, NULL);
        cvGetMinMaxHistValue(hist, &min_value, &max_value);
        printf("Minimum Histogram Value: %f, Maximum Histogram Value: %f\n", min_value, max_value);

        //Create an 8 bits single channel image to hold the histogram and paint it white
        imgHistogram = cvCreateImage(cvSize(bins, 50),8,3);
        cvRectangle(imgHistogram, cvPoint(0,0), cvPoint(256,50), CV_RGB(255,255,255),-1);

        //Draw the histogram
        for(int i=0; i < bins; i++){
            value = cvQueryHistValue_1D(hist, i);
            normalized = cvRound(value*50/max_value);
            cvLine(imgHistogram,cvPoint(i,50), cvPoint(i,50-normalized), CV_RGB(0,0,0));
        }

        cvFlip(image, NULL, 1);
        cvShowImage("Image Source", image);
        cvShowImage("Histogram", imgHistogram);

        //Page 19 paragraph 3 of "Learning OpenCV" tells us why we DO NOT use "cvReleaseImage(&image)" in this section
        cvReleaseImage(&imgHistogram);
        cvReleaseImage(&gray);
        cvReleaseHist(&hist);

        char c = cvWaitKey(10);

        //if ASCII key 27 (esc) is pressed then loop breaks
        if(c==27) break;

    }

    cvReleaseImage(&image);
    cvReleaseCapture(&capture);
    cvDestroyAllWindows();

}
A: 

Only a few things I can see or recommend:

Considering the build, make sure you're building in Release. Also, make sure the build of OpenCV you're using was built with OpenMP enabled, it makes an enormous difference.

Try moving your allocations outside the loop. Every loop you're re-creating gray and other images, when they should be re-used.

The other thing is your style, which makes it difficult to give good recommendations easily. It's poor style to pre-declare a bunch of variables, this is C-style. Declare your variables just prior to their use, and the code will be easier to read.

GMan
I must go for now, but stuff like that is what you should look for. Avoid constantly dynamic allocation, try to move that outside the loop.
GMan
Could you elaborate? Do you just mean that the OpenMP version is less buggy or something like that? I origianlly tried to use 2.0 (from sourceforge) but I could never get it to link correctly in Visual Studio 2008. I ended up using an older version that my book used (version 1.1, previously on sourceforge). I will try to improve my style too as you said, I am new to C++ (and all programming for that matter) so I'm sure my "style" will develop with time :)
typoknig
OpenMP is a multi-threading extension. With it enabled, the performance of OpenCV can increase dramatically.
GMan
I have been playing with this for a bit now, and please correct me if I am wrong, but if I move gray outside of my loop it will not update with each pass of the loop, thus the histogram will not update. I think I have to re-create gray with every pass of the loop to make this code work.
typoknig
@typoking: What did you move out? you should be able to move this out: `gray = cvCreateImage(cvGetSize(image), 8, 1);` and the matching release.
GMan
"gray" is created from "image" and "planes" is created from "gray" and the histogram is calculated from "planes". I need a new histogram with every frame so I think I need all of those items to update with every loop. How can they update if I move them outside the loop (I am not asking sarcasticly :) )?
typoknig
@typo: Do not move the update code out, only the `cvCreateImage` part. That isn't the part that does the conversion.
GMan
Update: I found the issue, it was actually my hardware (well the driver I think). I was using a PS3 Eye because of the amazing frame rates, but for some reason OpenCV does not like the PS3 Eye all the time. Sometimes it works great and other times not so great. I have verfied this on three computers, all of which run my code good with a standard web cam but randomly lock up when the PS3 Eye is used. Still, thank you for your suggestions GMan!
typoknig
@typo: No problems.
GMan
A: 

Update: I found the issue, it was actually my hardware (well the driver I think). I was using a PS3 Eye because of the amazing frame rates, but for some reason OpenCV does not like the PS3 Eye all the time. Sometimes it works great and other times not so great. I have verfied this on three computers, all of which run my code good with a standard web cam but randomly lock up when the PS3 Eye is used. Still, thank you for your suggestions GMan!

typoknig