leggiero-crescendo / Dev-perception

자율주행데브코스 인지과정 5기 기록
1 stars 0 forks source link

OpenCV with C++ Advanced #5

Open leggiero-crescendo opened 1 year ago

leggiero-crescendo commented 1 year ago

OpenCV keypoint detector

int main()
{
    cv::ocl::setUseOpenCL(false); // for ORB time check

    cv::Mat src = imread("lenna.bmp", cv::IMREAD_GRAYSCALE);

    if (src.empty()) {
        std::cerr << "Image load failed!" << std::endl;
        return -1;
    }

    cv::TickMeter tm; // time check -> t
    tm.start(); // t

    cv::Ptr<cv::Feature2D> detector = cv::SIFT::create(); // SIFT, KAZE, AKAZE, ORB

    std::vector<cv::KeyPoint> keypoints;
    detector->detect(src, keypoints);

    tm.stop(); // t
    std::cout << "Elapsed time: " << tm.getTimeMilli() << "ms." << std::endl;
    std::cout << "keypoints.size(): " << keypoints.size() << std::endl;

    cv::Mat dst;
    cv::drawKeypoints(src, keypoints, dst, cv::Scalar::all(-1), cv::DrawMatchesFlags::DRAW_RICH_KEYPOINTS);

    cv::imshow("dst", dst);
    cv::waitKey();
}

OpenCV keypoint descriptor

int main()
{
    cv::ocl::setUseOpenCL(false); // To set  opencl initialization to take place only once

    cv::Mat src = imread("lenna.bmp", cv::IMREAD_GRAYSCALE);

    if (src.empty()) {
        std::cerr << "Image load failed!" << std::endl;
        return -1;
    }

    cv::TickMeter tm;
    tm.start();

    cv::Ptr<cv::Feature2D> feature = cv::SIFT::create(); // SIFT, KAZE, AKAZE, ORB

    std::vector<cv::KeyPoint> keypoints;
    cv::Mat desc;
    feature->detectAndCompute(src, cv::Mat(), keypoints, desc);

    tm.stop();
    std::cout << "Elapsed time: " << tm.getTimeMilli() << "ms." << std::endl;
    std::cout << "keypoints.size(): " << keypoints.size() << std::endl;
    std::cout << "desc.size(): " << desc.size() << std::endl; // descriptor size : [ cols x rows ]

    cv::Mat dst;
    drawKeypoints(src, keypoints, dst, cv::Scalar::all(-1), cv::DrawMatchesFlags::DRAW_RICH_KEYPOINTS);

    imshow("dst", dst);
    cv::waitKey();
}

OpenCV keypoint matching

void keypoint_matching()
{
    Mat src1 = imread(file1, IMREAD_GRAYSCALE);
    Mat src2 = imread(file2, IMREAD_GRAYSCALE);

    if (src1.empty() || src2.empty()) {
        cerr << "Image load failed!" << endl;
        return;
    }

    vector<KeyPoint> keypoints1, keypoints2;
    Mat desc1, desc2;
    feature->detectAndCompute(src1, Mat(), keypoints1, desc1);
    feature->detectAndCompute(src2, Mat(), keypoints2, desc2);

    Ptr<DescriptorMatcher> matcher = BFMatcher::create();
//  Ptr<DescriptorMatcher> matcher = BFMatcher::create(NORM_HAMMING); // for binary descriptors

        // 매칭 정보 생성 
    vector<DMatch> matches; 
    matcher->match(desc1, desc2, matches);

    Mat dst;
    drawMatches(src1, keypoints1, src2, keypoints2, matches, dst);

    imshow("dst", dst);
    waitKey();
    destroyAllWindows();
}

good matching 1

vector matches; matcher->match(desc1, desc2, matches);

std::sort(mathces.begin(), mathces.end()); vector good_matches(matches.begin(), matches.begin() + 80);

# good matching 2
- knnMatch() 함수를 사용하여 두개의 매칭 결과를 반환하고
- 1번(가장 매칭이 잘 된 것) , 2번(두번째로 매칭이 잘 된 것)의 비율이 작을 수록 좋은 결과라고 반환
```cpp
/* 특징점 검출 및 기술 */

vector<vector<DMatch>> matches;
matcher->knnMatch(desc1, desc2, matches, 2);

vector<DMatch> good_mathces;
for (auto& m : matches){
    if (m[0].distance / m[1].distance < 0.7)
        good_matches.push_back(m[0]);
}

Good matching


void good_matching()
{
    Mat src1 = imread(file1, IMREAD_GRAYSCALE);
    Mat src2 = imread(file2, IMREAD_GRAYSCALE);

    if (src1.empty() || src2.empty()) {
        cerr << "Image load failed!" << endl;
        return;
    }

    vector<KeyPoint> keypoints1, keypoints2;
    Mat desc1, desc2;
    feature->detectAndCompute(src1, Mat(), keypoints1, desc1);
    feature->detectAndCompute(src2, Mat(), keypoints2, desc2);

    Ptr<DescriptorMatcher> matcher = BFMatcher::create();

#if 1
    vector<DMatch> matches;
    matcher->match(desc1, desc2, matches);

    std::sort(matches.begin(), matches.end());
    vector<DMatch> good_matches(matches.begin(), matches.begin() + 80);
#else
    vector<vector<DMatch>> matches;
    matcher->knnMatch(desc1, desc2, matches, 2);

    vector<DMatch> good_matches;
    for (const auto& m : matches) {
        if (m[0].distance / m[1].distance < 0.7)
            good_matches.push_back(m[0]);
    }
#endif

    Mat dst;
    drawMatches(src1, keypoints1, src2, keypoints2, good_matches, dst,
                Scalar::all(-1), Scalar::all(-1), vector<char>(),
                DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS);

    imshow("dst", dst);
    waitKey();
    destroyAllWindows();
}