openMVG_main_SfMInit_ImageListing

  1. 开始
  • 完成openMVG的编译之后,在build/software/SfM/SfM_GlobalPipeline.py路径下有对应的编译好的文件,该文件里面包含了对应的sfm整个流程的命令执行的pyton程序。如下内容详细解释内含的每条命令。
  1. 执行

    openMVG_main_SfMInit_ImageListing
    -i input_dir
    -o matches_dir
    -d camera_file_params

  • 如上命令的源文件是src/software/SfM/main_SfMInit_ImageListing.cpp

  • 通过阅读源文件的代码有如下全部的输入参数

    • -i:是输入的图像的文件,要求是里面直接包含图像的文件,例如输入的images, 那么images里面是要求直接包含 *.png 或者 *.JPG 之类的图像的格式的文件,与colmap不同,colmap是可以对输入的文件夹进行递归遍历,然后找到文件夹内的所有的图像。

    • -o: 是输出的内容的路径,执行指令之后会输出一个包含图像信息的文件,文件会对图像进行编号,还有相机内参的信息。

    • -d: 是相机文件sensor_width_camera_database.txt,这个文件是SfM_GlobalPipeline.py文件里面可以找到对应的路径。但是我一般通过如下的方式去设定相机的参数。

    • -f: 输入的是一个相机的焦距,是一个浮点型的数据,也就是不区分fx和fy.

    • -k: 输入内参的矩阵,不过要求这个矩阵是一个字符串的形式输入,如"f;0;ppx;0;f;ppy;0;0;1";

    • -c: 输入的相机的模型,有如下几种相机的类型:

      enum EINTRINSIC
      {
      PINHOLE_CAMERA_START = 0,
      PINHOLE_CAMERA, // No distortion
      PINHOLE_CAMERA_RADIAL1, // radial distortion K1
      PINHOLE_CAMERA_RADIAL3, // radial distortion K1,K2,K3
      PINHOLE_CAMERA_BROWN, // radial distortion K1,K2,K3, tangential distortion T1,T2
      PINHOLE_CAMERA_FISHEYE, // a simple Fish-eye distortion model with 4 distortion coefficients
      PINHOLE_CAMERA_END,
      CAMERA_SPHERICAL = PINHOLE_CAMERA_END + 1
      };

  • -g: 一个bool类型的数据, 用于判断是否是输入的相机组,如果是0那么设定每张图像都有对应的相机内参,如果是1设定所有图像共同一个相机内参。

  • -P:如果使用两这个符号位,那么就是说明使用EXIF中的GPS先验信息

  • -W:使用GPS先验信息的权重,如"x;y;z;", 默认三个方向的权重都是1.

  • -m: 设置GPS转换为xyz的方式,0是默认的ECEF的方式,1是UTM的方式。

  1. 重要信息
  • 这个部分的代码涉及到图像初始化的内容,以及相机的内参,相机内参对于SFM来说很重要,轻则结果异常,重则重建失败。
  • 此外,这里面还涉及到比较重要的部分是GPS的使用,以及对应的权重的信息设置
  • 所有的重要的信息都保存到两sfm_data的文件中,可以保存为json的格式方便查看
  1. 代码学习
  2. sfm_data的数据结构
cpp 复制代码
namespace openMVG {
namespace sfm {

/// Define a collection of IntrinsicParameter (indexed by View::id_intrinsic)
using Intrinsics = Hash_Map<IndexT, std::shared_ptr<cameras::IntrinsicBase>>;

/// Define a collection of Pose (indexed by View::id_pose)
using Poses = Hash_Map<IndexT, geometry::Pose3>;

/// Define a collection of View (indexed by View::id_view)
using Views = Hash_Map<IndexT, std::shared_ptr<View>>;

/// Generic SfM data container
/// Store structure and camera properties:
struct SfM_Data
{
  /// Considered views
  Views views;
  /// Considered poses (indexed by view.id_pose)
  Poses poses;
  /// Considered camera intrinsics (indexed by view.id_intrinsic)
  Intrinsics intrinsics;
  /// Structure (3D points with their 2D observations)
  Landmarks structure;
  /// Controls points (stored as Landmarks (id_feat has no meaning here))
  Landmarks control_points;

  /// Root Views path
  std::string s_root_path;

  //--
  // Accessors
  //--
  const Views & GetViews() const {return views;}
  const Poses & GetPoses() const {return poses;}
  const Intrinsics & GetIntrinsics() const {return intrinsics;}
  const Landmarks & GetLandmarks() const {return structure;}
  const Landmarks & GetControl_Points() const {return control_points;}

  /// Check if the View have defined intrinsic and pose
  bool IsPoseAndIntrinsicDefined(const View * view) const
  {
    if (!view) return false;
    return (
      view->id_intrinsic != UndefinedIndexT &&
      view->id_pose != UndefinedIndexT &&
      intrinsics.find(view->id_intrinsic) != intrinsics.end() &&
      poses.find(view->id_pose) != poses.end());
  }

  /// Get the pose associated to a view
  const geometry::Pose3 GetPoseOrDie(const View * view) const
  {
    return poses.at(view->id_pose);
  }
};

} // namespace sfm
} // namespace openMVG
  1. lla转换为ecef
cpp 复制代码
Vec3 lla_to_ecef
(
  double lat,
  double lon,
  double alt
)
{
  const double clat = cos( D2R(lat) );
  const double slat = sin( D2R(lat) );
  const double clon = cos( D2R(lon) );
  const double slon = sin( D2R(lon) );

  const double a2 = Square(WGS84_A);
  const double b2 = Square(WGS84_B);

  const double L = 1.0 / sqrt(a2 * Square(clat) + b2 * Square(slat));
  const double x = (a2 * L + alt) * clat * clon;
  const double y = (a2 * L + alt) * clat * slon;
  const double z = (b2 * L + alt) * slat;

  return Vec3(x, y, z);
}
  1. lla转换为utm
cpp 复制代码
/**
 ** Convert WGS84 lon,lat,alt data to UTM data (Universal Transverse Mercator)
 ** @param lat Latitude in degree
 ** @param lon Longitude in degree
 ** @param alt Altitude relative to the WGS84 ellipsoid
 ** @return UTM corresponding coordinates
 **/
Vec3 lla_to_utm
(
   double lat,
   double lon,
   double alt,
   double a = WGS84_A,
   double b = WGS84_B
)
{
  a /= 1000; // meters to kilometers
  b /= 1000; // meters to kilometers

  /// CONSTANTS
  static const double N0_n = 0;
  static const double N0_s = 1e4;
  static const double E0 = 5e2;
  static const double k0 = 0.9996;
  const double f = (a - b) / a;

  const double n    = f / (2 - f);
  const double n_2  = n   * n;
  const double n_3  = n_2 * n;
  const double n_4  = n_3 * n;
  const double n_5  = n_4 * n;
  const double n_6  = n_5 * n;
  const double n_7  = n_6 * n;
  const double n_8  = n_7 * n;
  const double n_9  = n_8 * n;
  const double n_10 = n_9 * n;

  const int lon_zone = 1 + floor((lon + 180) / 6);

  const double lon_0 = D2R(3 + 6 * (lon_zone - 1) - 180);

  lat = D2R(lat);
  lon = D2R(lon);

  const double A = a / (1 + n) * (1 + n_2/4 + n_4/64 + n_6/256 + n_8*25.0/16384.0 + n_10*49.0/65536.0);

  const double a1 = (1.0/2.0)*n - (2.0/3.0)*n_2 + (5.0/16.0)*n_3 + (41.0/180.0)*n_4 - (127.0/288.0)*n_5 + (7891.0/37800.0)*n_6 + (72161.0/387072.0)*n_7 - (18975107.0/50803200.0)*n_8 + (60193001.0/290304000.0)*n_9 + (134592031.0/1026432000.0)*n_10;
  const double a2 = (13.0/48.0)*n_2 - (3.0/5.0)*n_3 + (557.0/1440.0)*n_4 + (281.0/630.0)*n_5 - (1983433.0/1935360.0)*n_6 + (13769.0/28800.0)*n_7 + (148003883.0/174182400.0)*n_8 - (705286231.0/465696000.0)*n_9 + (1703267974087.0/3218890752000.0)*n_10;
  const double a3 = (61.0/240.0)*n_3 - (103.0/140.0)*n_4 + (15061.0/26880.0)*n_5 + (167603.0/181440.0)*n_6 - (67102379.0/29030400.0)*n_7 + (79682431.0/79833600.0)*n_8 + (6304945039.0/2128896000.0)*n_9 - (6601904925257.0/1307674368000.0)*n_10;
  const double a4 = (49561.0/161280.0)*n_4 - (179.0/168.0)*n_5 + (6601661.0/7257600.0)*n_6 + (97445.0/49896.0)*n_7 - (40176129013.0/7664025600.0)*n_8 + (138471097.0/66528000.0)*n_9 + (48087451385201.0/5230697472000.0)*n_10;
  const double a5 = (34729.0/80640.0)*n_5 - (3418889.0/1995840.0)*n_6 + (14644087.0/9123840.0)*n_7 + (2605413599.0/622702080.0)*n_8 - (31015475399.0/2583060480.0)*n_9 + (5820486440369.0/1307674368000.0)*n_10;
  const double a6 = (212378941.0/319334400.0)*n_6 - (30705481.0/10378368.0)*n_7 + (175214326799.0/58118860800.0)*n_8 + (870492877.0/96096000.0)*n_9 - (1328004581729009.0/47823519744000.0)*n_10;
  const double a7 = (1522256789.0/1383782400.0)*n_7 - (16759934899.0/3113510400.0)*n_8 + (1315149374443.0/221405184000.0)*n_9 + (71809987837451.0/3629463552000.0)*n_10;
  const double a8 = (1424729850961.0/743921418240.0)*n_8 - (256783708069.0/25204608000.0)*n_9 + (2468749292989891.0/203249958912000.0)*n_10;
  const double a9 = (21091646195357.0/6080126976000.0)*n_9 - (67196182138355857.0/3379030566912000.0)*n_10;
  const double a10 = (77911515623232821.0/12014330904576000.0)*n_10;

  const double t = sinh(atanh(sin(lat)) - 2*sqrt(n)/(1+n) * atanh(2*sqrt(n)/(1+n)*sin(lat)));
  const double xi = atan(t/cos(lon-lon_0));
  const double eta = atanh(sin(lon-lon_0) / sqrt(1+t*t));

  const double N0 = (lat > 0 ? N0_n : N0_s);

  const double E = E0 + k0 * A * (eta + a1*cos(2*1*xi)*sinh(2*1*eta) + a2*cos(2*2*xi)*sinh(2*2*eta) + a3*cos(2*3*xi)*sinh(2*3*eta) + a4*cos(2*4*xi)*sinh(2*4*eta) + a5*cos(2*5*xi)*sinh(2*5*eta) + a6*cos(2*6*xi)*sinh(2*6*eta) + a7*cos(2*7*xi)*sinh(2*7*eta) + a8*cos(2*8*xi)*sinh(2*8*eta) + a9*cos(2*9*xi)*sinh(2*9*eta) + a10*cos(2*10*xi)*sinh(2*10*eta));
  const double N = N0 + k0 * A * (xi + a1*sin(2*1*xi)*cosh(2*1*eta) + a2*sin(2*2*xi)*cosh(2*2*eta) + a3*sin(2*3*xi)*cosh(2*3*eta) + a4*sin(2*4*xi)*cosh(2*4*eta) + a5*sin(2*5*xi)*cosh(2*5*eta) + a6*sin(2*6*xi)*cosh(2*6*eta) + a7*sin(2*7*xi)*cosh(2*7*eta) + a8*sin(2*8*xi)*cosh(2*8*eta) + a9*sin(2*9*xi)*cosh(2*9*eta) + a10*sin(2*10*xi)*cosh(2*10*eta));

  // Scale E,N from kilometers to meters
  return Vec3(E * 1000, N * 1000, alt);
}
相关推荐
sdhdwyx1 年前
ubuntu20.04安装配置openMVG+openMVS
c++·算法·openmvs·openmvg