OpenCV C++:声明一个新变量会导致堆栈损坏

OpenCV C++: declaring a new variable leads to stack corruption

本文关键字:损坏 变量 堆栈 一个 C++ 声明 OpenCV 新变量      更新时间:2023-10-16

过去两天我一直在查看这段代码,不知道发生了什么。

void filterKeypoints(std::vector<KeyPoint> &keypoints, Mat orientation){
unsigned int rows = orientation.rows;
unsigned int cols = orientation.cols;
unsigned int N = keypoints.size();
Mat newOrientation;
vector<KeyPoint> newKeyPoints;
// Function do create n points in a interval equally spaced
vector<float> t = divideInterval(-3.14159265, 3.14159265, 6);
for (unsigned int i = 0; i < N; i++){
Mat x_c, y_c;
getKeyPoint(keypoints[i], x_c, y_c);
float radius_sq = (72 * pow(keypoints[i].size, 2));
float radius = 6 * sqrt(2)*keypoints[i].size;
float x_min = round(keypoints[i].pt.x - radius);
float x_max = round(keypoints[i].pt.x + radius);
float y_min = round(keypoints[i].pt.y - radius);
float y_max = round(keypoints[i].pt.y + radius);
cout << i << " of " << N << endl;
if ((x_min >= 0) && (x_max < cols) && (y_min >= 0) && (y_max < rows)){
Mat X, Y;
meshGrid(X, Y, x_min, x_max, y_min, y_max);
X = X.reshape(0, 1); // row vector
Y = Y.reshape(0, 1);
int nr = y_max - y_min + 1;
int nc = x_max - x_min + 1;
Mat D_array = Mat::zeros(128, 1, CV_32FC1);
float radius_sq_small = radius_sq / 16;
//////////// HERE STOPED IMPLEMENTATION
for (unsigned int j = 0; j < 16; j++){
Mat X_sq, Y_sq;
cv::pow(X - (float) x_c.at<float>(j), 2, X_sq);
cv::pow(Y - (float) y_c.at<float>(j), 2, Y_sq);
Mat Distance_Square = X_sq + Y_sq;
Mat If = Mat::zeros(rows, cols, CV_8UC1);
Mat Binary;
//cv::compare(Distance_Square, radius_sq_small, Binary, CMP_LE);
//Mat Binary = Distance_Square <= radius_sq_small;
//Binary = Binary.reshape(0, nr);
//Mat roi_img(If(cvRect(x_min, y_min, nc, nr)));
//Binary.copyTo(roi_img);

}
}
}
cout << "Everything run well." << endl;
}

如果创建Mat Binary的行被取消注释,则程序将中断并出现未处理的异常:它运行for循环,进入cout,并且没有退出void函数,从而启动错误:".exe停止工作"。

如果我同意这条线,一切都会如预期的那样进行。所以我猜测存在某种堆栈损坏,但我不太明白为什么。。。

注意:函数还没有全部实现,我只是不确定为什么会抛出这个错误。

关键点来自opencv-sift,方向是具有梯度方向的图像。我正在使用opencv 3.1

调用它的原始函数是:

void getImageDescriptors(Mat image, Mat orientation){
cv::Ptr<Feature2D> f2d = xfeatures2d::SIFT::create();
std::vector<KeyPoint> keypoints;
f2d->detect(image, keypoints);
Mat descriptors;
f2d->compute(image, keypoints, descriptors);
adjustAngle(keypoints);
filterKeypoints(keypoints, orientation);
cout << "Got here Correctly" << endl;
}

希望有人能帮助我!

谨致问候。

编辑1:

下面是getKeyPoint函数,它将一些表达式相应地应用于我要实现的文章。它从不返回错误,所以我不认为它来自这里。

void getKeyPoint(KeyPoint keypoint, Mat &x_c, Mat &y_c){
float xc_array[16] = { -1.5, -0.5, 0.5, 1.5, -1.5, -0.5, 0.5, 1.5, -1.5, -0.5, 0.5, 1.5, -1.5, -0.5, 0.5, 1.5 };
x_c = Mat(1, 16, CV_32FC1, &xc_array).clone();
float yc_array[16] = { -1.5, -1.5, -1.5, -1.5, -0.5, -0.5, -0.5, -0.5, 0.5, 0.5, 0.5, 0.5, 1.5, 1.5, 1.5, 1.5 };
y_c = Mat(1, 16, CV_32FC1, &yc_array).clone();
float SBP = 3 * keypoint.size;
float c = cos(keypoint.angle * 3.14159265 / 180);  // Convert to radians
float s = sin(keypoint.angle * 3.14159265 / 180);
x_c = SBP*(c*x_c - s*y_c) + keypoint.pt.x; // See this in future
y_c = SBP*(s*x_c + c*y_c) + keypoint.pt.y;
}

编辑2

通过用Mat Binary = Mat::zeros(Distance_Square.rows, Distance_Square.cols, CV_8UC1);替换Mat Binary;,错误消失了(创建一个零矩阵,而不仅仅是默认初始化)。

我的问题是,为什么这个变量扰乱了内存分配,而其他变量,如newOrientation、X_sq、Y_sq,却没有引起任何麻烦?

解决了,感谢所有提供帮助的人。基本上并不是divideInterval函数的所有路径都返回一个值,所以当释放内存时,它抛出了一个异常。我忽略了一个愚蠢的实现错误

不过,我不知道为什么错误只是偶尔出现。