我从http://smsoftdev-solutions.blogspot.com/2009/08/integral-histogram-for-fast-calculation.html中提取了我正在处理的这段代码。
目前,我正在将该页面上的代码移植到opencv2 c++实现中,这就是到目前为止。
主要
using namespace cv;
using namespace std;
//CONSTANTES
#define PI 3.142
//FUNCIONES
vector<Mat> extractIntegralHist(Mat in, const int _nbins);
int main(int argc, char *argv[])
{
//Definicion de variables
Mat frame;
vector<Mat> integrals(9);
namedWindow("main_video",WINDOW_AUTOSIZE);
namedWindow("temporal_window",WINDOW_AUTOSIZE);
//Inicializa la captura del video
VideoCapture cap(0);
if(!cap.isOpened()){
return -1;
cout << "No se puede capturar";
}
//Loop principal
while(1){
cap >> frame;
imshow("main_video",frame);
waitKey(1);
extractIntegralHist(frame, 9);
}
integrals.clear();
}
功能
//CALCULAR HISTOGRAMAS DE INTEGRALES
vector<Mat> extractIntegralHist(Mat in, const int _nbins){
Mat in_gray;
int x,y;
float temp_gradient,temp_magnitude;
namedWindow("temporal_window",WINDOW_AUTOSIZE);
//Convierte la imagen a escala de grises y normaliza
cvtColor(in,in_gray,CV_RGB2GRAY);
equalizeHist(in_gray,in_gray);
//Calcula la derivada de la imagen en gris en direccion x,y utilizando sobel
Mat xsobel, ysobel;
Sobel(in_gray, xsobel, CV_32FC1, 1, 0, 1);
Sobel(in_gray, ysobel, CV_32FC1, 0, 1, 1);
in_gray.release();
//Crea la matriz de 9 imagenes contenedoras -- REVISAR ESTE CODIGO
vector<Mat> bins(_nbins);
for (int i = 0; i < _nbins ; i++) {
bins[9] = Mat::zeros(in.size(),CV_32F);
}
//Crea la matriz donde se guardaran las integrales de la imagen
vector<Mat> integrals(_nbins);
for (int i = 0; i < _nbins ; i++) {
integrals[9] = Mat(Size(in_gray.cols+1,in_gray.rows+1),CV_64F);
}
//Calcula los contenedores
for(y=0;y<in.rows;y++){
float* xSobelPtr = (float*) (xsobel.row(y).data);
float* ySobelPtr = (float*) (ysobel.row(y).data);
float** binsRowPtrs = new float *[_nbins];
for (int i = 0; i < _nbins; i++){
binsRowPtrs[i] = (float*) (bins[i].row(y).data);
}
//Para cada pixel en la fila los valores de magnitud y orientacion son calculados
for(x=0;x<in.cols;x++){
if(xSobelPtr==0){
temp_gradient = ((atan(ySobelPtr[x]/(xSobelPtr[x]+0.00001)))*(180/PI)+90);
}
else{
temp_gradient = ((atan(ySobelPtr[x]/xSobelPtr[x]))+(180/PI)+90);
}
temp_magnitude = sqrt((xSobelPtr[x] * xSobelPtr[x]) + (ySobelPtr[x] * ySobelPtr[x]));
float binStep = 180/ /*_nbins*/9;
for (int i=1 ; i<=/*_nbins*/9 ; i++){
if (temp_gradient <= binStep*i){
binsRowPtrs[i-1][x] = temp_magnitude;
break;
}
}
}
}
for (int i = 0; i<_nbins;i++){
integral(bins[i],integrals[i]);
}
for (int i = 0; i <_nbins ; i++){
bins[i].release();
}
return integrals;
}
该程序可以编译,但是当我运行它时,它只是停止了,调试器向我显示了SIGSEV错误,并显示了61和38行。
38-extractIntegralHist(frame,9);
61-bins [9] = Mat::zeros(in.size(),CV_32F);
我无法查明问题,因为一切对我来说似乎还不错,请您看看代码吗?
编辑。更新。当运行函数extractIntegralHist时,似乎出现程序停止,据称在(函数的)第61行。现在,我知道这是一个内存处理异常,但是我只是找不到它出了什么问题,而且我不明白调试器在告诉我什么。
谢谢。
最佳答案
线
bins[9] = Mat::zeros(in.size(),CV_32F);
正在尝试访问
bins
的第十个元素(请注意零索引)。由于_nbins
传入的值为9
,因此它超出了 vector 的边界。另外,如果您使用.at()
而不是使用[]
访问元素,则这种错误将引发out_of_range
异常,这将在诊断问题时更有用。要将 vector 的每个元素分配给包含零的
cv::Mat
,请考虑将循环更改为for (int i = 0; i < _nbins ; i++) {
bins[i] = Mat::zeros(in.size(),CV_32F);
}
或更简洁地说,删除循环并将
bins
初始化替换为vector<Mat> bins(_nbins, Mat::zeros(in.size(),CV_32F));
请注意,在初始化
integrals
时遇到相同的问题。关于opencv - opencv2 HOG代码中的运行时错误SIGSEV,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/13125365/