网上没有现成的,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
boolcalibration_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);
}
Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=905822
相关推荐
Camera Calibration Tools摄像机标定工具
CameraCalibration:双目摄像头标定程序 ##使用说明: 1.为项目添加相应依赖库 2.修改LBF训练模型的读取位置 3.使用CameraCalibration代码块对双目摄像头进行标定 - 不懂运行,下载完可以私聊问,可远程教学 该资源...
c++版本代码,对应环境Ubuntu20.04、OpenCV 4.5.3版本。...camera_Calibration1.cpp、camera_Calibration2.cpp是单目相机标定的源码。 camera_Undistortion1.cpp、camera_Undistortion2.cpp是单目相机校正的源码。
【camera-radar】相机-毫米波雷达联合标定方案介绍+实现
该论文讲述了摄像头的内外参标定,包括普通摄像头,广角摄像头,鱼眼摄像头标定。
Bouguet camera calibration tool box 的理论基础。该算法是Opencv单目摄像头标定的原始实现。
3.按下Operation菜单里的Camera Calibration按钮,使用刚刚截取的十五张图片进行相机标定 4.标定成功后,按下Analyse键进行画面分析,在画面中会显示检测到的物体轮廓、形状、最小外接圆、颜色、边长、最小外接圆...
matlab相机标定外参代码相机校准 使用UR机器人安装在机器人上的摄像头进行手眼校准。 硬件 UR10 CB3机器人 树莓派4B 英特尔实感D415 RGBD摄像头 装有Windows / Linux和Python的PC 设想 具有以太网连接的UR10 CB3...
使用了openCV 和cvcut,标定板大小为 10* 10 每个棋盘格的大小为 20mm。
该工具箱是在camera calibration toolbox for matlab的基础上修改得到的一个自动标定工具箱,不用手动提取角点,使用方便~
velo2cam_calibration软件为由LiDAR 和摄像头设备组成的传感器对以任何可能的组合实现...Automatic Extrinsic Calibration Method for LiDAR and Camera Sensor Setups 更多详情、使用方法,请下载后细读README.md文件
TSAI的两步法论文.摄像机标定领域的又一经典文章.想要的就下吧.
GML Camera Calibration是一款主要为摄像爱好者量身打造,帮助你快速进行相机标定。张正友标定法棋盘格,双目标定棋盘格。附带棋盘标定表格A3,A4打印pdf图纸
OCamCalib: Omnidirectional Camera Calibration Toolbox for Matlab 来自苏黎世大学Davide Scaramuzza的OCamCalib全视角相机模型标定矫正算法。作者主页 因为是被墙了,所以我分享出来以供参考。 可用于鱼眼镜头。
MRPT项目[Win64]的Camera Calibration 2.0部分该GUI程序允许用户通过捕获棋盘的几张图像来找出摄像机的摄像机参数。 该程序允许在线抓取或图像,以及选择预先记录的图像文件。 它还显示了重新投影的点,未失真的...
摄像机与激光雷达的外参标定 相机和3D激光雷达之间的外部校准 1,坐标系 2,环境与工具标定板摄像头激光雷达 Visual Studio 2019+opencv matlab PolyWorks 2017 3,流程 ##参考参考 1, 2,2,
从网络摄像头获取图像这是一个小的辅助工具,可以从两个作为立体声对运行的网络摄像头中获取帧。 运行以下命令以使用它。 ./read -w [img_width] -h [img_height] -d [imgs_directory] -e [file_extension] 一旦运行...
calibration(相机标定) segmentation(阈值分割) solvePnP(PnP求解) reconstruction(重建) viz(三维可视化) --- 项目架构 ![image](image/3drecon流程.png) 1. **创建charuco板** 2. **相机标定** 3. **...