实验12

特征点检测与匹配

#include <bits/stdc++.h>
#include <opencv2/opencv.hpp>
#include "opencv2/core.hpp"
#include "opencv2/imgproc.hpp"
#include "opencv2/video.hpp"
#include "opencv2/objdetect.hpp"
#include "opencv2/imgcodecs.hpp"
#include "opencv2/highgui.hpp"
#include "opencv2/ml.hpp"
#define RATIO    0.2
#define p(a) putchar(a)
#define For(i,a,b) for(int i=a;i<=b;++i)
//by war
//2020.12.27
using namespace std;
using namespace cv;

int w,h,w0,h0,bc0,bc1,cnt;
double fps,part,diff,val;
bool lu_flag,flag;
Point lu,rd,mid,st,ed;
Mat temp,image,IMAGE;

const char * path = "/Users/war/Downloads/VID_20201226_210228.mp4";

void in(int &x){
    int y=1;char c=getchar();x=0;
    while(c<'0'||c>'9'){if(c=='-')y=-1;c=getchar();}
    while(c<='9'&&c>='0'){ x=(x<<1)+(x<<3)+c-'0';c=getchar();}
    x*=y;
}
void o(int x){
    if(x<0){p('-');x=-x;}
    if(x>9)o(x/10);
    p(x%10+'0');
}

void onMouse(int event, int x, int y, int flags, void *ustc){
    if(event == EVENT_LBUTTONDOWN){
        lu_flag = 1;
        lu = Point(x,y);
    }
    if(event == EVENT_MOUSEMOVE && lu_flag){
        temp = image.clone();
        rd = Point(x,y);
        if(lu != rd) rectangle(temp, lu, rd, Scalar(255, 0, 0), 3);
        imshow("temp",temp);
    }
    if(event == EVENT_LBUTTONUP){
        lu_flag = 0;flag = 1;
        rd = Point(x,y);
        IMAGE = temp(Rect(lu, rd));
    }
}

void init(){
    VideoCapture video(path);
    if(!video.isOpened()){
        cout<<"视频打开失败!"<<endl;
        return;
    }
    fps = video.get(CAP_PROP_FPS);
    part = 1000.0 / fps;
    namedWindow("temp");
    setMouseCallback("temp", onMouse);
    while(1){
        if(!lu_flag) video >> image;
        if(!image.data || waitKey(part) == 27) break;
        imshow("temp",image);
        if(flag){
            destroyWindow("temp");
            break;
        }
    }
    video.release();
}

void deal(Mat box,Mat scene){
    vector<KeyPoint> keypoints_obj, keypoints_sence;
        Mat descriptors_box, descriptors_sence;
        Ptr<ORB> detector = ORB::create();
        detector->detectAndCompute(scene, Mat(), keypoints_sence, descriptors_sence);
        detector->detectAndCompute(box, Mat(), keypoints_obj, descriptors_box);
        vector<DMatch> matches;

        Ptr<DescriptorMatcher> matcher = makePtr<FlannBasedMatcher>(makePtr<flann::LshIndexParams>(12, 20, 2));
        matcher->match(descriptors_box, descriptors_sence, matches);
        vector<DMatch> goodMatches;
        //printf("total match points : %d
", (int)matches.size());
        float maxdist = 0;
        for (unsigned int i = 0; i < matches.size(); ++i) {
            maxdist = max(maxdist, matches[i].distance);
        }
        for (unsigned int i = 0; i < matches.size(); ++i) {
            if (matches[i].distance < maxdist*RATIO)
                goodMatches.push_back(matches[i]);
        }
        printf("good match points : %d
", (int)goodMatches.size());
        Mat dst;
        drawMatches(IMAGE, keypoints_obj, scene, keypoints_sence, goodMatches, dst);
        imshow("output", dst);
}

void tracking(){
    w = abs(lu.x - rd.x);
    h = abs(lu.y - rd.y);
    auto x0 = lu.x - w;
    auto x1 = lu.x + w;
    auto y0 = rd.y - h;
    auto y1 = rd.y + h;
    x0 = max(0, x0);
    x1 = min(x1, image.cols);
    y0 = max(0, y0);
    y1 = min(y1, image.rows);
    VideoCapture video(path);
    if(!video.isOpened()){
        cout<<"视频打开失败!"<<endl;
        return;
    }
    fps = video.get(CAP_PROP_FPS);
    part = 1000.0 / fps;
    namedWindow("tracking");
    while(1){
        video >> image;
        if(!image.data || waitKey(part) == 27) break;
        deal(IMAGE,image);
    }
    video.release();
}

signed main(){
    init();
    tracking();
    waitKey(0);
    return 0;
}

光流法优化

#include <bits/stdc++.h>
#include <opencv2/opencv.hpp>
#include "opencv2/core.hpp"
#include "opencv2/imgproc.hpp"
#include "opencv2/video.hpp"
#include "opencv2/objdetect.hpp"
#include "opencv2/imgcodecs.hpp"
#include "opencv2/highgui.hpp"
#include "opencv2/ml.hpp"
#include<stdio.h>
#include <string>
#define RATIO    0.2
#define p(a) putchar(a)
#define For(i,a,b) for(int i=a;i<=b;++i)
//by war
//2020.12.27
using namespace std;
using namespace cv;

int w,h,w0,h0,bc0,bc1,cnt;
double fps,part,diff,val,T;
bool lu_flag,flag;
char temp_1[200];
Point lu,rd,mid,st,ed;
Mat temp,image,IMAGE,m1,mask_output;

const char * path = "/Users/war/Downloads/VID_20201227_144102.mp4";

void in(int &x){
    int y=1;char c=getchar();x=0;
    while(c<'0'||c>'9'){if(c=='-')y=-1;c=getchar();}
    while(c<='9'&&c>='0'){ x=(x<<1)+(x<<3)+c-'0';c=getchar();}
    x*=y;
}
void o(int x){
    if(x<0){p('-');x=-x;}
    if(x>9)o(x/10);
    p(x%10+'0');
}

void onMouse(int event, int x, int y, int flags, void *ustc){
    if(event == EVENT_LBUTTONDOWN){
        lu_flag = 1;
        lu = Point(x,y);
    }
    if(event == EVENT_MOUSEMOVE && lu_flag){
        temp = image.clone();
        rd = Point(x,y);
        if(lu != rd) rectangle(temp, lu, rd, Scalar(255, 0, 0), 3);
        imshow("temp",temp);
    }
    if(event == EVENT_LBUTTONUP){
        lu_flag = 0;flag = 1;
        rd = Point(x,y);
        IMAGE = temp(Rect(lu, rd));
    }
}

void init(){
    VideoCapture video(path);
    if(!video.isOpened()){
        cout<<"视频打开失败!"<<endl;
        return;
    }
    fps = video.get(CAP_PROP_FPS);
    part = 1000.0 / fps;
    namedWindow("temp");
    setMouseCallback("temp", onMouse);
    while(1){
        if(!lu_flag) video >> image;
        if(!image.data || waitKey(part) == 27) break;
        imshow("temp",image);
        if(flag){
            destroyWindow("temp");
            break;
        }
    }
    video.release();
}

void Matrix(vector<Point2f> src_corners,vector<Point2f> dst_corners,Mat scene){
    Mat h = findHomography(src_corners, dst_corners);
    m1 = Mat::zeros(scene.size(),CV_8UC3);
    rectangle(m1, lu, rd, Scalar(255, 255, 255), 3);
    warpPerspective(m1, mask_output, h, scene.size());
    Mat New;
    add(scene,mask_output,New);

    Mat des;
    des.create(scene.rows, 2*scene.cols, scene.type());
    Mat r1 = des(Rect(0, 0, scene.cols, scene.rows));
    temp.copyTo(r1);
    Mat r2 = des(Rect(scene.cols, 0, scene.cols, scene.rows));
    New.copyTo(r2);
    for (int i = 0; i < dst_corners.size(); i++){
        auto y0 = dst_corners[i].y;
        auto x0 = dst_corners[i].x + scene.cols;
        auto y1 = src_corners[i].y;
        auto x1 = src_corners[i].x;
        auto y2 = dst_corners[i].y;
        auto x2 = dst_corners[i].x + scene.cols;
        circle(des, Point2f(x0,y0), 3, Scalar(0, 255, 0), 3);
        line(des, Point2f(x1, y1), Point2f(x2, y2), Scalar(0, 0, 255), 4);
    }
    sprintf(temp_1,"fps: %lf",fps);
    putText(des, temp_1, Point(200,100),
        FONT_HERSHEY_SIMPLEX,1, Scalar (0,0,255));
    
    imshow("des", des);
}

void deal(Mat pre,Mat cur){
    
    int maxCount = 50;
    double minDis = 20;
    double qLevel = 0.01;
 
 
    Mat pre_gray, cur_gray;
    vector<uchar> status;
    vector<float> err;


    vector<Point2f>pre_points, cur_points,temp;
    cvtColor(pre, pre_gray, COLOR_RGB2GRAY);
    goodFeaturesToTrack(pre_gray, temp, maxCount, qLevel, minDis);

    for(auto i:temp){
        if(i.x >= lu.x && i.x <= rd.x && i.y>=lu.y && i.y<=rd.y){
            pre_points.push_back(i);
        }
    }

    calcOpticalFlowPyrLK(pre, cur, pre_points, cur_points, status, err);

    int tr_num = 0;

    for (int i = 0; i < status.size(); i++)
    {
        if (status[i] == 1)
            tr_num++;
    }
    if(tr_num>=4){
        Matrix(pre_points,cur_points,cur);
    }
}

void tracking(){
    VideoCapture video(path);
    if(!video.isOpened()){
        cout<<"视频打开失败!"<<endl;
        return;
    }
    fps = video.get(CAP_PROP_FPS);
    part = 1000.0 / fps;
    namedWindow("tracking");
    while(1){
        T = (double)getTickCount();
        video >> image;
        T = ((double)getTickCount() - T) * 10.0 / getTickFrequency();
        fps = 1.0 / T;
        if(!image.data || waitKey(part) == 27) break;
        deal(temp,image);
    }
    video.release();
}

signed main(){
    init();
    tracking();
    waitKey(0);
    return 0;
}

原文地址:https://www.cnblogs.com/war1111/p/14195434.html