ユークリッド座標系 <-> 同次座標系の変換

座標変換を行う際には、ある点の座標を同次座標で表現したほうが計算が便利な場合がある。
OpenCVでは、ユークリッド座標から同次座標、同次座標からユークリッド座標へ変換するための関数が用意されている。
  • cv::convertPointsToHomogeneous
    同次座標系への変換。n次元の座標をn+1次元の同次座標へ変換する。
  • cv::convertPointsFromHomogeneous
    ユークリッド座標系への変換。n+1次元の同次座標をn次元のユークリッド座標へ変換する。
  • cv::convertPointsHomogeneous
    自動でユークリッド座標系 -> 同次座標系、ユークリッド座標系 <- 同次座標系を判断し変換する。内部で、cv::convertPointsToHomogeneousまたはcv::convertPointsFromHomogeneousを呼び出している。
以下に使用例を示す。

#include <iostream>
#include <vector>

#include <opencv2/opencv.hpp>

int main(int argc, char** argv)
{
  std::vector<cv::Point2d> points2D;

  //適当に二次元座標を生成
  for (int i = 0; i < 10; ++i)
  {
    cv::Point2d p;
    p.x = rand();
    p.y = rand();

    points2D.push_back( p );
  }

  std::vector<cv::Point3d> points3D;

  //ユークリッド座標 -> 同次座標系への変換
  cv::convertPointsToHomogeneous(points2D, points3D);
  std::cout << "Euclidean to Homogeneous" << std::endl;
  for (int i = 0; i < points2D.size(); ++i)
  {
    std::cout << points2D[i] << ", " << points3D[i] << std::endl;
  }

  //同次座標->ユークリッド座標への変換
  for (int i = 0; i < points2D.size(); ++i)
  {
    //points3Dを適当にスケーリング
    points3D[i] *= 3;
  }
  cv::convertPointsFromHomogeneous(points3D, points2D);
  std::cout << "Homogeneous to Euclidean" << std::endl;
  for (int i = 0; i < points2D.size(); ++i)
  {
    std::cout << points2D[i] << ", " << points3D[i] << std::endl;
  }

  //convertPointsHomogeneousでは自動で
  //同次座標系->ユークリッド座標系、ユークリッド座標系->同次座標系を判断
  cv::convertPointsHomogeneous(points2D, points3D);
  std::cout << "Euclidean to Homogeneous" << std::endl;
  for (int i = 0; i < points2D.size(); ++i)
  {
    std::cout << points2D[i] << ", " << points3D[i] << std::endl;
  }

  //四次元同次座標系への変換
  cv::Mat points4D;
  cv::convertPointsToHomogeneous(points3D, points4D);
  std::cout << "Euclidean to Homogeneous" << std::endl;
  for (int i = 0; i < points2D.size(); ++i)
  {
    std::cout << points3D[i] << ", " << points4D.row( i ) << std::endl;
  }

  return 0;
}



結果
Euclidean to Homogeneous
[41, 18467], [41, 18467, 1]
[6334, 26500], [6334, 26500, 1]
[19169, 15724], [19169, 15724, 1]
[11478, 29358], [11478, 29358, 1]
[26962, 24464], [26962, 24464, 1]
[5705, 28145], [5705, 28145, 1]
[23281, 16827], [23281, 16827, 1]
[9961, 491], [9961, 491, 1]
[2995, 11942], [2995, 11942, 1]
[4827, 5436], [4827, 5436, 1]
Homogeneous to Euclidean
[41, 18467], [123, 55401, 3]
[6334, 26500], [19002, 79500, 3]
[19169, 15724], [57507, 47172, 3]
[11478, 29358], [34434, 88074, 3]
[26962, 24464], [80886, 73392, 3]
[5705, 28145], [17115, 84435, 3]
[23281, 16827], [69843, 50481, 3]
[9961, 491], [29883, 1473, 3]
[2995, 11942], [8985, 35826, 3]
[4827, 5436], [14481, 16308, 3]
Euclidean to Homogeneous
[41, 18467], [41, 18467, 1]
[6334, 26500], [6334, 26500, 1]
[19169, 15724], [19169, 15724, 1]
[11478, 29358], [11478, 29358, 1]
[26962, 24464], [26962, 24464, 1]
[5705, 28145], [5705, 28145, 1]
[23281, 16827], [23281, 16827, 1]
[9961, 491], [9961, 491, 1]
[2995, 11942], [2995, 11942, 1]
[4827, 5436], [4827, 5436, 1]
Euclidean to Homogeneous
[41, 18467, 1], [41, 18467, 1, 1]
[6334, 26500, 1], [6334, 26500, 1, 1]
[19169, 15724, 1], [19169, 15724, 1, 1]
[11478, 29358, 1], [11478, 29358, 1, 1]
[26962, 24464, 1], [26962, 24464, 1, 1]
[5705, 28145, 1], [5705, 28145, 1, 1]
[23281, 16827, 1], [23281, 16827, 1, 1]
[9961, 491, 1], [9961, 491, 1, 1]
[2995, 11942, 1], [2995, 11942, 1, 1]
[4827, 5436, 1], [4827, 5436, 1, 1]

コメント

このブログの人気の投稿

COLMAPでキャリブレーション済みのデータを使う

5点アルゴリズムによるカメラ位置・姿勢の推定

2D-3D対応からのカメラ位置・姿勢の推定