首页 > 解决方案 > OpenCV 特征匹配并行处理

问题描述

我匹配的图像具有以下属性:正确匹配的关键点对应该具有相同(或非常接近)的 y 坐标值。 有点像这样

以加快程序并提高准确性。我将两个图像切成 12 个水平条纹,然后进行特征匹配。

目标是获取关键点信息(坐标)。

它看起来像这样:

void featureMatching(Mat &img1, Mat &img2, vector<KeyPoint> &keypoints_1,
                 vector<KeyPoint> &keypoints_2) {
    // store the matched keypoint pairs into keypoints_1 and keypoints_2.
}

void feature_blocks(Mat &img_l, Mat &img_r, vector<KeyPoint> &keypoints_l,
                 vector<KeyPoint> &keypoints_r, int num_block) {
    Mat block_l, block_r;
    Mat temp_block;
    vector<Mat> mat_blocks;
    vector<KeyPoint> temp_keypoints_l, temp_keypoints_r;
    Mat concated_block;

    int block_width, bloch_height;
    block_width = img_l.cols;
    block_height = int(img_l.rows / num_block);

    for (int i = 0, coor_y = 0; i < num_block; i++, coor_y += block_height) {
        if (i == num_block - 1)
            block_height += img_l.rows % num_block;
        block_l = img_l(Rect(0, coor_y, block_width, bloch_height));
        block_r = img_r(Rect(0, coor_y, block_width, bloch_height));
        if (DEBUG) {
            cout << "----- block " << i << " ----- " << endl;
        }
        temp_keypoints_l.clear();
        temp_keypoints_r.clear();
        featureMatching(block_l, block_r, temp_keypoints_l, temp_keypoints_r);
        keypoints_l.insert(end(keypoints_l), begin(temp_keypoints_l),
                           end(temp_keypoints_l));
        keypoints_r.insert(end(keypoints_r), begin(temp_keypoints_r),
                           end(temp_keypoints_r));
    }
}

int main() {
    ...
    img1 = imread("test1.jpg", IMREAD_COLOR);
    img2 = imread("test2.jpg", IMREAD_COLOR);
    vector<KeyPoint> keypoint1, keypoint2;
    feature_blocks(img1, img2, keypoint1, keypoint2, 12);

}

只要 keypoint1[i] 对应 keypoint2[i],keypoint1 和 keypoint2 中的关键点顺序无关紧要。有没有一种简单的方法可以并行化 feature_blocks 中的 for 循环?

我阅读了 OpenCV 文档中的教程,但我只是不知道如何实现它。也就是说,我不知道如何让每个线程处理一个图像块。

编辑

我在 Warpstar22 的推荐下使用 OpenMP。有用!

    #pragma omp parallel for
    for (int i = 0; i < num_block; i++) {
        int block_height = int(img_l.rows / num_block);
        int coor_y = block_height * i;

        if (i == num_block - 1)
            block_height += img_l.rows % num_block;

        Mat block_l, block_r;
        block_l = img_l(Rect(0, coor_y, block_width, block_height));
        block_r = img_r(Rect(0, coor_y, block_width, block_height));
        if (DEBUG) {
            cout << "----- block " << i << " ----- " << endl;
        }

        vector<KeyPoint> temp_keypoints_l, temp_keypoints_r;
        featureMatching(block_l, block_r, temp_keypoints_l, temp_keypoints_r,
                    coor_y);

        #pragma omp critical
        keypoints_l.insert(end(keypoints_l), begin(temp_keypoints_l),
                           end(temp_keypoints_l));
        #pragma omp critical
        keypoints_r.insert(end(keypoints_r), begin(temp_keypoints_r),
                           end(temp_keypoints_r));
    }

标签: c++opencv

解决方案


您可能会更轻松地使用 OpenMP。OpenMP 可以很容易集成。当我制作算法并发现它很慢时,我已经使用了很多。如果您尝试并行化循环,则可以在#pragma omp parallel forfor 循环语句上方添加该行。然后,您必须使用-fopenmp. 这是一个关于 OpenMP 的简单教程的链接。

或者,我想 OpenCV 在运行其特征描述符函数时已经通过并行处理优化了处理。我不确定,但我知道在构建时需要确保启用并行处理支持的标志。此外,如果您也没有,则 parallel_for 函数也不起作用。


推荐阅读