供一份可以调试的程序.不知道对不对,也是从网上拼凑,拷贝过来的. 标定的图像好像要求比较苛刻,总是找不到点,将就着用把. main函数直接调用 calibrate_main()就可以了
标定总是找不到点,图像要求很高,可能整个算法只能做测试,不能实际应用了.
#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)
{
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);
}
void calibrate_main()
{
int image_width = 864;
int image_height = 648;//待标定图片的大小
const int ChessBoardSize_w = 9;
const int ChessBoardSize_h = 9;//图片中可标定的标角数
const CvSize ChessBoardSize = cvSize(ChessBoardSize_w,ChessBoardSize_h);
const int NPoints = ChessBoardSize_w*ChessBoardSize_h;
const int NImages=15;//待标定的图片数
int corner_count[NImages] = {0};
float SquareWidth = 20; //棋盘格子的边长,可任意设定,不影响内参数,只影响内参数
CvMat *intrinsics;
CvMat *distortion_coeff;
CvMat *rotation_vectors;
CvMat *translation_vectors;
CvMat *object_points;
CvMat *point_counts;
CvMat *image_points;
IplImage *current_frame_rgb;
IplImage *current_frame_gray;
IplImage *chessBoard_Img;
CvPoint2D32f corners[NPoints*NImages];
chessBoard_Img =cvCreateImage(cvSize(image_width, image_height), IPL_DEPTH_8U, 3);
current_frame_gray = cvCreateImage(cvSize(image_width, image_height), IPL_DEPTH_8U, 1);
current_frame_rgb = cvCreateImage(cvSize(image_width, image_height), IPL_DEPTH_8U, 3);
int captured_frames=0;
for(captured_frames=0;captured_frames<NImages;captured_frames++)
{
char* filename ="chess_std.bmp"; //说明:我把待标定的图片的名子依次命名为:01.jpg, 02.jpg, 03.jpg, 04.jpg,……
switch(captured_frames)
{
case 0: filename="mimage\\c01.bmp"; break;
case 1: filename="mimage\\c02.bmp"; break;
case 2: filename="mimage\\c03.bmp"; break;
case 3: filename="mimage\\c04.bmp"; break;
case 4: filename="mimage\\c05.bmp"; break;
case 5: filename="mimage\\c06.bmp"; break;
case 6: filename="mimage\\c07.bmp"; break;
case 7: filename="mimage\\c08.bmp"; break;
case 8: filename="mimage\\c09.bmp"; break;
case 9: filename="mimage\\c10.bmp"; break;
case 10: filename="mimage\\c11.bmp"; break;
case 11: filename="mimage\\c12.bmp"; break;
case 12: filename="mimage\\c13.bmp"; break;
case 13: filename="mimage\\c14.bmp"; break;
case 14: filename="mimage\\c15.bmp"; break;
case 15: filename="mimage\\c16.bmp"; break;
case 16: filename="mimage\\c17.bmp"; break;
}
chessBoard_Img=cvLoadImage( filename, CV_LOAD_IMAGE_COLOR );
cvCvtColor(chessBoard_Img, current_frame_gray, CV_BGR2GRAY);
cvCopy(chessBoard_Img,current_frame_rgb);
int find_corners_result;
find_corners_result = cvFindChessboardCorners(current_frame_gray, ChessBoardSize, &corners[captured_frames*NPoints],
&corner_count[captured_frames],
CV_CALIB_CB_ADAPTIVE_THRESH );
cvFindCornerSubPix( current_frame_gray,
&corners[captured_frames*NPoints],
NPoints, cvSize(2,2),cvSize(-1,-1),
cvTermCriteria(CV_TERMCRIT_ITER|CV_TERMCRIT_EPS,20,0.03) );
cvDrawChessboardCorners(current_frame_rgb, ChessBoardSize,
&corners[captured_frames*NPoints],
NPoints,
find_corners_result);
// cvNamedWindow( "Window 0", 0);
cvNamedWindow( "result", 0);
//cvShowImage("Window 0",chessBoard_Img);
cvShowImage("result",current_frame_rgb);
cvWaitKey(50000);
}
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);
InitCorners3D(object_points, ChessBoardSize, NImages, SquareWidth);
cvSetData( image_points, corners, sizeof(CvPoint2D32f));
cvSetData( point_counts, &corner_count, sizeof(int));
cvCalibrateCamera2( object_points,
image_points,
point_counts,
cvSize(image_width,image_height),
intrinsics,
distortion_coeff,
rotation_vectors,
translation_vectors,
0);
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
[j] = ((float*)(intrinsics->data.ptr + intrinsics->step*i))[j];
}
dist
= ((float*)(distortion_coeff->data.ptr))
;
tranv
= ((float*)(translation_vectors->data.ptr))
;
rotv
= ((float*)(rotation_vectors->data.ptr))
;
}
dist[3] = ((float*)(distortion_coeff->data.ptr))[3];
printf("----------------------------------------\r\n ");
printf("INTRINSIC MATRIX: \r\n ");
printf("[ %6.4f %6.4f %6.4f ] \r\n ", intr[0][0], intr[0][1], intr[0][2]);
printf("[ %6.4f %6.4f %6.4f ] \r\n ", intr[1][0], intr[1][1], intr[1][2]);
printf("[ %6.4f %6.4f %6.4f ] \r\n ", intr[2][0], intr[2][1], intr[2][2]);
printf("----------------------------------------- \r\n ");
printf("DISTORTION VECTOR: \r\n ");
printf("[ %6.4f %6.4f %6.4f %6.4f ] \r\n ", dist[0], dist[1], dist[2], dist[3]);
printf("----------------------------------------- \r\n ");
printf("ROTATION VECTOR: \r\n ");
printf("[ %6.4f %6.4f %6.4f ] \r\n ", rotv[0], rotv[1], rotv[2]);
printf("TRANSLATION VECTOR: \r\n ");
printf("[ %6.4f %6.4f %6.4f ] \r\n ", tranv[0], tranv[1], tranv[2]);
printf("----------------------------------------- \r\n ");
cvReleaseMat(&intrinsics);
cvReleaseMat(&distortion_coeff);
cvReleaseMat(&rotation_vectors);
cvReleaseMat(&translation_vectors);
cvReleaseMat(&point_counts);
cvReleaseMat(&object_points);
cvReleaseMat(&image_points);
cvDestroyAllWindows();
}