OpenCV for Ios 学习笔记(6)-标记检测3

本文原始地址:OpenCV for Ios 学习笔记(6)-标记检测3


标记位置的精细化

 //根据相机的旋转,调整标记的姿态
//marker:捕获到的标记
            std::rotate(marker.points.begin(), marker.points.begin() + 4 - nRotations, marker.points.end());

在捕获到标记后并且根据标记编码筛选后,我们应该重新定义它们的角。这步有助于下面估计标记的3d形态。

std::vector<cv::Point2f> preciseCorners(4 * goodMarkers.size());
        //找到所有标记的角点
        for (size_t i=0; i<goodMarkers.size(); i++)
        {
            const Marker& marker = goodMarkers[i];
            
            for (int c = 0; c <4; c++)
            {
                preciseCorners[i*4 + c] = marker.points[c];
            }
        }
        //类型
        /* 
         CV_TERMCRIT_ITER 用最大迭代次数作为终止条件
         CV_TERMCRIT_EPS 用精度作为迭代条件
         CV_TERMCRIT_ITER+CV_TERMCRIT_EPS 用最大迭代次数或者精度作为迭代条件,决定于哪个条件先满足
         */
        //迭代的最大次数
        //特定的阀值
        cv::TermCriteria termCriteria = cv::TermCriteria(cv::TermCriteria::MAX_ITER | cv::TermCriteria::EPS, 30, 0.01);
        
        //输入图像
        //输入的角点,也作为输出更精确的角点
        //接近的大小(Neighborhood size)
        //Aperture parameter for the Sobel() operator
        //像素迭代(扩张)的方法
        cv::cornerSubPix(grayscale, preciseCorners, cvSize(5,5), cvSize(-1,-1), termCriteria);
        
        // 保存最新的顶点
        for (size_t i=0; i<goodMarkers.size(); i++)
        {
            Marker& marker = goodMarkers[i];
            
            for (int c=0;c<4;c++)
            {
                marker.points[c] = preciseCorners[i*4 + c];
            }
        }

我们得到的图像应该像这样:

OpenCV for Ios 学习笔记(6)-标记检测3_第1张图片


但是需要注意一点,我们在标记检测的早期的阶段没有使用cornerSubPix函数是因为它的复杂性-调用这个函数处理大量顶点时会耗费大量的处理时间,因此我们只在处理有效标记时使用。


描绘标记的3维形态


总所周知,增强现实技术是将现实世界与虚拟物体完美融合。为了将物体呈现到3维空间中,我们必须知道它相对于我们正在进行帧捕获的相机的姿态。因此,我们将会在笛卡尔坐标系中使用欧几里得转换来表示这个姿态。

标记在3维空间的位置和它本身的投影矩阵有以下关联:

P = A * [R|T] * M;

其中:

M表示一个3维的点

[R|T] 表示一个[3|4]的欧几里得矩阵

 A表示一个相机矩阵或者固有的矩阵参数

P表示M在屏幕空间中的投影




在我们完成标记标记检测,并且得到它在2维空间的4个角点(屏幕空间投影),下一步我们就要获取A矩阵和M向量参数并计算欧几里得矩阵变换。

Camera Calibration and 3D Reconstruction


相机校准

每个相机都具有独特的参数,如焦距、主点,和镜头畸变模型。

找出相机内在参数的过程就是相机校准。因为相机校准描述了透视变换和在输出图像上的镜头畸变,因此对增强现实应用至关重要。为了取得最好的用户体验,增强现实中的物体也应该使用相同的透视投影。

为了校准相机,我们需要一个特殊的图案(棋盘或者白色背景上的黑色圆圈)。下面是实现相机校准的一个较好的算法:

使用棋盘格来进行摄像机标定

OpenCV for Ios 学习笔记(6)-标记检测3_第2张图片


为了展示相机校准,我们创建CameraCalibration类:


/**
 * 一个相机校准类,存储相机的内在参数和畸变向量
 */

class CameraCalibration
{
public:
  CameraCalibration();
  CameraCalibration(float fx, float fy, float cx, float cy);
  CameraCalibration(float fx, float fy, float cx, float cy, float distorsionCoeff[4]);
  
  void getMatrix34(float cparam[3][4]) const;

  const Matrix33& getIntrinsic() const;
  const Vector4&  getDistorsion() const;
  
private:
  Matrix33 m_intrinsic;
  Vector4  m_distorsion;
};

具体实现:

待传



链接:

http://docs.opencv.org/modules/calib3d/doc/camera_calibration_and_3d_reconstruction.html


你可能感兴趣的:(ios,opencv,ar)