基于openCV的多视角图像特征点检测、匹配与变换

代码实现了以下功能:
1、基于openCV的特征点检测和匹配(feature_match()函数)
2、获取手机照片信息,通过EXIFreader()函数读取照片焦距等信息
3、根据匹配特征点求解Homography单应矩阵,并对两个视角图像进行变换。(TransFormEstimate()函数)

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

using namespace std;
using namespace easyexif;

//store key points and match results
vector<vector<cv::KeyPoint>> MyKeyPoint(2);
vector<cv::Mat> FastDescriptor(2);
vector<cv::DMatch> matches;

//************************基于openCV的特征点检测和匹配*****************
void feature_match(string image1, string image2){

    vector<cv::Mat> img(2);
    img[0] = cv::imread(image1, 0);
    img[1] = cv::imread(image2, 0);

    //Do SIFT
    cv::Ptr<cv::SIFT> SIFTDetec = cv::SIFT::create(300,3,0.10,10,1.6);
    SIFTDetec->detectAndCompute(img[0],cv::noArray(), MyKeyPoint[0], FastDescriptor[0]);
    SIFTDetec->detectAndCompute(img[1],cv::noArray(), MyKeyPoint[1], FastDescriptor[1]);
    // cv::Mat image_show;
    // cv::drawKeypoints(img[0], MyKeyPoint[0], image_show, 0,0);
    // cv::namedWindow("plot point",CV_WINDOW_NORMAL);
    // cv::imshow("plot point",image_show);
    // cv::waitKey(0);

    //Do Matching
    cv::BFMatcher matchMatrain;
    matchMatrain.match(FastDescriptor[0], FastDescriptor[1], matches);
    // cv::Mat visualizeImg;
    // cv::drawMatches(img[0], MyKeyPoint[0],
    //                 img[1], MyKeyPoint[1],
    //                 matches,
    //                 visualizeImg,
    //                 cv::Scalar(0,128,128));
    // cv::namedWindow("Matche Result",CV_WINDOW_NORMAL);
    // cv::imshow("Matche Result", visualizeImg);
    // cv::waitKey(0);
}

//************获取手机照片信息,通过EXIFreader()函数读取照片焦距等信息********
double EXIFreader(string *path){
    const char *photoPath = path->c_str();
    // Read the JPEG file into a buffer
    FILE *fp = fopen(photoPath, "rb");
    if (!fp) {
        printf("Can't open file.\n");
        exit(0);
    }
    fseek(fp, 0, SEEK_END);
    unsigned long fsize = ftell(fp);
    rewind(fp);
    unsigned char *buf = new unsigned char[fsize];
    if (fread(buf, 1, fsize, fp) != fsize) {
        printf("Can't read file.\n");
        delete[] buf;
        exit(0);
    }
    fclose(fp);

    // Parse EXIF
    EXIFInfo result;
    int code = result.parseFrom(buf, fsize);
    delete[] buf;
    if (code) {
        printf("Error parsing EXIF: code %d\n", code);
        exit(0);
    }

    return result.FocalLength;
}


//*******根据匹配特征点求解Homography单应矩阵,并对两个视角图像进行变换***********
void TransFormEstimate(string img1, string img2){

    double Focal[2];
    Focal[0] = EXIFreader(&img1);
    Focal[1] = EXIFreader(&img2);
    feature_match(img1, img2);
    vector<cv::Point2f> p1_pair, p2_pair;
    for(int i=0; i<matches.size(); i++){
        p1_pair.push_back(MyKeyPoint[0][matches[i].queryIdx].pt);
        p2_pair.push_back(MyKeyPoint[1][matches[i].trainIdx].pt);
    }
    cv::Mat H = cv::findHomography(p1_pair, p2_pair, CV_RANSAC);
    
    vector<cv::Mat> img(2);
    img[0] = cv::imread(img1, 0);
    img[1] = cv::imread(img2, 0);
    cv::Mat im_transform;
    cv::warpPerspective(img[0], im_transform, H, img[1].size());
    cv::namedWindow("Raw",CV_WINDOW_NORMAL);
    cv::imshow("Raw", img[0]);
    cv::namedWindow("Target",CV_WINDOW_NORMAL);
    cv::imshow("Target", img[1]);
    cv::namedWindow("Transform",CV_WINDOW_NORMAL);
    cv::imshow("Transform", im_transform);
    cv::waitKey(0);

}


int main(){
    string ImagePath = "/home/linux1/MyCode/3D_reconstruction/Data/";
    vector<string> src_name;
    string img1 = "3.jpg";
    string img2 = "4.jpg";
    src_name = {ImagePath+img1, ImagePath+img2};
    TransFormEstimate(src_name[0], src_name[1]);
    return 0;
}

你可能感兴趣的:(点云三维场景重建,opencv,计算机视觉,图像处理)