写真1をシフトする
写真2をシフトする
視点マトリックス
基本的なマトリックス
必須のマトリックス
ホモグラフィー行列
ホモグラフ推定: 従来のアルゴリズムから深層学習まで - Zhihu (zhihu.com) https://zhuanlan.zhihu.com/p/74597564
opencv ホモグラフィー行列計算関数 findHomography - Zhihu (zhihu.com) https://zhuanlan.zhihu.com/p/511844759
推定カメラパラメータ
カメラ マトリックス - Jianshu (jianshu.com) https://www.jianshu.com/p/2341da36aa8e
c++ – 左右に異なるカメラマトリックスを使用したOpenCV findEssentialMatおよびrecoverPose – コードログ
#include <iostream>
#include <Eigen/Dense>
Eigen::Matrix3d computeEssentialMatrix(const Eigen::MatrixXd& points1, const Eigen::MatrixXd& points2)
{
// Convert pixel coordinates to normalized plane coordinates
Eigen::MatrixXd normalizedPoints1 = points1.colwise().homogeneous();
Eigen::MatrixXd normalizedPoints2 = points2.colwise().homogeneous();
// Construct the matrix A for the linear equation system
Eigen::MatrixXd A(points1.rows(), 9);
for (int i = 0; i < points1.rows(); ++i) {
A.row(i) << normalizedPoints2(i, 0) * normalizedPoints1(i, 0),
normalizedPoints2(i, 0) * normalizedPoints1(i, 1),
normalizedPoints2(i, 0),
normalizedPoints2(i, 1) * normalizedPoints1(i, 0),
normalizedPoints2(i, 1) * normalizedPoints1(i, 1),
normalizedPoints2(i, 1),
normalizedPoints1(i, 0),
normalizedPoints1(i, 1),
1.0;
}
// Perform singular value decomposition (SVD) on matrix A
Eigen::JacobiSVD<Eigen::MatrixXd> svd(A, Eigen::ComputeFullV);
// Extract the column of V corresponding to the smallest singular value
Eigen::VectorXd singularValues = svd.singularValues();
Eigen::MatrixXd ematrix = svd.matrixV().col(svd.matrixV().cols() - 1).reshaped().topRows(3);
// Rectify the essential matrix to satisfy constraints
Eigen::JacobiSVD<Eigen::MatrixXd> svd2(ematrix, Eigen::ComputeFullU | Eigen::ComputeFullV);
Eigen::VectorXd singularValues2 = svd2.singularValues();
singularValues2[2] = 0.0; // Force the third singular value to be zero
ematrix = svd2.matrixU() * singularValues2.asDiagonal() * svd2.matrixV().transpose();
return ematrix;
}
int main()
{
// Assume we have matched feature point correspondences as Eigen matrices
Eigen::MatrixXd points1(4, 2);
points1 << 10, 20,
30, 40,
50, 60,
70, 80;
Eigen::MatrixXd points2(4, 2);
points2 << 15, 25,
35, 45,
55, 65,
75, 85;
// Compute the essential matrix
Eigen::Matrix3d essentialMatrix = computeEssentialMatrix(points1, points2);
std::cout << "Essential Matrix:\n" << essentialMatrix << std::endl;
return 0;
}
コンピューティングホモグラフィー | 画像の貼り合わせ - YouTube https://www.youtube.com/watch?v=l_qjO4cM74o
cv::Ptr<cv::DescriptorMatcher> matcher = cv::DescriptorMatcher::create(cv::DescriptorMatcher::BRUTEFORCE);
std::vector<std::vector<cv::DMatch>> knnMatches;
std::vector<cv::DMatch> filteredMatches;
matcher->knnMatch(imagecvdescriptors1, imagecvdescriptors2, knnMatches, 2);
filteredMatches.reserve(knnMatches.size());
auto &md = image3->tris.add_attr<float>("matchDistance");
int mdi = 0;
for (const auto& knnMatch : knnMatches) {
if (knnMatch.size() < 2) {
continue;
}
float distanceRatio = knnMatch[0].distance / knnMatch[1].distance;
if (distanceRatio < matchD) {
filteredMatches.push_back(knnMatch[0]);
md[mdi] = static_cast<float>(knnMatch[0].distance);
mdi++;
}
}
zeno::log_info("BRUTEFORCE knnMatches.size:{},filteredMatches.size:{}",knnMatches.size(),filteredMatches.size());