某些内存位置未处理的异常
Unhandled Exception at some memory location
我在一个项目中工作,我必须在其中检测人的运动。首先,我编写了一个用于运动检测的程序并使其正常工作。然后我使用 HOGDescriptor
转向人体检测,并将这两个程序结合起来以提高处理速度。首先我监视一个运动,如果检测到任何运动,然后我通过表示运动的矩形框裁剪图像,并将裁剪的部分单独发送到人体检测功能,以便快速处理。
但是出现了一个问题。有时我得到了很好的结果,有时我得到一个弹出窗口 window 说 .exe 文件中的某些内存位置出现未处理的异常 。
我的程序是
#include <iostream>
#include <ctime>
#include<stdlib.h>
#include<vector>
#include"opencv2\opencv.hpp"
#include"opencv2\highgui\highgui.hpp"
#include"opencv2\core\core.hpp"
#include"opencv2\imgproc\imgproc.hpp"
#include<string>
#include<sstream>
using namespace std;
using namespace cv;
Mat detect1(int,VideoCapture,VideoWriter);
vector<Rect> found;
int humandet(Mat,Rect);
BackgroundSubtractorMOG2 bg[5];
int _tmain(int argc, _TCHAR* argv[])
{
Mat frame[5];
string win[5]={"Video 0","Video 1","Video 2","Video 3"};
string ip,user,pass;
stringstream ss;
string vid[5]={"D:/Recorded.avi","D:/Recorded1.avi","D:/Recorded2.avi","D:/Recorded3.avi"};
VideoWriter vidarr[5];
VideoCapture cap[5];
int n,type,j;
cout<<"Enter the no of cameras";
cin>>n;
for(int i=0,j=0;i<n;i++)
{
cout<<"Enter the camera type\n1.IP camera\n2.Non IP camera";
cin>>type;
if(type==2)
{
VideoCapture cap1(j++);
cap[i]=cap1;
cap[i].set(CV_CAP_PROP_FRAME_WIDTH,320);
cap[i].set(CV_CAP_PROP_FRAME_HEIGHT,240);
cap[i].set(CV_CAP_PROP_FPS,2);
}
else
{
cout<<"Enter the IP add:portno, username and password";
cin>>ip>>user>>pass;
ss<<"http://"<<user<<":"<<pass<<"@"<<ip<<"/axis-cgi/mjpg/video.cgi?.mjpg";
string s(ss.str());
VideoCapture cap2(s);
cap[i]=cap2;
cap[i].set(CV_CAP_PROP_FRAME_WIDTH,320);
cap[i].set(CV_CAP_PROP_FRAME_HEIGHT,240);
cap[i].set(CV_CAP_PROP_FPS,2);
}
VideoWriter video(vid[i],CV_FOURCC('D','I','V','X'),2,Size(320,240));
vidarr[i]=video;
}
while(9)
{
for(int i=0;i<n;i++)
{
frame[i]=detect1(i,cap[i],vidarr[i]);
imshow(win[i],frame[i]);
}
if(waitKey(30)==27)
break;
}
return 0;
}
Mat detect1(int j,VideoCapture cap,VideoWriter vid)
{
Mat frame;
Mat diff;
cap>>frame;
double large_area=0;
int large=0;
Rect bound_rect;
bg[j].nmixtures=3;
bg[j].bShadowDetection=true;
bg[j].nShadowDetection=0;
bg[j].fTau = 0.5;
bg[j].operator() (frame,diff);
vector<vector<Point>> contour;
findContours(diff,contour,CV_RETR_EXTERNAL,CV_CHAIN_APPROX_SIMPLE);
for(unsigned int i=0;i<contour.size();i++)
{
double area=contourArea(contour[i]);
if(area>large_area)
{
large_area=area;
large=i;
bound_rect=boundingRect(contour[i]);
}
}
contour.clear();
if(large_area/100 > 2)
{
humandet(frame,bound_rect);
rectangle(frame,bound_rect,Scalar(0,0,255),2);
putText(frame,"Recording",Point(20,20),CV_FONT_HERSHEY_PLAIN,2,Scalar(0,255,0),2);
vid.write(frame);
return (frame);
}
else
return (frame);
}
int humandet(Mat frame1,Rect bound)
{
HOGDescriptor hog;
hog.setSVMDetector(HOGDescriptor::getDefaultPeopleDetector());
if((bound.height < 100) && (bound.width < 80))
{
Mat roi;
roi.create(Size(80,100),frame1.type());
roi.setTo(Scalar::all(0));
Mat fram=frame1(bound);
fram.copyTo(roi(Rect(0,0,(bound.height-1),(bound.width-1))));
hog.detectMultiScale(roi,found,0,Size(8,8),Size(32,32),1.025);
roi.release();
fram.release();
}
else if((bound.height < 200) && (bound.width < 160))
{
Mat roi;
roi.create(Size(160,200),frame1.type());
roi.setTo(Scalar::all(0));
Mat fram=frame1(bound);
fram.copyTo(roi(Rect(1,1,(bound.height-1),(bound.width-1))));
hog.detectMultiScale(roi,found,0,Size(8,8),Size(32,32),1.025);
roi.release();
fram.release();
}
else
{
Mat roi;
roi=frame1;
hog.detectMultiScale(roi,found,0,Size(8,8),Size(32,32),1.025);
roi.release();
}
for(unsigned int i=0;i<found.size();i++)
{
rectangle(frame1,found[i], Scalar(255,0,0), 2);
}
if(found.size())
{
frame1.release();
found.clear();
return 1;
}
else
return 0;
}
在我使用裁剪方法之前,效果很好。即,当我将框架传递给 'humandet' 函数而不做任何更改并按原样处理时,没有问题。但是速度很慢。这样我就裁剪了图像并使分辨率保持不变并进行了处理。由于这个原因,处理速度增加到相当大的数量。但它经常抛出异常。我认为问题出在内存分配上。但是我想不通。
给我一个解决方案和方法来调试我犯的错误。
提前致谢。
开始调试的理想方式是捕获异常并打印堆栈跟踪。
请参阅此 post 了解如何生成堆栈跟踪 How to generate a stacktrace when my gcc C++ app crashes
这将查明产生异常的位置
在 try-catch 块中调用 detectMultiScale。这个 try-catch 块解决了我的问题。
try{
hog.detectMultiScale(roi,found,0,Size(8,8),Size(32,32),1.025);
}
catch(cv::Exception & e){
return false;
}
我也在尝试用 HogDescriptor 检测人。当我调试我的代码时,我意识到只有当裁剪后的图像尺寸很小时才会出现此错误。它与训练数据大小有关。也许这对你有用:HOG detector: relation between detected roi size and training sample size
我在一个项目中工作,我必须在其中检测人的运动。首先,我编写了一个用于运动检测的程序并使其正常工作。然后我使用 HOGDescriptor
转向人体检测,并将这两个程序结合起来以提高处理速度。首先我监视一个运动,如果检测到任何运动,然后我通过表示运动的矩形框裁剪图像,并将裁剪的部分单独发送到人体检测功能,以便快速处理。
但是出现了一个问题。有时我得到了很好的结果,有时我得到一个弹出窗口 window 说 .exe 文件中的某些内存位置出现未处理的异常 。
我的程序是
#include <iostream>
#include <ctime>
#include<stdlib.h>
#include<vector>
#include"opencv2\opencv.hpp"
#include"opencv2\highgui\highgui.hpp"
#include"opencv2\core\core.hpp"
#include"opencv2\imgproc\imgproc.hpp"
#include<string>
#include<sstream>
using namespace std;
using namespace cv;
Mat detect1(int,VideoCapture,VideoWriter);
vector<Rect> found;
int humandet(Mat,Rect);
BackgroundSubtractorMOG2 bg[5];
int _tmain(int argc, _TCHAR* argv[])
{
Mat frame[5];
string win[5]={"Video 0","Video 1","Video 2","Video 3"};
string ip,user,pass;
stringstream ss;
string vid[5]={"D:/Recorded.avi","D:/Recorded1.avi","D:/Recorded2.avi","D:/Recorded3.avi"};
VideoWriter vidarr[5];
VideoCapture cap[5];
int n,type,j;
cout<<"Enter the no of cameras";
cin>>n;
for(int i=0,j=0;i<n;i++)
{
cout<<"Enter the camera type\n1.IP camera\n2.Non IP camera";
cin>>type;
if(type==2)
{
VideoCapture cap1(j++);
cap[i]=cap1;
cap[i].set(CV_CAP_PROP_FRAME_WIDTH,320);
cap[i].set(CV_CAP_PROP_FRAME_HEIGHT,240);
cap[i].set(CV_CAP_PROP_FPS,2);
}
else
{
cout<<"Enter the IP add:portno, username and password";
cin>>ip>>user>>pass;
ss<<"http://"<<user<<":"<<pass<<"@"<<ip<<"/axis-cgi/mjpg/video.cgi?.mjpg";
string s(ss.str());
VideoCapture cap2(s);
cap[i]=cap2;
cap[i].set(CV_CAP_PROP_FRAME_WIDTH,320);
cap[i].set(CV_CAP_PROP_FRAME_HEIGHT,240);
cap[i].set(CV_CAP_PROP_FPS,2);
}
VideoWriter video(vid[i],CV_FOURCC('D','I','V','X'),2,Size(320,240));
vidarr[i]=video;
}
while(9)
{
for(int i=0;i<n;i++)
{
frame[i]=detect1(i,cap[i],vidarr[i]);
imshow(win[i],frame[i]);
}
if(waitKey(30)==27)
break;
}
return 0;
}
Mat detect1(int j,VideoCapture cap,VideoWriter vid)
{
Mat frame;
Mat diff;
cap>>frame;
double large_area=0;
int large=0;
Rect bound_rect;
bg[j].nmixtures=3;
bg[j].bShadowDetection=true;
bg[j].nShadowDetection=0;
bg[j].fTau = 0.5;
bg[j].operator() (frame,diff);
vector<vector<Point>> contour;
findContours(diff,contour,CV_RETR_EXTERNAL,CV_CHAIN_APPROX_SIMPLE);
for(unsigned int i=0;i<contour.size();i++)
{
double area=contourArea(contour[i]);
if(area>large_area)
{
large_area=area;
large=i;
bound_rect=boundingRect(contour[i]);
}
}
contour.clear();
if(large_area/100 > 2)
{
humandet(frame,bound_rect);
rectangle(frame,bound_rect,Scalar(0,0,255),2);
putText(frame,"Recording",Point(20,20),CV_FONT_HERSHEY_PLAIN,2,Scalar(0,255,0),2);
vid.write(frame);
return (frame);
}
else
return (frame);
}
int humandet(Mat frame1,Rect bound)
{
HOGDescriptor hog;
hog.setSVMDetector(HOGDescriptor::getDefaultPeopleDetector());
if((bound.height < 100) && (bound.width < 80))
{
Mat roi;
roi.create(Size(80,100),frame1.type());
roi.setTo(Scalar::all(0));
Mat fram=frame1(bound);
fram.copyTo(roi(Rect(0,0,(bound.height-1),(bound.width-1))));
hog.detectMultiScale(roi,found,0,Size(8,8),Size(32,32),1.025);
roi.release();
fram.release();
}
else if((bound.height < 200) && (bound.width < 160))
{
Mat roi;
roi.create(Size(160,200),frame1.type());
roi.setTo(Scalar::all(0));
Mat fram=frame1(bound);
fram.copyTo(roi(Rect(1,1,(bound.height-1),(bound.width-1))));
hog.detectMultiScale(roi,found,0,Size(8,8),Size(32,32),1.025);
roi.release();
fram.release();
}
else
{
Mat roi;
roi=frame1;
hog.detectMultiScale(roi,found,0,Size(8,8),Size(32,32),1.025);
roi.release();
}
for(unsigned int i=0;i<found.size();i++)
{
rectangle(frame1,found[i], Scalar(255,0,0), 2);
}
if(found.size())
{
frame1.release();
found.clear();
return 1;
}
else
return 0;
}
在我使用裁剪方法之前,效果很好。即,当我将框架传递给 'humandet' 函数而不做任何更改并按原样处理时,没有问题。但是速度很慢。这样我就裁剪了图像并使分辨率保持不变并进行了处理。由于这个原因,处理速度增加到相当大的数量。但它经常抛出异常。我认为问题出在内存分配上。但是我想不通。
给我一个解决方案和方法来调试我犯的错误。 提前致谢。
开始调试的理想方式是捕获异常并打印堆栈跟踪。 请参阅此 post 了解如何生成堆栈跟踪 How to generate a stacktrace when my gcc C++ app crashes
这将查明产生异常的位置
在 try-catch 块中调用 detectMultiScale。这个 try-catch 块解决了我的问题。
try{
hog.detectMultiScale(roi,found,0,Size(8,8),Size(32,32),1.025);
}
catch(cv::Exception & e){
return false;
}
我也在尝试用 HogDescriptor 检测人。当我调试我的代码时,我意识到只有当裁剪后的图像尺寸很小时才会出现此错误。它与训练数据大小有关。也许这对你有用:HOG detector: relation between detected roi size and training sample size