opencv的SIFT样例(CPP/python)

发布时间:2024年01月16日

Python代码的实现:

import cv2
import numpy as np
import time
import os
def main():
    images = os.listdir('./images/')
    pre_image = cv2.imread('./images/1.jpg', 0)
    print("images:",images)

    # 初始化 SIFT 和 SURF
    sift = cv2.xfeatures2d.SIFT_create()
    # surf = cv2.xfeatures2d.SURF_create()
    bf = cv2.BFMatcher()
    start_time = time.time()

    for img in images:
        img2 = cv2.imread(os.path.join('./images', img), 0)

        # 寻找关键点和计算描述符
        kp1, des1 = sift.detectAndCompute(pre_image, None)
        kp2, des2 = sift.detectAndCompute(img2, None)

        ti = time.time()
        # 匹配关键点
        matches = bf.knnMatch(des1, des2, k=2)
        # 应用比值测试来获取好的匹配点
        good = []
        for m, n in matches:
            if m.distance < 0.75 * n.distance:
                good.append([m])

        # 可视化匹配结果
        img3 = cv2.drawMatchesKnn(pre_image, kp1, img2, kp2, good, None, flags=2)
        print("knnMatch spend time:{} second".format(time.time()-ti))

    print("this spend time is :{} second".format(time.time()-start_time))

if __name__ == "__main__":
    main()
  
#include <opencv2/opencv.hpp>
#include <opencv2/xfeatures2d.hpp>
#include <opencv2/xfeatures2d/nonfree.hpp>
#include <iostream>
#include <vector>
#include <ctime>
#include <sys/types.h>
#include <dirent.h>
#include <iostream>
#include <chrono>

void readFilesInDir(const std::string& dir_path, std::vector<std::string>& files)
{
    DIR *dir;
    struct dirent *ent;
    if ((dir = opendir(dir_path.c_str())) != NULL)
    {
        while ((ent = readdir(dir)) != NULL)
        {
            if (ent->d_name[0] != '.')
            {
                files.push_back(ent->d_name);
            }
        }
        closedir(dir);
    }
}
int main()
{
    std::vector<std::string> files;
    readFilesInDir("./images", files);

    cv::Ptr<cv::xfeatures2d::SIFT> sift = cv::xfeatures2d::SIFT::create();
    cv::BFMatcher bf;
    cv::Mat pre_image = cv::imread("./images/1.jpg", 0);
    clock_t start = clock();
    auto _start = std::chrono::high_resolution_clock::now();

    for (const auto& file : files)
    {
        cv::Mat img2 = cv::imread("./images/" + file, 0);

        std::vector<cv::KeyPoint> kp1, kp2;
        cv::Mat des1, des2;

        sift->detectAndCompute(pre_image, cv::noArray(), kp1, des1);
        sift->detectAndCompute(img2, cv::noArray(), kp2, des2);
        std::vector<std::vector<cv::DMatch>> matches;
        auto _t = std::chrono::high_resolution_clock::now();
        bf.knnMatch(des1, des2, matches, 2);
        std::vector<cv::DMatch> goodMatches;

        auto _e = std::chrono::high_resolution_clock::now();
        std::chrono::duration<double, std::milli> _elapsed = _e - _t;

        double _ex = _elapsed.count() / 1000.0;
        std::cout << "step spend time is :" << _ex << " s" << std::endl;


        for (int i = 0; i < matches.size(); ++i)
        {
            if (matches[i][0].distance < 0.75 * matches[i][1].distance)
            {
                goodMatches.push_back(matches[i][0]);
            }
        }
        cv::Mat img3;
        cv::drawMatches(pre_image, kp1, img2, kp2, goodMatches, img3, cv::Scalar::all(-1), cv::Scalar::all(-1), std::vector<char>(), cv::DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS);
    }
    auto end = std::chrono::high_resolution_clock::now();
    std::chrono::duration<double, std::milli> elapsed = end - _start;
    double elapsedSeconds = elapsed.count() / 1000.0;
    std::cout << "this spend time is: " << (double)(clock() - start) / CLOCKS_PER_SEC << " s : " << elapsedSeconds << " seconds" << std::endl;
    return 0;
}

结论说明:
两种代码在同一个环境上的,相同的图片大小和数量(19张图片),运行耗时如下:
python

spend time is : 57.90586733818054 second

c++

spend time is: 57.71 seconds

差距不会很明显,但是如果文件很多,并且使用多线程/多进程,会有一个比较明显的差距。

文章来源:https://blog.csdn.net/weixin_50005386/article/details/135613857
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。