1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 | #include "stitching.h" int main() { cv::VideoCapture cap0(1); cv::VideoCapture cap1(3); cv::VideoCapture cap2(0); cv::VideoCapture cap3(2); // cv::VideoCapture cap0(0), cap1(1), cap2(2), cap3(3); if (!(cap0.isOpened()) || !(cap1.isOpened()) || !(cap2.isOpened()) || !(cap3.isOpened())) { std::cerr << "Camera open failed !!!" << std::endl; return -1; } std::cout << std::endl << "camera loading ..." << std::endl << std::endl; cv::Mat frame0, frame1, frame2, frame3; cv::Mat stitch_up, stitch_down, stitch_dst; My_Stitching stitcher0, stitcher1, stitcher2; while (true) { cap0 >> frame0; if (frame0.empty()) { std::cerr << "frame0 not load ..." << std::endl; break; } cap1 >> frame1; if (frame1.empty()) { std::cerr << "frame1 not load ..." << std::endl; break; } cap2 >> frame2; if (frame2.empty()) { std::cerr << "frame2 not load ..." << std::endl; break; } cap3 >> frame3; if (frame3.empty()) { std::cerr << "frame3 not load ..." << std::endl; break; } stitch_up = stitcher0.stitch(frame0, frame1, "width"); stitch_down = stitcher1.stitch(frame2, frame3, "width"); stitch_dst = stitcher2.stitch(stitch_up, stitch_down, "height"); cv::imshow("frame0", frame0); cv::imshow("frame1", frame1); cv::imshow("frame2", frame2); cv::imshow("frame3", frame3); cv::imshow("stitch_up", stitch_up); cv::imshow("stitch_down", stitch_down); cv::imshow("stitch_dst", stitch_dst); int key = cv::waitKey(1); if (key == 'q') break; else if (key == 's') { stitcher0.homography = cv::Mat(); stitcher1.homography = cv::Mat(); stitcher2.homography = cv::Mat(); } } std::cout << "프로그램 종료..." << std::endl << std::endl; cv::destroyAllWindows(); return 0; } | cs |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 | #include "stitching.h" std::tuple<std::vector<cv::KeyPoint>, cv::Mat> My_Stitching::detect_and_describe(cv::Mat image) { cv::Mat image_gray; cv::cvtColor(image, image_gray, cv::COLOR_BGR2GRAY); cv::Ptr<cv::Feature2D> sift_feature = cv::SIFT::create(); std::vector<cv::KeyPoint> keypoints; cv::Mat descriptors; sift_feature->detectAndCompute(image_gray, cv::Mat(), keypoints, descriptors); return std::make_tuple(keypoints, descriptors); } cv::Mat My_Stitching::match_keypoints(cv::Mat imageA, cv::Mat imageB, std::vector<cv::KeyPoint> keypointA, std::vector<cv::KeyPoint> keypointB, cv::Mat featuresA, cv::Mat featuresB, float ratio, double repojThresh) { std::vector<std::vector<cv::DMatch>> rawMatches; std::vector<cv::DMatch> goodMatches; std::vector<cv::Point2f> pointsA, pointsB; cv::Ptr<cv::DescriptorMatcher> matcher = cv::DescriptorMatcher::create("BruteForce"); matcher->knnMatch(featuresA, featuresB, rawMatches, 2); for (int i = 0; i < rawMatches.size(); i++) { if ((rawMatches[i].size() == 2) && (rawMatches[i][0].distance < (rawMatches[i][1].distance * ratio))) { goodMatches.push_back(rawMatches[i][0]); } } if (goodMatches.size() > 4) { for (int i = 0; i < goodMatches.size(); i++) { pointsA.push_back(keypointA[goodMatches[i].queryIdx].pt); pointsB.push_back(keypointB[goodMatches[i].trainIdx].pt); } homography = findHomography(pointsB, pointsA, cv::RANSAC); return homography; } } cv::Mat My_Stitching::stitch(cv::Mat imageA, cv::Mat imageB, std::string mode, float ratio, double repojThresh) { std::vector<cv::KeyPoint> keypointA, keypointB; cv::Mat featuresA, featuresB; cv::Mat matchFeatures, matches; std::vector<cv::DMatch> goodMatches; cv::Mat warp_image, dst; if (homography.empty()) { std::tie(keypointA, featuresA) = detect_and_describe(imageA); std::tie(keypointB, featuresB) = detect_and_describe(imageB); homography = match_keypoints(imageA, imageB, keypointA, keypointB, featuresA, featuresB, ratio, repojThresh); std::cout << "homography matrix : " << std::endl << homography << std::endl << std::endl; } if (mode == "width") { cv::warpPerspective(imageB, warp_image, homography, cv::Size(imageA.cols * 2, imageA.rows)); dst = warp_image.clone(); cv::Mat roi(dst, cv::Rect(0, 0, imageA.cols, imageA.rows)); imageA.copyTo(roi); } else if (mode=="height") { cv::warpPerspective(imageB, warp_image, homography, cv::Size(imageA.cols, imageA.rows * 2)); dst = warp_image.clone(); cv::Mat roi(dst, cv::Rect(0, 0, imageA.cols, imageA.rows)); imageA.copyTo(roi); } return dst; } | cs |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | #ifndef __STITCHING__ #define __STITCHING__ #include <opencv2/opencv.hpp> #include <iostream> #include <string> #include <tuple> class My_Stitching { public: cv::Mat homography; std::tuple<std::vector<cv::KeyPoint>, cv::Mat> detect_and_describe(cv::Mat image); cv::Mat match_keypoints(cv::Mat imageA, cv::Mat imageB, std::vector<cv::KeyPoint> keypointA, std::vector<cv::KeyPoint> keypointB, cv::Mat featuresA, cv::Mat featuresB, float ratio, double repojThresh); cv::Mat stitch(cv::Mat imageA, cv::Mat imageB, std::string mode, float ratio = 0.75, double repojThresh = 4.0); }; #endif | cs |
다음검색