单张图片计算和下一张图片之间的单应矩阵--无需匹配点

单张图片计算和下一张图片之间的单应矩阵--无需匹配点

使用场景-平面的映射(如地面,墙面)

单应矩阵的基础知识

链接: Basic concepts of the homography explained with code.

链接: Planar Homographies.

链接: 图像处理之理解Homography matrix(单应性矩阵).

OPENCV官方代码案例: https://github.com/opencv/opencv/tree/master/samples/cpp/tutorial_code/features2D/Homography

代码片

博客设置页面,选择一款你喜欢的代码片高亮样式,下面展示同样高亮的 代码片.

// An highlighted block

void computeC2MC1(const Mat &R1, const Mat &tvec1, const Mat &R2, const Mat &tvec2,
                  Mat &R_1to2, Mat &tvec_1to2)
{
    //c2Mc1 = c2Mo * oMc1 = c2Mo * c1Mo.inv()
    R_1to2 = R2 * R1.t();
    tvec_1to2 = R2 * (-R1.t()*tvec1) + tvec2;
}
Mat computeHomography(const Mat &R_1to2, const Mat &tvec_1to2, const double d_inv, const Mat &normal)
{
    Mat homography = R_1to2 + d_inv * tvec_1to2*normal.t();
    return homography;
}
/*
* pose1 pose2 两个机器的POSE值(世界坐标系)
* extrinc_matrix 相机外参 4*4
* cameraMatrix_K 相机内参 3*3
* 输出:单应矩阵
*/
cv::Mat compute_homography_by_para(cv::Vec3f pose1,cv::Vec3f pose2 )
{

    double theta1 = pose1[2]   ;
    double theta2 =  pose2[2];
//    0.389087  Y:   A: -0.015  X: 0.05628  Y: -0.000273276  A: -0.007  LS: 0.381486  AS: 0
// X: 0.782331  Y: -0.024205  A: -0.052  LS: 0  AS: 0 0.799277  Y: -0.014131  A: -0.032
    cv::Mat M_v_o_1= (Mat_<double>(4,4) << cos(theta1),-sin(theta1),0.0,pose1[0],sin(theta1),cos(theta1), 0.0, pose1[1] , 0.0 , 0.0, 1, 0,  0.0, 0.0,0.0, 1);
    cv::Mat M_v_o_2= (Mat_<double>(4,4) << cos(theta2),-sin(theta2),0.0, pose2[0], sin(theta2),cos(theta2), 0.0, pose2[1], 0.0 , 0.0, 1, 0,  0.0, 0.0,0.0, 1);
    cv::Mat M_c1_o =   extrinc_matrix.inv() * M_v_o_1.inv();//extrinc_matrix * M_v_o_1   ;
    cv::Mat M_c2_o =  extrinc_matrix.inv() * M_v_o_2.inv();//extrinc_matrix * M_v_o_2 ;

    cv::Mat R_1to2, tvec_1to2;

    cv::Mat R1 = M_c1_o.rowRange(0,3).colRange(0,3).clone();
    cv::Mat tvec1 =  M_c1_o.rowRange(0,3).colRange(3,4).clone();

    cv::Mat R2 = M_c2_o.rowRange(0,3).colRange(0,3).clone();
    cv::Mat tvec2  = M_c2_o.rowRange(0,3).colRange(3,4).clone();

    computeC2MC1(R1, tvec1, R2, tvec2, R_1to2, tvec_1to2);


    cv::Mat normal = (Mat_<double>(3,1) << 0, 0, 1);
    cv::Mat normal1 = R1  * normal;
    cv::Mat origin(3, 1, CV_64F, Scalar(0));
    cv::Mat origin1 = R1 *origin + tvec1;
    double d_inv1 = 1.0 / normal1.dot(origin1);

    cv::Mat homography_euclidean = computeHomography(R_1to2, tvec_1to2  , d_inv1, normal1);
    cv::Mat homography = cameraMatrix_K * homography_euclidean * cameraMatrix_K.inv();
    homography /= homography.at<double>(2,2);
    return homography;
}
int main()
{

// 初始化机器移动的两个POSE值
        cv::Vec3f pose_vec, next_pose_vec;
        pose_vec[0]  = 0.389087 ;
        pose_vec[1] =  -0.024205 ;
        pose_vec[2]  =  0.05628   ;


        next_pose_vec[0] =  0.782331  ;
        next_pose_vec[1] =  -0.014205 ;
        next_pose_vec[2]  = -0.052 ;

        cv::Mat homography= compute_homography_by_para( pose_vec,next_pose_vec );

        Mat mask_output;
        warpPerspective(origin, mask_output, homography, Size(origin.cols,origin.rows));

        resize(mask_output, mask_output, Size(origin.cols/cutio, origin.rows/cutio));
        cv::Mat cmpare(mask_output, cv::Range(330 , image.rows ),cv::Range(0 , image.cols ));// cols
//        imwrite(convert.str(),image_next);
        cv::namedWindow( "correction", cv::WINDOW_AUTOSIZE );
        cv::imshow( "correction", cmpare      );
        cv::waitKey(0);
        return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是基于OpenCV库的Python代码实现: ``` import cv2 import numpy as np # 读取两张图片 img1 = cv2.imread('image1.jpg') img2 = cv2.imread('image2.jpg') # 初始化ORB检测器 orb = cv2.ORB_create() # 使用ORB检测器提取关键和描述符 kp1, des1 = orb.detectAndCompute(img1, None) kp2, des2 = orb.detectAndCompute(img2, None) # 使用Brute-Force匹配器进行特征匹配 bf = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck=True) matches = bf.match(des1, des2) # 将匹配结果按照距离从小到大排序 matches = sorted(matches, key=lambda x: x.distance) # 选取前10个最佳匹配对 best_matches = matches[:10] # 绘制匹配结果 img_matches = cv2.drawMatches(img1, kp1, img2, kp2, best_matches, None, flags=2) # 显示匹配结果 cv2.imshow('Matches', img_matches) cv2.waitKey(0) # 提取匹配对的坐标 src_pts = np.float32([kp1[m.queryIdx].pt for m in best_matches]).reshape(-1, 1, 2) dst_pts = np.float32([kp2[m.trainIdx].pt for m in best_matches]).reshape(-1, 1, 2) # 使用RANSAC算法计算单应矩阵 H, mask = cv2.findHomography(src_pts, dst_pts, cv2.RANSAC, 5.0) # 输出单应矩阵 print('Homography Matrix:\n', H) ``` 代码实现的具体步骤如下: 1. 使用OpenCV库读取两张图片。 2. 初始化ORB检测器,使用它提取两张图片的关键和描述符。 3. 使用Brute-Force匹配器进行特征匹配,将匹配结果按照距离从小到大排序,选取前10个最佳匹配对。 4. 绘制匹配结果并显示。 5. 提取匹配对的坐标,使用RANSAC算法计算单应矩阵。 6. 输出单应矩阵。 需要注意的是,单应矩阵计算可能存在误差,因此需要对结果进行验证和修正。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值