Example #1
0
void  getObjectPointsAndImagePoints(const Mat& depth1,const Mat& depth2,const vector<KeyPoint>& keyPts1,const vector<KeyPoint>& keyPts2,const vector<DMatch>& matches,vector<Point2f>& imagePoints,vector<Point3f>& objectPoints,vector<Eigen::Vector2d>& imagePoints1,vector<Eigen::Vector2d>& imagePoints2,const CAMERA_INTRINSIC_PARAMETERS& C)
{
    for(size_t i=0;i<matches.size();i++)
    {
        int m = matches[i].queryIdx;
        int n = matches[i].trainIdx;
        int x1 = keyPts1[m].pt.x;
        int y1 = keyPts1[m].pt.y;
        Point2f p = keyPts1[m].pt;
        int x = keyPts2[n].pt.x;
        int y = keyPts2[n].pt.y;

        ushort d = ((ushort*) depth1.data)[y*depth1.cols+x];
        if(d == 0) continue;
        Eigen::Vector2d p1;
        p1<<x1,y1;
        Eigen::Vector2d p2;
        p2<<x,y;
        imagePoints1.push_back(p1);
        imagePoints2.push_back(p2);

        Point3f q(x1,y1,d);

        imagePoints.push_back(p);
        Point3f q1 = point2dTo3d(q,C);
        objectPoints.push_back(q1);
        //cout<<"abcd"<<q1<<endl;

    }
}
Example #2
0
RESULT_OF_PNP estimateMotion( FRAME& frame1, FRAME& frame2, CAMERA_INTRINSIC_PARAMETERS& camera, double good_match_threshold, int min_good_match){
	// 匹配描述子
	vector<cv::DMatch> matches;
	cv::FlannBasedMatcher matcher;
	matcher.match(frame1.desp,frame2.desp,matches);
	//cout<<"Find total "<<matches.size()<<" matches."<<endl;
	/*
	// 可视化:显示匹配的特征
	cv::Mat imgMatches;
	cv::drawMatches(frame1.rgb,frame1.kp,frame2.rgb,frame2.kp,matches,imgMatches);
	cv::imshow("matches",imgMatches);
	cv::imwrite("../pic/matches.png",imgMatches);
	cv::waitKey(0);
	*/
	// 筛选匹配,把距离太大的去掉
	// 这里使用的准则是去掉大于四倍最小距离的匹配
	vector<cv::DMatch> goodMatches;
	double minDis = 9999;
	for(size_t i=0;i<matches.size();i++){
		if(matches[i].distance<minDis){
			minDis = matches[i].distance;
		}
	}
	for(size_t i=0;i<matches.size();i++){
		if(matches[i].distance < good_match_threshold*minDis){
			goodMatches.push_back(matches[i]);
		}
	}
	
	/*
	cv::drawMatches(frame1.rgb,frame1.kp,frame2.rgb,frame2.kp,goodMatches,imgMatches);
	cv::imshow("good matches",imgMatches);
	cv::imwrite("../pic/good_matches.png",imgMatches);
	cv::waitKey(0);
	*/
	// 计算图像间的运动关系
	// 关键函数:cv::solvePnPRansac()
	// 为调用此函数准备必要的参数

	// 第一个帧的三维点
	vector<cv::Point3f> pts_obj;
	// 第二个帧的图像点
	vector<cv::Point2f> pts_img;
	RESULT_OF_PNP result;
	
	if(goodMatches.size() <  min_good_match){
		result.inliers = 0;
	}else{	
		// 显示 good matches
		cout<<"good matches = "<<goodMatches.size()<<endl;
		for(size_t i=0;i<goodMatches.size();i++){
			// query 是第一个, train 是第二个
			cv::Point2f p = frame1.kp[goodMatches[i].queryIdx].pt;
			// 获取d是要小心!x是向右的,y是向下的,所以y才是行,x是列!
			unsigned short d = frame1.depth.ptr<unsigned short>(int(p.y))[int(p.x)];
			if(d == 0){
				continue;
			}
			pts_img.push_back(cv::Point2f(frame2.kp[goodMatches[i].trainIdx].pt));
			// 将(u,v,d)转成(x,y,z)
			cv::Point3f pt(p.x,p.y,d);
			cv::Point3f pd = point2dTo3d(pt,camera);
			pts_obj.push_back(pd);
		}
		if(pts_obj.size() == 0){
			result.inliers = 0;
			return result;
		}
		double camera_matrix_data[3][3] = {
			{camera.fx,0,camera.cx},
			{0,camera.fy,camera.cy},
			{0,0,1}
		};
	
		// 构建相机矩阵
		cv::Mat cameraMatrix(3,3,CV_64F,camera_matrix_data);
		cv::Mat inliers;
		// 求解pnp
		cv::solvePnPRansac(pts_obj,pts_img,cameraMatrix,cv::Mat(),result.rvec,result.tvec,false,100,1.0,100,inliers);
		result.inliers = inliers.rows;
	}
	
	/*
	// 画出inliers匹配
	vector<cv::DMatch> matchesShow;
	for(size_t i=0;i<result.inliers;i++){
		matchesShow.push_back(goodMatches[inliers.ptr<int>(i)[0]]);
	}
	cv::drawMatches(frame1.rgb,frame1.kp,frame2.rgb,frame2.kp,matchesShow,imgMatches);
	cv::imshow("inlier matches",imgMatches);
	cv::imwrite("../pic/inliers.png",imgMatches);
	cv::waitKey(0);
	*/
	return result;
}