基于OpenCV做“三维重建”(4)--相机姿态还原和实现三维重建

本文介绍了使用OpenCV进行三维重建的过程,通过读取相机校准参数并利用这些参数及图像点与对象点来确定相机位置。文中展示了如何创建虚拟场景,并通过解决PnP问题得到相机姿态。
v当我们构建成功了viz,就可以使用3维效果给我们提供的便利,进一步进行一些3维的操作。
508489-20190403105137449-1002395233.png
在这个动画中,注意图片后面的那个黑线,对应的是相机的位置。
/*------------------------------------------------------------------------------------------*\
This file contains material supporting chapter 11 of the book:
OpenCV3 Computer Vision Application Programming Cookbook
Third Edition
by Robert Laganiere, Packt Publishing, 2016.
This program is free software; permission is hereby granted to use, copy, modify,
and distribute this source code, or portions thereof, for any purpose, without fee,
subject to the restriction that the copyright notice may not be removed
or altered from any source or altered source distribution.
The software is released on an as-is basis and without any warranties of any kind.
In particular, the software is not guaranteed to be fault-tolerant or free from failure.
The author disclaims all warranties with regard to this software, any use,
and any consequent failure, is purely the responsibility of the user.
Copyright (C) 2016 Robert Laganiere, www.laganiere.name
\*------------------------------------------------------------------------------------------*/
#include "stdafx.h"
#include <opencv2/core.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/viz.hpp>
#include <opencv2/calib3d.hpp>
#include <iostream>
int main()
{
    // Read the camera calibration parameters
    cv::Mat cameraMatrix;
    cv::Mat cameraDistCoeffs;
    cv::FileStorage fs("calib.xml"cv::FileStorage::READ);
    fs["Intrinsic"] >> cameraMatrix;
    fs["Distortion"] >> cameraDistCoeffs;
    std::cout << " Camera intrinsic: " << cameraMatrix.rows << "x" << cameraMatrix.cols << std::endl;
    std::cout << cameraMatrix.at<double>(0, 0) << " " << cameraMatrix.at<double>(0, 1) << " " << cameraMatrix.at<double>(0, 2) << std::endl;
    std::cout << cameraMatrix.at<double>(1, 0) << " " << cameraMatrix.at<double>(1, 1) << " " << cameraMatrix.at<double>(1, 2) << std::endl;
    std::cout << cameraMatrix.at<double>(2, 0) << " " << cameraMatrix.at<double>(2, 1) << " " << cameraMatrix.at<double>(2, 2) << std::endl << std::endl;
    cv::Matx33d cMatrix(cameraMatrix);
    // Input image points
    std::vector<cv::Point2fimagePoints;
    imagePoints.push_back(cv::Point2f(136, 113));
    imagePoints.push_back(cv::Point2f(379, 114));
    imagePoints.push_back(cv::Point2f(379, 150));
    imagePoints.push_back(cv::Point2f(138, 135));
    imagePoints.push_back(cv::Point2f(143, 146));
    imagePoints.push_back(cv::Point2f(381, 166));
    imagePoints.push_back(cv::Point2f(345, 194));
    imagePoints.push_back(cv::Point2f(103, 161));
    // Input object points
    std::vector<cv::Point3fobjectPoints;
    objectPoints.push_back(cv::Point3f(0, 45, 0));
    objectPoints.push_back(cv::Point3f(242.5, 45, 0));
    objectPoints.push_back(cv::Point3f(242.5, 21, 0));
    objectPoints.push_back(cv::Point3f(0, 21, 0));
    objectPoints.push_back(cv::Point3f(0, 9, -9));
    objectPoints.push_back(cv::Point3f(242.5, 9, -9));
    objectPoints.push_back(cv::Point3f(242.5, 9, 44.5));
    objectPoints.push_back(cv::Point3f(0, 9, 44.5));
    // Read image
    cv::Mat image = cv::imread("e:/template/bench2.jpg");
    // Draw image points
    for (int i = 0; i < 8; i++) {
        cv::circle(imageimagePoints[i], 3, cv::Scalar(0, 0, 0),2);
    }
    cv::imshow("An image of a bench"image);
    // Create a viz window
    cv::viz::Viz3d visualizer("Viz window");
    visualizer.setBackgroundColor(cv::viz::Color::white());
    /// Construct the scene
    // Create a virtual camera
    cv::viz::WCameraPosition cam(cMatrix,  // matrix of intrinsics
        image,    // image displayed on the plane
        30.0,     // scale factor
        cv::viz::Color::black());
    // Create a virtual bench from cuboids
    cv::viz::WCube plane1(cv::Point3f(0.0, 45.0, 0.0), 
        cv::Point3f(242.5, 21.0, -9.0), 
        true,  // show wire frame 
        cv::viz::Color::blue());
    plane1.setRenderingProperty(cv::viz::LINE_WIDTH, 4.0);
    cv::viz::WCube plane2(cv::Point3f(0.0, 9.0, -9.0), 
        cv::Point3f(242.5, 0.0, 44.5), 
        true,  // show wire frame 
        cv::viz::Color::blue());
    plane2.setRenderingProperty(cv::viz::LINE_WIDTH, 4.0);
    // Add the virtual objects to the environment
    visualizer.showWidget("top"plane1);
    visualizer.showWidget("bottom"plane2);
    visualizer.showWidget("Camera"cam);
    // Get the camera pose from 3D/2D points
    cv::Mat rvectvec;
    cv::solvePnP(objectPointsimagePoints,      // corresponding 3D/2D pts 
        cameraMatrixcameraDistCoeffs// calibration 
        rvectvec);                    // output pose
    std::cout << " rvec: " << rvec.rows << "x" << rvec.cols << std::endl;
    std::cout << " tvec: " << tvec.rows << "x" << tvec.cols << std::endl;
    cv::Mat rotation;
    // convert vector-3 rotation
    // to a 3x3 rotation matrix
    cv::Rodrigues(rvecrotation);
    // Move the bench    
    cv::Affine3d pose(rotationtvec);
    visualizer.setWidgetPose("top"pose);
    visualizer.setWidgetPose("bottom"pose);
    // visualization loop
    while(cv::waitKey(100)==-1 && !visualizer.wasStopped())
    {
        visualizer.spinOnce(1,     // pause 1ms 
            true); // redraw
    }
    return 0;
}

三维重建这块,我也运行成功书本的例子:
508489-20190403105138331-1997157320.jpg

508489-20190403105138745-469776304.jpg





附件列表

 

转载于:https://www.cnblogs.com/jsxyhelu/p/10647399.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值