我正在与OpenCV合作开展一个学校项目。该计划的主要部分是直方图的比较。将有一个直方图数据库,将从实时视频源创建新的直方图,然后与数据库中的直方图进行比较。现在我只是想从视频源中正确创建直方图。 我的问题是程序会以随机间隔急剧崩溃或减速。所以我的问题是我如何防止程序崩溃或放慢速度? OpenCV对我来说一直有点不稳定,所以我不确定它是否是我的代码的问题,或者它是否仅仅是OpenCV的本质。如果它与我的代码有关,我认为问题可能与帧速率有关(猜测/直觉)。我正在使用“cvWaitKey”来“加速”帧的加载,但“学习OpenCV”这本书有关于“cvWaitKey”的说法
c = cvWaitKey(33); if(c == 27)break; 一旦我们显示了帧,我们就等待33毫秒。如果用户点击密钥,则c 将被设置为该键的ASCII值;如果没有,那么它将被设置为-1。如果用户点击 Esc键(ASCII 27),然后我们将退出读循环。否则,33 ms将通过 我们将再次执行循环。 值得注意的是,在这个简单的例子中,我们没有明确控制 任何智能方式的视频速度。我们完全依赖于计时器 cvWaitKey()用于加速帧的加载。在更复杂的应用程序中它会 明智地从CvCapture结构(来自AVI)读取实际帧速率 表现得相应!
您将在下面的代码中看到(从here修改)我的循环在开始下一次执行之前等待10ms。通常程序运行时根本没有问题,但有时它会在不到一分钟或五分钟内崩溃,实际上没有我可以检测到的模式。 有关如何防止此崩溃(或减速)的任何建议都会受到欢迎。我还应该补充一点,我正在使用OpenCV 1.1(无法让OpenCV 2.0正常工作),我是使用Visual Studio 2008,每次修改代码时都会创建.MSI安装程序包,也就是说,我不在Visual Studio中调试。依赖项是cv110.dll,cxcore110.dll和highgui110.dll。我的代码如下:
// 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();
}
答案 0 :(得分:1)
我只能看到或推荐的一些东西:
考虑到构建,请确保您在Release中构建。此外,请确保您使用的OpenCV的构建是在启用OpenMP的情况下构建的,它会产生巨大的差异。
尝试在循环外移动您的分配。在重新使用时,每个循环都会重新创建gray
和其他图像。
另一个是你的风格,这使得很难轻易提出好的建议。预先声明一堆变量的风格很差,这是C风格。在使用之前声明变量,代码将更容易阅读。
答案 1 :(得分:1)
更新:我发现了问题,它实际上是我的硬件(我认为是驱动程序)。由于惊人的帧率,我使用的是PS3 Eye,但由于某些原因,OpenCV并不喜欢PS3 Eye。有时它很有效,有时则不那么好。我已经在三台计算机上进行了验证,所有这些计算机都使用标准网络摄像头运行我的代码,但在使用PS3 Eye时随机锁定。不过,谢谢你对GMan的建议!