1\针对视频流
#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<KeyPoint> keyPoint_one;
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<SIFT> sift = xfeatures2d::SIFT::create();
sift->detectAndCompute(ingray, mask, keyPoint_one, description_one);
vector<Point2f> feature_one;
Point show_point;
Mat show_mask;
mask.copyTo(show_mask);
for (int i = 0; i < keyPoint_one.size(); i++)
{
feature_one.push_back(keyPoint_one[i].pt);
show_point=keyPoint_one[i].pt;
circle(show_mask,show_point,5,Scalar(100),-1,8);
}
fpts[0] = feature_one;
cout << "第一张图片特征点个数" << fpts[0].size() << endl;
imshow("show_mask",show_mask);
}
void LKTrackFeature()
{
//光流追踪
calcOpticalFlowPyrLK(prev_frame, gray, fpts[0], fpts[1], status, errors);
//提取sift特征点
Ptr<SIFT> sift = xfeatures2d::SIFT::create();
vector<KeyPoint> keyPoint_two;
sift->detectAndCompute(gray, mask, keyPoint_two, description_two);
cout << keyPoint_two.size() << endl;
vector<DMatch> matches;
BFMatcher matcher(NORM_L2);
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;
vector<DMatch> good_good_match;
for (int j = 0; j < description_one.rows; j++)
{
float a_dist = max(6 * min_dist, 30.0);
if (matches[j].distance<= a_dist)
{
good_match.push_back(matches[j]);
}
}
cout<<"good_match:"<<good_match.size()<<endl;
int k = 0;
for (int j = 0; j < good_match.size(); j++)
{
int sift_one_index =good_match[j].queryIdx;
int sift_two_index =good_match[j].trainIdx;
float a = fpts[1][sift_one_index].x-keyPoint_two[sift_two_index].pt.x;
float b = fpts[1][sift_one_index].y - keyPoint_two[sift_two_index].pt.y;
float a_b =abs(a)+abs(b);
cout << "a+b:"<<a_b << endl;
if ((a_b<0.05)&&(status[sift_one_index]))
{
good_good_match.push_back(good_match[j]);
fpts[0][k] = fpts[0][sift_one_index];
fpts[1][k++] = fpts[1][sift_one_index];
}
}
fpts[0].resize(k);
fpts[1].resize(k);
cout << fpts[0].size() << endl;
cout << fpts[1].size() << endl;
Mat img_goodmatch;
drawMatches(prev_frame,keyPoint_one,gray,keyPoint_two,good_good_match,img_goodmatch);
imshow("优化后匹配",img_goodmatch);
}
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("../get37_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;
}
2\两张图片间的测试
#include <iostream>
#include <opencv2/opencv.hpp>
#include <opencv2/xfeatures2d.hpp>
using namespace std;
using namespace cv;
vector<Point2f> one_frame_point4;//第一张图片四点
vector<Point2f> src_points_4;
Point point_one;
Mat mask;
//获取贴图图片的坐标
void get_img_points(Mat &src_img)
{
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;
}
}
Mat getmyHomographMat(Mat &lastPart, Mat &curPart,vector<Point2f> &points,vector<Point2f> &one_frame_point4)
{
//寻找第一张图片特征点
vector<KeyPoint> keyPoint_one,keyPoint_two;
Mat description_one,description_two;
vector<Point2f> fpts[2];
vector<uchar> status;
vector<float> errors;
//第一张图片的sift点
Ptr<xfeatures2d::SIFT> sift = xfeatures2d::SIFT::create();
sift->detectAndCompute(lastPart, 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;
//对第二张图片进行处理
//光流追踪
calcOpticalFlowPyrLK(lastPart, curPart, fpts[0], fpts[1], status, errors);
//提取sift特征点
sift->detectAndCompute(curPart, mask, keyPoint_two, description_two);
cout << keyPoint_two.size() << endl;
vector<DMatch> matches;
FlannBasedMatcher matcher;
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;
vector<DMatch> good_good_match;
for (int j = 0; j < description_one.rows; j++)
{
float a_dist = max(6* min_dist, 30.0);
if (matches[j].distance<= a_dist)
{
good_match.push_back(matches[j]);
}
}
cout<<"good_match:"<<good_match.size()<<endl;
int k = 0;
for (int j = 0; j < good_match.size(); j++)
{
int sift_one_index =good_match[j].queryIdx;
int sift_two_index =good_match[j].trainIdx;
float a = fpts[1][sift_one_index].x-keyPoint_two[sift_two_index].pt.x;
float b = fpts[1][sift_one_index].y - keyPoint_two[sift_two_index].pt.y;
float a_b =abs(a)+abs(b);
cout << "a+b:"<<a_b << endl;
if ((a_b<0.05)&&(status[sift_one_index]))
{
good_good_match.push_back(good_match[j]);
fpts[0][k] = fpts[0][sift_one_index];
fpts[1][k++] = fpts[1][sift_one_index];
}
}
fpts[0].resize(k);
fpts[1].resize(k);
cout << fpts[0].size() << endl;
cout << fpts[1].size() << endl;
Mat img_goodmatch;
drawMatches(lastPart,keyPoint_one,curPart,keyPoint_two,good_good_match,img_goodmatch);
imshow("优化后匹配",img_goodmatch);
//获取矩阵
Mat homography_H;
homography_H = findHomography(fpts[0],fpts[1],RANSAC,3,noArray(),2000,0.995);
return homography_H;
}
int main ( int argc, char** argv )
{
//-- 读取图像
Mat img_1 = imread ("../frame1.jpg",1);
Mat img_1_gray;
cvtColor(img_1,img_1_gray,COLOR_BGR2GRAY);
Mat img_2 = imread ( "../frame2.jpg",1);
Mat img_2_gray;
cvtColor(img_2,img_2_gray,COLOR_BGR2GRAY);
Mat src_img = imread("../Tulips.jpg", 1);
//获取贴图四个点
get_img_points(src_img);
//获取贴图位置点
Mat frame_one;
img_1.copyTo(frame_one);
namedWindow("video_input",WINDOW_NORMAL);
setMouseCallback("video_input",on_Left_Mouse,&frame_one);
Mat tempImage;
img_1.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(img_1_gray.size(),img_1_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);
Mat H;
H=getmyHomographMat(img_1,img_2,src_points_4,one_frame_point4);
cout<<H<<endl;
waitKey(0);
return 0;
}