ORB_LK视频贴图

#include<opencv2/opencv.hpp>
#include<iostream>
#include<opencv2/xfeatures2d.hpp>
#include<vector>
using namespace std;
using namespace cv;
using namespace cv::xfeatures2d;

//全局变量
Mat src_img = imread("../Tulips.jpg", 1);
Mat frame,gray,prev_frame,mask;
vector<Point2f> one_frame_point4;//第一张图片四点
vector<Point> next_frame_point4;
Point point_one;
vector<uchar> status;
vector<float> errors;
// sift特征变量
Mat description_one;
Mat description_two;
vector<Point2f> fpts[2];


vector<Point2f> src_points_4;
//获取贴图图片的坐标
void get_img_points()
{

    Size src_size = src_img.size();
    src_points_4.push_back(Point2f(0, 0));
    src_points_4.push_back(Point2f(src_size.width - 1, 0));
    src_points_4.push_back(Point2f(src_size.width - 1, src_size.height - 1));
    src_points_4.push_back(Point2f(0, src_size.height - 1));
}
//鼠标交互获取mask区域和第一张图片特征点
void on_Left_Mouse(int event,int x,int y,int flags,void* param)
{
    Mat& image = *(Mat*)param;
    switch (event)
    {
        case EVENT_LBUTTONDOWN:
        {

            point_one.x = x;
            point_one.y = y;
            one_frame_point4.push_back(point_one);
            circle(image, point_one, 5, Scalar(0, 0, 255), -1, 8);
        }
            break;
        default:
            break;
    }
}

//获取特征点
void detectFeature(Mat &ingray)
{

    Ptr<ORB> orb = ORB::create(150, 1.2f, 8, 31, 0, 2, ORB::HARRIS_SCORE, 31, 20);
    vector<KeyPoint> keyPoint_one;
    orb->detectAndCompute(ingray, mask, keyPoint_one, description_one);
    vector<Point2f> feature_one;
    for (int i = 0; i < keyPoint_one.size(); i++)
    {
        feature_one.push_back(keyPoint_one[i].pt);
    }
    fpts[0] = feature_one;
    cout << "第一张图片特征点个数" << fpts[0].size() << endl;

}

void LKTrackFeature()
{
    //光流追踪
    calcOpticalFlowPyrLK(prev_frame, gray, fpts[0], fpts[1], status, errors);
    //提取sift特征点
    Ptr<ORB> orb = ORB::create(150, 1.2f, 8, 31, 0, 2, ORB::HARRIS_SCORE, 31, 20);
    vector<KeyPoint> keyPoint_two;
    orb->detectAndCompute(gray, mask, keyPoint_two, description_two);
    cout << keyPoint_two.size() << endl;
    vector<DMatch> matches;
    BFMatcher matcher(NORM_HAMMING);
    matcher.match(description_one,description_two,matches);
    cout << description_one.rows << endl;
    double min_dist = 10000, max_dist = 0;
    for (int i = 0; i < description_one.rows; i++)
    {
        double dist = matches[i].distance;
        if (dist < min_dist) { min_dist = dist; }
        if (dist > max_dist) { max_dist = dist; }
    }
    cout << "min:" << min_dist << "\t" << "max:" << max_dist << endl;
    //vector<DMatch> good_match;
    int k = 0;
    for (int j = 0; j < fpts[0].size(); j++)
    {
        //float a = fpts[1][j].x-keyPoint_two[j].pt.x;
        //float b = fpts[1][j].y - keyPoint_two[j].pt.y;
        //cout << "a:" << a << "b:" << b << endl;
        float a = max(2 * min_dist, 10.0);
        if ((matches[j].distance<= a)&&status[j])
        {
            fpts[0][k] = fpts[0][j];
            fpts[1][k++] = fpts[1][j];
            //good_match.push_back(matches[j]);
        }
    }
    fpts[0].resize(k);
    fpts[1].resize(k);
    cout << fpts[0].size() << endl;
    cout << fpts[1].size() << endl;
}
int main()
{
    VideoCapture capture("../41_output.mp4");
    if (!capture.isOpened())
    {
        cout << "could not load video file..." << endl;
        return -1;
    }
    int num_frames = capture.get(CAP_PROP_FRAME_COUNT);
    double num_fps = capture.get(CAP_PROP_FPS);
    Size num_size = Size(capture.get(CAP_PROP_FRAME_WIDTH), capture.get(CAP_PROP_FRAME_HEIGHT));
    cout << "frames:" << num_frames << endl;
    cout << "fps:" << num_fps << endl;
    cout << "size:" << num_size << endl;
    VideoWriter writer;
    writer.open("../sift_LK_test.avi", VideoWriter::fourcc('M', 'J', 'P', 'G'), num_fps, num_size);
    namedWindow("video_input", 0);
    namedWindow("video_output", 0);
    //获取贴图的四个点坐标集合
    get_img_points();
    //读取视频图片进行处理

    int n = 0;
    while (capture.read(frame))
    {
        n++;
        cvtColor(frame, gray, COLOR_BGR2GRAY);
        if (prev_frame.empty())
        {
            gray.copyTo(prev_frame);
        }

        if (n==1)
        {

            Mat frame_one;
            frame.copyTo(frame_one);
            setMouseCallback("video_input",on_Left_Mouse,&frame_one);
            Mat tempImage;
            frame.copyTo(tempImage);
            while (true)
            {
                circle(tempImage,point_one,5,Scalar(0,0,255),-1,8);
                imshow("video_input", tempImage);
                if (waitKey(10) == 27)break;
            }
            mask = Mat::zeros(gray.size(),gray.type());
            vector<Point> points_mask;
            for (int i = 0; i <4 ; ++i) {
                points_mask.push_back(one_frame_point4[i]);

            }
            fillConvexPoly(mask,points_mask,Scalar(255),LINE_AA);
            detectFeature(gray);
            //贴图
            Mat warp_Homo = getPerspectiveTransform(src_points_4, one_frame_point4);
            Mat frame_clone, frame_fill;
            frame.copyTo(frame_clone);
            frame.copyTo(frame_fill);
            warpPerspective(src_img,frame_clone,warp_Homo,frame_clone.size());
            fillConvexPoly(frame_fill,points_mask,Scalar(0,0,0),LINE_AA);
            frame_fill = frame_fill + frame_clone;
            writer << frame_fill;

        }
        if (n>=2)
        {
            imshow("video_output", frame);
            LKTrackFeature();
            Mat homography_H;
            homography_H = findHomography(fpts[0],fpts[1],RANSAC,3,noArray(),2000,0.995);
            cout << "homograyphy_H:" << homography_H << endl;
            //贴图操作
            vector<Point2f> points_tran;
            perspectiveTransform(one_frame_point4,points_tran,homography_H);
            Mat warp_Homo = getPerspectiveTransform(src_points_4, points_tran);
            Mat frame_clone, frame_fill;
            frame.copyTo(frame_clone);
            frame.copyTo(frame_fill);
            warpPerspective(src_img,frame_clone,warp_Homo,frame_clone.size());
            vector<Point> points_mask;
            for (int i = 0; i <4 ; ++i) {
                points_mask.push_back(points_tran[i]);
            }
            fillConvexPoly(frame_fill,points_mask,Scalar(0,0,0),LINE_AA);
            frame_fill = frame_fill + frame_clone;
            writer << frame_fill;

            //把第二张图片看成第一张
            mask = Mat::zeros(gray.size(), gray.type());
            fillConvexPoly(mask, points_mask ,Scalar(255), LINE_AA);
            gray.copyTo(prev_frame);
            detectFeature(prev_frame);
            for (int i = 0; i < 4; i++)
            {
                one_frame_point4[i] = points_tran[i];
            }
        }
        char c = waitKey(1);
        if (c==27)
        {
            break;
        }

    }
    waitKey(0);
    return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值