`
water84222
  • 浏览: 375380 次
  • 性别: Icon_minigender_1
  • 来自: 大连
社区版块
存档分类
最新评论

camera calibration 摄像头标定 代码整理

阅读更多

网上没有现成的,OPENCV也没有提供完整的示例,自己整理了一下,贴出来记录。

但是这里cvFindChessboardCorners非常不稳定,不能工作, 是否要自己写呢?

#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// OpenCV
#include <cxcore.h>
#include <cv.h>
#include <highgui.h>
#include <cvaux.h>


void InitCorners3D(CvMat *Corners3D, CvSize ChessBoardSize, int Nimages, float SquareSize);

/* uncomment the following to drop frames to prevent delays */
#define DROP_FRAMES 1
#define MAX_PORTS 3
#define MAX_CAMERAS 1
#define NUM_BUFFERS 8


/* declarations for OpenCV */
IplImage                 *current_frame_rgb,grid;
IplImage                 *current_frame_gray;
IplImage                 *readOnlyImg;

int                       freeze = 0;

int image_width = 640;
int image_height = 480;

bool                      verbose = false;


// Calibration stuff
bool   calibration_done = false;
const CvSize    ChessBoardSize = cvSize(4,4);
float    SquareWidth = 101.6f; //in millimeters
const int    NImages = 20; //Number of images to collect
const   int NPoints = 4*4;

CvMat *intrinsics;
CvMat *distortion_coeff;
CvMat *rotation_vectors;
CvMat *translation_vectors;
CvMat *object_points;
CvMat *point_counts;
CvMat *image_points;


int
main(int argc, char *argv[])
{


  int counter = 0;
  int find_corners_result = 0;
  int captured_frames = 0;


  CvPoint2D32f corners[NImages*NPoints];
  int corner_count[NImages];

  CvFont font;
  cvInitFont( &font, CV_FONT_VECTOR0,5, 5, 0, 7, 8);
 
  intrinsics   = cvCreateMat(3,3,CV_32FC1);
  distortion_coeff  = cvCreateMat(1,4,CV_32FC1);
  rotation_vectors  = cvCreateMat(NImages,3,CV_32FC1);
  translation_vectors  = cvCreateMat(NImages,3,CV_32FC1);

  point_counts   = cvCreateMat(NImages,1,CV_32SC1);

  object_points  = cvCreateMat(NImages*NPoints,3,CV_32FC1);
  image_points   = cvCreateMat(NImages*NPoints,2,CV_32FC1);


  // Function to fill in the real-world points of the checkerboard
  InitCorners3D(object_points, ChessBoardSize, NImages, SquareWidth);

 
    CvCapture* capture = 0;
   
    if( argc == 1 || (argc == 2 && strlen(argv[1]) == 1 && isdigit(argv[1][0])))
        capture = cvCaptureFromCAM( argc == 2 ? argv[1][0] - '0' : 0 );
    else if( argc == 2 )
        capture = cvCaptureFromAVI( argv[1] );

    if( !capture )
    {
        fprintf(stderr,"Could not initialize capturing...\n");
        return -1;
    }
 
  // Initialize all of the IplImage structures
  current_frame_rgb = cvCreateImage(cvSize(image_width, image_height), IPL_DEPTH_8U, 3);
  IplImage *current_frame_rgb2 = cvCreateImage(cvSize(image_width, image_height), IPL_DEPTH_8U, 3);
  current_frame_gray = cvCreateImage(cvSize(image_width, image_height), IPL_DEPTH_8U, 1);
  readOnlyImg   = cvCreateImage(cvSize(image_width, image_height), IPL_DEPTH_8U, 3);
  IplImage *tempimg = cvCreateImage(cvSize(image_width, image_height), IPL_DEPTH_8U, 1);
  CvScalar e;
  e.val[0] =1.0;
  cvSet(tempimg,e,0);

  /* make the window */
  //cvZero(readOnlyImg);
  e.val[0] =255;
  e.val[1] =255;
  e.val[2] =255;
  cvSet(readOnlyImg,e,0);
  for(int i = 0;i<ChessBoardSize.width;i++)
   for(int j = 0;j<ChessBoardSize.height;j++)
   {
    int w =image_width/(ChessBoardSize.width);
    int h = image_height/(ChessBoardSize.height);

  if((i+j)%2==1)
     cvRectangle( readOnlyImg, cvPoint(w*i,h*j),cvPoint(w*(i+1)-1,h*(j+1)-1), CV_RGB(0,0,0),CV_FILLED, 8, 0 );
   }


  cvNamedWindow( "grid", 0);
  cvNamedWindow( "Window 0", 0);
 
  cvResizeWindow( "grid", 500,500);
  cvMoveWindow("Window 0", 100, 100);
 

  printf("WHEN THE COUNTER HITS 20, YOU'RE DONE \n");

  while (!calibration_done)
  {
    while (captured_frames < NImages)
    {
      if (verbose) printf("%d \n", counter);
      counter++;

 

   current_frame_rgb = cvQueryFrame( capture );
   //current_frame_rgb = cvLoadImage( "c:\\BoardStereoL3.jpg" );

   if( !current_frame_rgb )
    break;

     cvCvtColor(current_frame_rgb, current_frame_gray, CV_BGR2GRAY);

 //cvMul(current_frame_gray,tempimg,current_frame_gray,1.5);
 //cvAdaptiveThreshold( current_frame_gray, current_frame_gray,255,CV_ADAPTIVE_THRESH_MEAN_C, CV_THRESH_BINARY, 3, 5 );
 
 //cvThreshold( current_frame_gray, current_frame_gray,90,255,CV_THRESH_BINARY_INV);
 //cvThreshold( current_frame_gray, current_frame_gray,90,255,CV_THRESH_BINARY);
 

 int pos = 1;
 IplConvKernel* element = 0;
 const int element_shape = CV_SHAPE_ELLIPSE;
 element = cvCreateStructuringElementEx( pos*2+1, pos*2+1, pos, pos, element_shape, 0 );
 cvDilate(current_frame_gray,current_frame_gray,element,1);
 cvErode(current_frame_gray,current_frame_gray,element,1);
 cvReleaseStructuringElement(&element);

 cvShowImage("grid",current_frame_gray);
 
   
    find_corners_result = cvFindChessboardCorners(current_frame_gray,
                                          ChessBoardSize,
                                          &corners[captured_frames*NPoints],
                                          &corner_count[captured_frames],
                                          0);

      if (find_corners_result !=0)
      {
   
        cvDrawChessboardCorners(current_frame_rgb, ChessBoardSize, &corners[captured_frames*NPoints], NPoints, find_corners_result);

        if (counter%10 == 0)
        // I do this to give you time to move the checkerboard around between captures
        {
          CvTermCriteria corner_criteria = cvTermCriteria(CV_TERMCRIT_ITER, 100, 0.1);
   
          cvFindCornerSubPix( current_frame_gray,&corners[captured_frames*NPoints],
                              NPoints, cvSize(3,3), cvSize(-1,-1),
                              corner_criteria );
                       
          cvPutText(current_frame_rgb, "FLASH!" , cvPoint(100, 300), &font, CV_RGB(255,0,0));
          printf("%d ... \n", captured_frames+1);
          // NOTE: I put the little "FLASH" thing in here so that you know when it takes the snapshot
          //       I'd gotten used to the little flash when using DirectShow for intrinsic calibration
          captured_frames++;
        }
      }
 
      cvShowImage("Window 0",current_frame_rgb);
  
  
      cvWaitKey(100);

      find_corners_result = 0;
    }   
 
    printf("\n");
   
    cvSetData( image_points, corners, sizeof(CvPoint2D32f));
    cvSetData( point_counts, corner_count, sizeof(int));
     
    cvCalibrateCamera2( object_points,
                        image_points,
                        point_counts,
                        cvSize(640,480),
                        intrinsics,
                        distortion_coeff,
                        rotation_vectors,
                        translation_vectors,
                        0);
                       
  calibration_done = true;                       
  }

  //
  // All this below is used for dumping the parameters to the screen
  //

  float intr[3][3] = {0.0};
  float dist[4] = {0.0};
  float tranv[3] = {0.0};
  float rotv[3] = {0.0};

  for ( int i = 0; i < 3; i++)
  {
    for ( int j = 0; j < 3; j++)
    {
      intr[i][j] = ((float*)(intrinsics->data.ptr + intrinsics->step*i))[j];
    }
      dist[i] = ((float*)(distortion_coeff->data.ptr))[i];
      tranv[i] = ((float*)(translation_vectors->data.ptr))[i];
      rotv[i] = ((float*)(rotation_vectors->data.ptr))[i];
  }
  dist[3] = ((float*)(distortion_coeff->data.ptr))[3];

  printf("-----------------------------------------\n");
  printf("INTRINSIC MATRIX: \n");
  printf("[ %6.4f %6.4f %6.4f ] \n", intr[0][0], intr[0][1], intr[0][2]);
  printf("[ %6.4f %6.4f %6.4f ] \n", intr[1][0], intr[1][1], intr[1][2]);
  printf("[ %6.4f %6.4f %6.4f ] \n", intr[2][0], intr[2][1], intr[2][2]);
  printf("-----------------------------------------\n");
  printf("DISTORTION VECTOR: \n");
  printf("[ %6.4f %6.4f %6.4f %6.4f ] \n", dist[0], dist[1], dist[2], dist[3]);
  printf("-----------------------------------------\n");
  printf("ROTATION VECTOR: \n");
  printf("[ %6.4f %6.4f %6.4f ] \n", rotv[0], rotv[1], rotv[2]);
  printf("TRANSLATION VECTOR: \n");
  printf("[ %6.4f %6.4f %6.4f ] \n", tranv[0], tranv[1], tranv[2]);
  printf("-----------------------------------------\n");

  exit(0);
  cvDestroyAllWindows();
}

void InitCorners3D(CvMat *Corners3D, CvSize ChessBoardSize, int NImages, float SquareSize)
{
  int CurrentImage = 0;
  int CurrentRow = 0;
  int CurrentColumn = 0;
  int NPoints = ChessBoardSize.height*ChessBoardSize.width;
  float * temppoints = new float[NImages*NPoints*3];

  // for now, assuming we're row-scanning
  for (CurrentImage = 0 ; CurrentImage < NImages ; CurrentImage++)
  {
    for (CurrentRow = 0; CurrentRow < ChessBoardSize.height; CurrentRow++)
    {
      for (CurrentColumn = 0; CurrentColumn < ChessBoardSize.width; CurrentColumn++)
      {
    temppoints[(CurrentImage*NPoints*3)+(CurrentRow*ChessBoardSize.width + CurrentColumn)*3]=(float)CurrentRow*SquareSize;
    temppoints[(CurrentImage*NPoints*3)+(CurrentRow*ChessBoardSize.width + CurrentColumn)*3+1]=(float)CurrentColumn*SquareSize;
    temppoints[(CurrentImage*NPoints*3)+(CurrentRow*ChessBoardSize.width + CurrentColumn)*3+2]=0.f;
      }
    }
  }
  (*Corners3D) = cvMat(NImages*NPoints,3,CV_32FC1, temppoints);
}
 

分享到:
评论

相关推荐

    GML C++ Camera Calibration 源代码

    相机标定是计算机视觉领域中的一个关键步骤,用于获取摄像头的内在参数,如焦距、主点坐标以及畸变系数等。GML(Geometric Modeling Language)C++相机标定源代码提供了一种实现这一过程的方法。在本篇中,我们将...

    MATLAB工具箱大全-Camera Calibration 像机标定工具箱

    MATLAB的"Camera Calibration"工具箱提供了完整的像机标定解决方案,适用于科研和工程应用。下面将详细介绍这个工具箱的关键知识点和功能。 一、基本概念 1. 像机模型:MATLAB工具箱基于pinhole相机模型,该模型...

    Camera Calibration Tools摄像机标定工具

    《Camera Calibration Tools摄像机标定工具详解》 在计算机视觉领域,摄像机标定是一项至关重要的技术,它能够校正摄像机成像过程中的失真,提高图像处理和分析的精度。Camera Calibration Tools就是专为此目的设计...

    基于C++实现双目摄像头标定以及深度匹配+源代码+文档说明

    CameraCalibration:双目摄像头标定程序 ##使用说明: 1.为项目添加相应依赖库 2.修改LBF训练模型的读取位置 3.使用CameraCalibration代码块对双目摄像头进行标定 - 不懂运行,下载完可以私聊问,可远程教学 该资源...

    camera_calibration 相机标定 vs工程

    在“camera_calibration”与“工程”之间进行对比,我们可以深入理解相机标定在实际应用中的重要性和挑战。 相机标定通常包括以下几个核心知识点: 1. **相机模型**:相机模型描述了图像像素如何对应于现实世界的...

    Flexible Camera Calibration By Viewing a Plane From Unknown Orientations课件

    在"Flexible Camera Calibration By Viewing a Plane From Unknown Orientations"中,主要探讨了相机模型的灵活性以及在不同未知方向下对相机进行校准的方法。 1. **透视变换** 摄像头模型基于透视原理,即三维...

    CameraCalibration.

    OpenCV库提供了强大的摄像头标定工具和函数,例如`findChessboardCorners()`用于检测棋盘格角点,`calibrateCamera()`用于求解相机参数,`initUndistortRectifyMap()`和`remap()`用于图像矫正。在提供的`...

    Matlab相机标定工具箱(Camera Calibration Toolbox for Matlab)实验

    ### Matlab相机标定工具箱(Camera Calibration Toolbox for Matlab)实验详解 #### 一、实验目的与背景 在图像处理和计算机视觉领域,准确地获取相机的内外参数对于后续的图像处理工作至关重要。Matlab相机标定...

    radar_camera_calibration.zip

    "radar_camera_calibration"的压缩包内容可能包含了标定所需的工具、代码和教程,这些资源通常用于执行以下步骤: 1. **标定硬件准备**:确保拥有一个毫米波雷达设备和至少一台摄像头,安装在车辆或平台上,并保持...

    Review on Camera Calibration

    由于摄像头安装位置较低以及使用局部视觉导致场景范围较小,一般标定方法可以满足精度需求。但是,所有计算设备和传感器都安装在机器人上,这意味着对计算资源的需求较高,并且需要高效的算法支持。 #### 三、相机...

    单目摄像头标定.zip

    c++版本代码,对应环境Ubuntu20.04、OpenCV 4.5.3版本。...camera_Calibration1.cpp、camera_Calibration2.cpp是单目相机标定的源码。 camera_Undistortion1.cpp、camera_Undistortion2.cpp是单目相机校正的源码。

    camera_calibration_像机标定_

    在提供的文件“camera_calibration.m”中,很可能是包含了实现这些步骤的MATLAB代码。MATLAB是一种广泛用于科学计算和数据分析的编程环境,非常适合进行图像处理和计算机视觉任务。这个脚本可能包含函数来读取图像、...

    摄像头标定

    对于OpenCV未完全覆盖的需求,开发者可能需要自行编写标定代码。这包括创建自己的棋盘格模板,调整标定参数,甚至优化棋盘角点检测算法。实践中,细致的准备工作,如设定合适的棋盘格尺寸、保持摄像头与标定板的距离...

    anger_camera_greatlyfbi_camera_Cameracalibration_源码.zip

    "Cameracalibration"通常涉及到图像处理和计算机视觉领域,目的是提高摄像头捕捉到的图像质量,使其更准确、更一致。 在计算机视觉中,相机校准是至关重要的一步。它涉及确定相机的内参和外参,以便对捕获的图像...

    Camera calibration With OpenCV的代码介绍

    文档最后提到了标定过程中,为了适应不同分辨率的摄像头,需要将畸变参数与校正时使用的分辨率进行相应的缩放。这是因为在不同的分辨率下,畸变效应的量化表现会有所不同。 总结来说,OpenCV提供了一个结构化的方法...

    BouguetCameraCalibrationToolbox.pdf

    Bouguet Camera Calibration Toolbox是基于MatLab平台开发的一个用于摄像头标定的工具箱,其理论基础和算法实现主要应用于单目摄像头的标定任务中。该工具箱通过使用平面校准物(如棋盘格)来进行摄像头参数的标定,...

    anger_camera_greatlyfbi_camera_Cameracalibration_

    标题中的"anger_camera_greatlyfbi_camera_Cameracalibration_"似乎是一个组合字符串,可能代表一个特定的项目或任务,涉及到相机、FBI(可能是与高质量或专业级摄像头相关的代号)以及相机校准。描述中的"anger ...

    CameraCalibration.zip

    "CameraCalibration.zip" 文件可能包含用于执行以上步骤的代码示例、图像数据集、预定义的参数模板等,帮助用户进行相机标定。对于初次接触此领域的开发者,理解并实践这些步骤是非常有益的,能够提升他们在计算机...

    【camera-radar】相机-毫米波雷达联合标定方案介绍+实现

    本篇文章将深入探讨“相机-毫米波雷达联合标定”这一主题,旨在理解其工作原理、标定方法以及实际应用。 一、相机-毫米波雷达联合标定的重要性 1. 提升定位精度:通过联合标定,可以精确地确定相机和雷达之间的相对...

    matlab相机标定工具箱下载

    在计算机视觉领域,相机标定是一项至关重要的任务,它能够帮助我们精确地理解摄像头的内在参数,从而在图像处理和3D重建等应用中获得准确的结果。Matlab作为一款强大的数学计算软件,提供了丰富的工具箱支持,其中...

Global site tag (gtag.js) - Google Analytics