实验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\n", (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\n", (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; }