首页 文章

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

提问于
浏览
0

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

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 stopped working" .

如果我提交这一行,一切都按预期进行 . 所以我猜测存在某种堆栈损坏,但我不太了解为什么......

注意:该函数尚未全部实现,我只是不确定为什么会抛出此错误 .

关键点来自opencv sift和orientation是一个具有渐变方向的图像 . 我正在使用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;
}

希望有人能帮助我!

最好的祝福 .

EDIT 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;
}

EDIT 2

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

我的问题是,为什么这个变量搞乱了内存分配,而其他像newOrientation,X_sq,Y_sq没有造成任何麻烦?

1 回答

  • 0

    解决了,谢谢所有帮助过的人 . 基本上并非所有divideInterval函数的路径都返回一个值,因此在释放内存时会抛出异常 . 这是我经过的一个愚蠢的实现错误 .

    我仍然不知道为什么有时会抛出错误 .

相关问题