傲笑风 2017-03-29 11:08 采纳率: 100%
浏览 3067
已采纳

关于opencv标定(cvCalibrateCamera2)的问题

#include"opencv2/opencv.hpp"
#include"opencv2/highgui/highgui.hpp"
#include"opencv2/core/core.hpp"
#include"opencv2/imgproc/imgproc.hpp"
#include"iostream"
using namespace cv;
using namespace std;

int main()
{
VideoCapture capture(1);
if (!capture.isOpened())
{
cout << "摄像头打开失败" << endl;
return 0;
}
Mat frame;
namedWindow("捕捉画面", WINDOW_AUTOSIZE);
char filename[20];
int image_num = 1;

while (true)
{
    capture >> frame;
    if (!frame.data)
    {
        cout << "获取帧数失败" << endl;
        return 0;
    }
    imshow("捕捉画面", frame);
    if (waitKey(10) == ' ')
    {
        sprintf(filename, "%d.jpg", image_num);
        imwrite(filename, frame);
        cout << "截取第" << image_num << "张图片成功" << endl;
        image_num++;
    }
    if(waitKey(10)=='q'||waitKey(10)=='27')
    {
        cout << "总共截取" << --image_num << endl;
        cout << "截图程序结束" << endl;
        break;
    }
}
int rows = frame.rows;
int cols = frame.cols;
destroyWindow("捕捉画面");

Size board_size = Size(7, 7);//棋盘格每行每列的内角点个数
int per_image_point = board_size.height*board_size.width;//每张图片一共多少个角点
CvPoint2D32f* image_point_buf = new CvPoint2D32f[per_image_point];//存放每个角点坐标的坐标的数组
CvMat* image_points=cvCreateMat(per_image_point*image_num, 2, CV_32FC1);//定义图片坐标系
CvMat* object_points=cvCreateMat(per_image_point*image_num, 3, CV_32FC1);//定义世界坐标系
CvMat* point_count = cvCreateMat(image_num,1, CV_32SC1);//用来存放成功标定图片的角点数的图片
IplImage* show;//存放截图到的图片
int found=0;//用来判定是否检测到每张截取图片上所有的角点的标识符
int corner_counts;//存放每张图片输出角点的个数
int success = 0;//用来计算成功标定图片的张数
int step;//用来计算图像坐标系和世界坐标系存储角点坐标的个数
int cube_length = 7;

for (int i=1; i <= image_num; i++)
{
    sprintf(filename, "%d.jpg", i);
    show = cvLoadImage(filename);
    namedWindow("replay");

    /*检测角点*/
    found = cvFindChessboardCorners(show, board_size, image_point_buf, &corner_counts, 
                                    CV_CALIB_CB_ADAPTIVE_THRESH | CV_CALIB_CB_FILTER_QUADS);
    if (found == 0)
    {
        cout << "第" << i << "张图片没有检测到棋盘格所有的角点" << endl;
        cvShowImage("replay", show);
        waitKey(0);
    }
    else
    {
        cout << "第" << i << "张图片检测到" << corner_counts << "个角点" << endl;
        IplImage* grayimage=cvCreateImage(cvGetSize(show),8,1);//创建一个一show具有同一size、8位、单通道的矩阵
        cvCvtColor(show, grayimage, COLOR_BGR2GRAY);

        /*亚像素角点检测*/
        cvFindCornerSubPix(grayimage,image_point_buf,corner_counts,Size(11,11),Size(-1,-1), 
                           TermCriteria(CV_TERMCRIT_ITER+CV_TERMCRIT_EPS, 30, 0.1));

        /*绘制角点*/
        cvDrawChessboardCorners(show, board_size, image_point_buf, corner_counts, found);

        cvShowImage("replay", show);
        waitKey(0);
    }

    if (per_image_point == corner_counts)
    {
        step = success*per_image_point;
        for (int i = step, j = 0; j < per_image_point; ++i, ++j)
        {
            /*由于图像坐标系imagr_points是由image_num行,2列组成,所以第一列存放角点的x坐标,第二列存放角点的y坐标*/
            CV_MAT_ELEM(*image_points, float, i, 0) = image_point_buf[j].x;
            CV_MAT_ELEM(*image_points, float, i, 1) = image_point_buf[j].y;

            CV_MAT_ELEM(*object_points, float, i, 0) = (float)(j / cube_length);
            CV_MAT_ELEM(*object_points, float, i, 1) = (float)(j % cube_length);
            CV_MAT_ELEM(*object_points, float, i, 2) = 0.0f;
        }
        /*图片point_count是由image_num行、1列组成,用来存放成功标定图片的角点数*/
        CV_MAT_ELEM(*point_count, int, success, 0) = per_image_point;
        success++;
    }
}
cvReleaseImage(&show);
cvDestroyWindow("replay");
cout << image_num << "张图片中," << success << "张图片标定成功" << endl;
cout << image_num << "张图片中," << image_num-success << "张图片标定失败" << endl;

/*开始计算摄像机内外参数*/
/*CvCapture* capture1;
capture1 = cvCreateCameraCapture(1);
IplImage* show_colie;
show_colie = cvQueryFrame(capture1);*/

CvMat* object_points2 = cvCreateMat(per_image_point*success, 3, CV_32FC1);
CvMat* image_points2 = cvCreateMat(per_image_point*success, 2, CV_32FC1);
CvMat* point_count2 = cvCreateMat(success, 1, CV_32SC1);

for (int i = 0; i < success*per_image_point; ++i)
{
    CV_MAT_ELEM(*image_points2, float, i, 0) = CV_MAT_ELEM(*image_points, float, i, 0);
    CV_MAT_ELEM(*image_points2, float, i, 1) = CV_MAT_ELEM(*image_points, float, i, 1);
    CV_MAT_ELEM(*object_points2, float, i, 0) = CV_MAT_ELEM(*object_points, float, i, 0);
    CV_MAT_ELEM(*object_points2, float, i, 1) = CV_MAT_ELEM(*object_points, float, i, 1);
    CV_MAT_ELEM(*object_points2, float, i, 2) = CV_MAT_ELEM(*object_points, float, i, 2);
}
for (int i = 0; i < success; ++i)
    CV_MAT_ELEM(*point_count2, int, i, 0) = CV_MAT_ELEM(*point_count, int, i, 0);

cvReleaseMat(&image_points);
cvReleaseMat(&object_points);
cvReleaseMat(&point_count);

/*用来存放形变参数的矩阵,其通常为[k1,k2,p1,p2,k3]的一维向量,其中k1,k2,k3为径向畸变,p1,p2为切向畸变*/
CvMat* distortion_coeffs = cvCreateMat(5, 1, CV_32FC1);

/*用来存放内参数的矩阵,其通常为[fx,0,cx
                                0,fy,cx
                                0, 0, 1]*/                                
CvMat* intrinsic_matrix = cvCreateMat(3, 3, CV_32FC1);
CV_MAT_ELEM(*intrinsic_matrix, float, 0, 0) = 1.0f;
CV_MAT_ELEM(*intrinsic_matrix, float, 1, 1) = 1.0f;

/*计算摄像头的内外参数*/
cvCalibrateCamera2(object_points2, image_points2, point_count2, Size(rows,cols), intrinsic_matrix, distortion_coeffs,
                   NULL, NULL, 0);


cout << "内参数矩阵为:" << endl;
cout << CV_MAT_ELEM(*intrinsic_matrix, float, 0, 0) <<" "<< CV_MAT_ELEM(*intrinsic_matrix, float, 0, 1) 
    <<" "<< CV_MAT_ELEM(*intrinsic_matrix, float, 0, 2) << endl;
cout << CV_MAT_ELEM(*intrinsic_matrix, float, 1, 0) << " " << CV_MAT_ELEM(*intrinsic_matrix, float, 1, 1)
    << " " << CV_MAT_ELEM(*intrinsic_matrix, float, 1, 2) << endl;
cout << CV_MAT_ELEM(*intrinsic_matrix, float, 2, 0) << " " << CV_MAT_ELEM(*intrinsic_matrix, float, 2, 1)
    << " " << CV_MAT_ELEM(*intrinsic_matrix, float, 2, 2) << endl;
//cout << "形变参数为:" << endl;
//cout << distortion_coeffs << endl;

/*cvSave("内参数矩阵.xml", intrinsic_matrix);
cvSave("形变参数矩阵.xml", distortion_coeffs);

CvMat* intrinsic = (CvMat*)cvLoad("内参数矩阵.xml");
CvMat* distortion = (CvMat*)cvLoad("形变参数矩阵.xml");

IplImage* mapx = cvCreateImage(cvGetSize(show_colie), IPL_DEPTH_32F, 1);
IplImage* mapy = cvCreateImage(cvGetSize(show_colie), IPL_DEPTH_32F, 1);

cvInitUndistortMap(intrinsic, distortion, mapx, mapy);

namedWindow("原始图");
namedWindow("非畸变图");

while (show_colie)
{
    show_colie = cvQueryFrame(capture1);
    IplImage* clone = cvCloneImage(show_colie);
    cvShowImage("原始图", show_colie);
    cvRemap(clone, show_colie, mapx, mapy);
    cvReleaseImage(&clone);
    cvShowImage("非畸变图", show_colie);
    waitKey(0);
}
*/
system("pause");
return 0;

}
结果显示:
图片说明
请求大神们告知为什么这样,万分感谢

  • 写回答

1条回答 默认 最新

  • devmiao 2017-03-29 15:26
    关注
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

问题事件

  • 已采纳回答 9月2日

悬赏问题

  • ¥15 vue2中使用计算属性
  • ¥50 远程桌面打开Mastercam、没有许可证、物理机打开正常
  • ¥15 ubuntu安装gdal后java读取tif文件报错
  • ¥15 请问lammps怎么做两种金属连接的原子浓度分布图
  • ¥15 求jacquard数据集
  • ¥15 w10部分软件不能联网
  • ¥15 关于安装hbase的问题(操作系统-windows)
  • ¥15 novnc连接pve虚拟机报错安全协议不支持262
  • ¥15 设备精度0.03给多少公差能达到CPK1.33
  • ¥15 qt+ffmpeg报错non-existing PPS 0 referenced