目标双站定位仿真C++代码
point-position2 初步完善版。
不再使用eigen库,行列式直接计算得出结果。判断共面异面分别处理。
先提取双站获得图像的匹配特征点,由双站位置信息解析目标位置。

// point-position2.cpp : 定义控制台应用程序的入口点。
#include "stdafx.h"
#include <stdio.h>
#include <iostream>
#include "opencv2/core/core.hpp"
#include "opencv2/features2d/features2d.hpp"
#include "opencv2/highgui/highgui.hpp"
#include <opencv2/nonfree/features2d.hpp>
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/nonfree/nonfree.hpp"
#include "opencv2/legacy/legacy.hpp"
#include<math.h>
using namespace cv; int main( int argc, char** argv )
{ Mat img_1 = imread("book_in_scene.png");
Mat img_2 = imread("book2.png"); if( !img_1.data || !img_2.data )
{ std::cout<< " --(!) Error reading images " << std::endl; return -; } //-- Step 1: Detect the keypoints using SURF Detector
int minHessian = ; SiftFeatureDetector detector( minHessian );
//SurfFeatureDetector detector( minHessian ); vector<KeyPoint> keypoints_1, keypoints_2; detector.detect( img_1, keypoints_1 );
detector.detect( img_2, keypoints_2 ); //-- Step 2: Calculate descriptors (feature vectors)
SiftDescriptorExtractor extractor;
//SurfDescriptorExtractor extractor; Mat descriptors_1, descriptors_2; extractor.compute( img_1, keypoints_1, descriptors_1 );
extractor.compute( img_2, keypoints_2, descriptors_2 ); //-- Step 3: Matching descriptor vectors using FLANN matcher
FlannBasedMatcher matcher;
std::vector< DMatch > matches;
matcher.match( descriptors_1, descriptors_2, matches ); double max_dist = ; double min_dist = ; //-- Quick calculation of max and min distances between keypoints
for( int i = ; i < descriptors_1.rows; i++ )
{ double dist = matches[i].distance;
if( dist < min_dist ) min_dist = dist;
if( dist > max_dist ) max_dist = dist;
} //printf("-- Max dist : %f \n", max_dist );
//printf("-- Min dist : %f \n", min_dist ); //-- Draw only "good" matches (i.e. whose distance is less than 2*min_dist )
//-- PS.- radiusMatch can also be used here.
std::vector< DMatch > good_matches; for( int i = ; i < descriptors_1.rows; i++ )
{ if( matches[i].distance < *min_dist )
{ good_matches.push_back( matches[i]); }
} //-- Draw only "good" matches
Mat img_matches;
drawMatches( img_1, keypoints_1, img_2, keypoints_2,
good_matches, img_matches
); //-- Show detected matches
//imshow( "Good Matches", img_matches );
//imwrite("Lena_match_surf.jpg",img_matches);
//imwrite("Lena_match_sift.jpg",img_matches);
//good_matches[i].queryIdx保存着第一张图片匹配点的序号,keypoints_1[good_matches[i].queryIdx].pt.x 为该序号对应的点的x坐标。y坐标同理
//good_matches[i].trainIdx保存着第二张图片匹配点的序号,keypoints_2[good_matches[i].trainIdx].pt.x 为为该序号对应的点的x坐标。y坐标同理
printf( "--Keypoint 1:%f,%f: %d -- Keypoint 2:%f,%f: %d \n",
keypoints_1[good_matches[].queryIdx].pt.x,keypoints_1[good_matches[].queryIdx].pt.y,good_matches[].queryIdx,
keypoints_2[good_matches[].trainIdx].pt.x,keypoints_2[good_matches[].trainIdx].pt.y,good_matches[].trainIdx );
/*_______________________________________________________________________________________________________________________________*/ double x_inImage1,y_inImage1,x_inImage2,y_inImage2,y,X,Y,alpha,gamma;//像面坐标(x,y)和图像尺寸(X,Y)以及成像视场角(alpha,gamma)
double x1,y1,z1,x2,y2,z2;//双站坐标
double alpha1,gamma1;//双站俯仰角和偏转角
double alpha2,gamma2; //赋予初始值
alpha1=;
gamma1=;
alpha2=;
gamma2=; X=;
Y=;
double FOVx=;
double FOVy=FOVx*Y/X;
x1=,y1=,z1=;
x2=,y2=,z2=; /* //测角偏差补偿
x_inImage1=keypoints_1[good_matches[0].queryIdx].pt.x;//目标点坐标由匹配所得
y_inImage1=keypoints_1[good_matches[0].queryIdx].pt.y;
x_inImage2=keypoints_2[good_matches[0].queryIdx].pt.x;
y_inImage2=keypoints_2[good_matches[0].queryIdx].pt.y; double deviation_alpha1=(x_inImage1-X/2)/X*FOVx;
double deviation_alpha2=(x_inImage2-X/2)/X*FOVx;
double deviation_gamma1=(y_inImage1-Y/2)/X*FOVy;
double deviation_gamma2=(y_inImage2-Y/2)/X*FOVy; alpha1=alpha1+deviation_alpha1;
alpha2=alpha2+deviation_alpha2;
gamma1=gamma1+deviation_gamma1;
gamma2=gamma2+deviation_gamma2;
*/
//开始计算
double pi=*(atan(1.0/))-*atan(1.0/);//精确定义圆周率
std::cout<<"pi为:"<<pi<<std::endl;
alpha1=alpha1*pi/;//角度弧度转换
gamma1=gamma1*pi/;
alpha2=alpha2*pi/;
gamma2=gamma2*pi/; // std::cout<<"cos(alpha1)为:"<<cos(alpha1)<<std::endl;
// std::cout<<"cos(gamma1)为:"<<cos(gamma1)<<std::endl;
double m1=(cos(alpha1))*(cos(gamma1));
double n1=(sin(alpha1))*(cos(gamma1));
double p1=sin(gamma1);
double m2=(cos(alpha2))*(cos(gamma2));
double n2=(sin(alpha2))*(cos(gamma2));
double p2=sin(gamma2); std::cout<<"方向向量1为:"<<m1<<","<<n1<<","<<p1<<std::endl;
std::cout<<"方向向量2为:"<<m2<<","<<n2<<","<<p2<<std::endl; double coplane;//共面判断
coplane=(x2-x1)*(n1*p2-n2*p1)-(y2-y1)*(m1*p2-m2*p1)+(z2-z1)*(m1*n2-m2*n1);//coplane=0共面
if(coplane)
{
//计算公垂线方向向量A1、B1、C1
double A1=n1*p2-n2*p1;
double B1=p1*m2-p2*m1;
double C1=m1*n2-m2*n1;
//
double A2=n2*C1-p2*B1;
double B2=p2*A1-m2*C1;
double C2=m2*B1-n2*A1; double A3=n1*C1-p1*B1;
double B3=p1*A1-m1*C1;
double C3=m1*B1-n1*A1; double delta1=n1*(B1*C2-B2*C1)+m1*(A1*C2-A2*C1);
double delta2=n2*(B1*C3-B3*C1)+m2*(A1*C3-A3*C1);
double D1=A2*(x2-x1)+B2*(y2-y1)+C2*(z2-z1);
double D2=A3*(x1-x2)+B3*(y1-y2)+C3*(z1-z2); double Xg,Yg,Zg,Xh,Yh,Zh,Xtarget,Ytarget,Ztarget;//两直线垂足G和H点坐标,目标点在其中点位置。
Xg=x1-(D1*m1*C1)/delta1;
Yg=y1-(D1*n1*C1)/delta1;
Zg=z1+D1*(A1*m1+B1*n1)/delta1;
Xh=x2-(D2*m2*C1)/delta2;
Yh=y2-(D2*n2*C1)/delta2;
Zh=z2+D2*(A1*m2+B1*n2)/delta2; Xtarget=(Xg+Xh)/;
Ytarget=(Yg+Yh)/;
Ztarget=(Zg+Zh)/; std::cout<<"目标坐标为:"<<Xtarget<<","<<Ytarget<<","<<Ztarget<<std::endl<<std::endl;
}
else//两线共面且相交,引入参数t
{
double t;
t=(p2*(y1-y2)+n2*(z2-z1))/(n2*p1-p2*n1);
double Xtarget,Ytarget,Ztarget;
Xtarget=x1+m1*t;
Ytarget=y1+n1*t;
Ztarget=z1+p1*t;
std::cout<<"目标坐标为:"<<Xtarget<<","<<Ytarget<<","<<Ztarget<<std::endl<<std::endl;
}
getchar();
//waitKey(0);
return ;
}
目标双站定位仿真C++代码的更多相关文章
- iOS定位到崩溃代码行数
不知道大家是不是在代码调试过程中经常遇到项目崩溃的情况: 比如: 数组越界: 没有实现方法选择器: 野指针: 还有很多很多情况.......昨天学到了一种可以直接定位到崩溃代码行数的一个命令,记录一下 ...
- dump文件定位程序崩溃代码行
1.dump文件 2.程序对应的pdb 步骤一:安装windbg 步骤二:通过windbg打开crash dump文件 步骤三:设置pdb文件路径,即符号表路径 步骤四:运行命令!analyze -v ...
- linux设备驱动程序第四部分:从如何定位oops对代码的调试方法,驱动线
在一个我们谈到了如何编写一个简单的字符设备驱动程序,我们不是神,编写肯定会失败的代码,在这个过程中,我们需要继续写代码调试.在普通c应用.我们经常使用printf输出信息.或者使用gdb要调试程序,然 ...
- 使用MAP文件快速定位程序崩溃代码行 (转)
使用MAP文件快速定位程序崩溃代码行 =========================================================== 作者: lzmfeng(http://lz ...
- uboot搬移部分和重定位部分的代码分析
来看一下搬移部分和重定位部分的代码: relocate: /* 把U-BOOT重新定位到RAM*/ //r0=0; adr r0, _start /* r0是代码的当前位置*/ ld ...
- linux设备驱动第四篇:从如何定位oops的代码行谈驱动调试方法
上一篇我们大概聊了如何写一个简单的字符设备驱动,我们不是神,写代码肯定会出现问题,我们需要在编写代码的过程中不断调试.在普通的c应用程序中,我们经常使用printf来输出信息,或者使用gdb来调试程序 ...
- matlab中双站异面直线法定位目标
calc.m %% 参数信息初始化 [x1,y1,z1]=deal(); [x2,y2,z2]=deal(,,); m1=/; n1=/; p1=^(/)/; m2=; n2=-^(/)/; p2=^ ...
- 目标检测之Faster-RCNN的pytorch代码详解(模型训练篇)
本文所用代码gayhub的地址:https://github.com/chenyuntc/simple-faster-rcnn-pytorch (非本人所写,博文只是解释代码) 好长时间没有发博客了 ...
- VS快速定位文件、代码插件——DPack
之前用Myeclipse开发一个Java项目,发现其中“Open Resource”(Ctrl+Shirft+R)的功能比较好用,回到.Net后就找了找VS相应的功能,试了几个后觉得Dpack比较好用 ...
随机推荐
- 如何在Ubuntu上在多个PHP版本之间切换 (for swoole)
摘要: 之前一直用Php7.0,今天想用7.2试下一些特性,安装完之后,切换回7.0却不能再使用7.0的swoole了,原来是切换方式出现了问题 一 从PHP 7.0 切换到 PHP 7.2 Apac ...
- 62. Unique Paths (JAVA)
A robot is located at the top-left corner of a m x n grid (marked 'Start' in the diagram below). The ...
- 设置centos的yum仓库源为阿里源
前提 使我们的主机能够连接到外网 cd /etc/yum.repos.d/ #切换到yum仓库目录下 rm -rf * #删除默认配置仓库 wget -O /etc/yum.repos.d/CentO ...
- SSH整合——登录模块
1.导包——参照我的GitHub Hibernate hibernate/lib/required hibernate/lib/jpa 数据库驱动 Struts2 struts-blank.war/W ...
- Filter(过滤器) 和 interceptor(拦截器)的区别
Filter(过滤器) 和 interceptor(拦截器)的区别 1.拦截器是基于java反射机制的,而过滤器是基于函数回调的. 2.过滤器依赖于Servlet容器,而拦截器不依赖于Servlet容 ...
- Python socket服务
套接字(socket)是一个抽象层,应用程序可以通过它发送或接收数据,可对其进行像对文件一样的打开.读写和关闭等操作. 1. 实现客户端发送字符,服务器返回大写的字符: 服务器: import soc ...
- 【洛谷P1490】买蛋糕
题目大意:给定一个正整数 N,求至少从 [1,N] 中选出多少个数能够表示出 [1,N] 中的所有整数,每个数只能被选 1 次,并求出对于最优解有多少种不同的选择方案. 题解:好题. 仅考虑用最少的不 ...
- 移动web开发问题和经验总结
前言 这里大部分是自己遇到过的情况,还有一部分借鉴了同行的文章,如果大家有遇到其它坑,欢迎提出来一起研究. 知识要点 1. Meta标签 1.禁止用户缩放页面,页面强制让文档的宽度与设备的宽度保持1: ...
- 如何编写高质量的js代码--底层原理
转自: 如何编写高质量的 JS 函数(1) -- 敲山震虎篇 本文首发于 vivo互联网技术 微信公众号 链接:https://mp.weixin.qq.com/s/7lCK9cHmunvYlbm ...
- 【shell】sed指定追加模式空间的次数
最近遇到一个文本复制的场景,需要把文本的每一行都重复输出三次. 这个用awk或者sed实现都还是很简单的. sed代码: [root]$ seq | sed '{h;G;G}' 现在的问题是,如果每行 ...