opencv calibration demo 阅读笔记

本文是在阅读opencv sample 所做的笔记。

fundamental

ctype.h

ctype.h character conversion macros and ctype macros
The ctype.h header file of the C Standard Library declares several functions that are useful for testing and mapping characters.

All the functions accepts int as a parameter, whose value must be EOF or representable as an unsigned char.

time

    time_t tt;
    time(&tt);
    struct tm *t2 = localtime(&tt);
    char buf[1024];
    strftime(buf, sizeof(buf) - 1, "%c", t2);

    fs << "calibration_time" << buf;

time 函数返回秒数自午夜 (00:00 elapsed: 00), 1970 年一月 1 日,协调世界 (UTC)时 (utc),根据系统时钟。 返回值。 timer给定位置的存储。 ,在不存储情况下,此参数可以为 NULL返回值。

time 是 _time64 的包装,默认情况下,因此, time_t 与 __time64_t等效。 如果需要强制编译器解释 time_t 为旧 32 位 time_t,可以定义 _USE_32BIT_TIME_T。 这样做,因为应用程序可以在 2038 中,一月 18 日之后失败不建议使用;使用此宏在 64 位平台不允许的。

calib

calib3d moudle in opencv 包含了很多用来标定用的函数。

FileStorage

class FileStorage
XML/YAML file storage class that encapsulates all the information necessary for writing or reading data to/from a file.

All the functions return non-zero (true) if the argument c satisfies the condition described, and zero(false) if not.

main steps

code

1.print help and use instructions.
if (argc < 2)
{
    help();
    return 0;
}
2.解析 输入命令行参数
for (i = 1; i < argc; i++)
{
    const char* s = argv[i];
    if (strcmp(s, "-w") == 0)
    {
        if (sscanf(argv[++i], "%u", &boardSize.width) != 1 || boardSize.width <= 0)
            return fprintf(stderr, "Invalid board width\n"), -1;
    }
    else if (strcmp(s, "-h") == 0)
    {
        if (sscanf(argv[++i], "%u", &boardSize.height) != 1 || boardSize.height <= 0)
            return fprintf(stderr, "Invalid board height\n"), -1;
    }
    else if (strcmp(s, "-pt") == 0)
    {
        i++;
        if (!strcmp(argv[i], "circles"))
            pattern = CIRCLES_GRID;
        else if (!strcmp(argv[i], "acircles"))
            pattern = ASYMMETRIC_CIRCLES_GRID;
        else if (!strcmp(argv[i], "chessboard"))
            pattern = CHESSBOARD;
        else
            return fprintf(stderr, "Invalid pattern type: must be chessboard or circles\n"), -1;
    }
    else if (strcmp(s, "-s") == 0)
    {
        if (sscanf(argv[++i], "%f", &squareSize) != 1 || squareSize <= 0)
            return fprintf(stderr, "Invalid board square width\n"), -1;
    }
    else if (strcmp(s, "-n") == 0)
    {
        if (sscanf(argv[++i], "%u", &nframes) != 1 || nframes <= 3)
            return printf("Invalid number of images\n"), -1;
    }
    else if (strcmp(s, "-a") == 0)
    {
        if (sscanf(argv[++i], "%f", &aspectRatio) != 1 || aspectRatio <= 0)
            return printf("Invalid aspect ratio\n"), -1;
        flags |= CALIB_FIX_ASPECT_RATIO;
    }
    else if (strcmp(s, "-d") == 0)
    {
        if (sscanf(argv[++i], "%u", &delay) != 1 || delay <= 0)
            return printf("Invalid delay\n"), -1;
    }
    else if (strcmp(s, "-op") == 0)
    {
        writePoints = true;
    }
    else if (strcmp(s, "-oe") == 0)
    {
        writeExtrinsics = true;
    }
    else if (strcmp(s, "-zt") == 0)
    {
        flags |= CALIB_ZERO_TANGENT_DIST;
    }
    else if (strcmp(s, "-p") == 0)
    {
        flags |= CALIB_FIX_PRINCIPAL_POINT;
    }
    else if (strcmp(s, "-v") == 0)
    {
        flipVertical = true;
    }
    else if (strcmp(s, "-V") == 0)
    {
        videofile = true;
    }
    else if (strcmp(s, "-o") == 0)
    {
        outputFilename = argv[++i];
    }
    else if (strcmp(s, "-su") == 0)
    {
        showUndistorted = true;
    }
    else if (s[0] != '-')
    {
        if (isdigit(s[0]))
            sscanf(s, "%d", &cameraId);
        else
            inputFilename = s;
    }
    else
        return fprintf(stderr, "Unknown option %s", s), -1;
}
分类处理输入图片和视频

if (inputFilename)
{
    if (!videofile && readStringList(inputFilename, imageList))
        mode = CAPTURING;
    else
        capture.open(inputFilename);
}
else
    capture.open(cameraId);

准备读入图像数据


if (!capture.isOpened() && imageList.empty())
    return fprintf(stderr, "Could not initialize video (%d) capture\n", cameraId), -2;

if (!imageList.empty())
    nframes = (int)imageList.size();

if (capture.isOpened())
    printf("%s", liveCaptureHelp);

读取图像


namedWindow("Image View", 1);

for (i = 0;; i++)//main loop
{
    Mat view, viewGray;
    bool blink = false;

    if (capture.isOpened())
    {
        Mat view0;
        capture >> view0;
        view0.copyTo(view);
    }
    else if (i < (int)imageList.size())
        view = imread(imageList[i], 1);
//image list 读入mat 
    if (view.empty())
    {
        if (imagePoints.size() > 0)
            runAndSave(outputFilename, imagePoints, imageSize,
            boardSize, pattern, squareSize, aspectRatio,
            flags, cameraMatrix, distCoeffs,
            writeExtrinsics, writePoints);
        break;
    }
//将一些标定的配置信息写入要输出的文件
    imageSize = view.size();

    if (flipVertical)
        flip(view, view, 0);

    vector<Point2f> pointbuf;
    cvtColor(view, viewGray, COLOR_BGR2GRAY);
///检测角点,
    bool found;
    switch (pattern)
    {
    case CHESSBOARD:
        found = findChessboardCorners(view, boardSize, pointbuf,CALIB_CB_ADAPTIVE_THRESH | CALIB_CB_FAST_CHECK | CALIB_CB_NORMALIZE_IMAGE);
        break;
    case CIRCLES_GRID:
        found = findCirclesGrid(view, boardSize, pointbuf);
        break;
    case ASYMMETRIC_CIRCLES_GRID:
        found = findCirclesGrid(view, boardSize, pointbuf, CALIB_CB_ASYMMETRIC_GRID);
        break;
    default:
        return fprintf(stderr, "Unknown pattern type\n"), -1;
    }
// improve the found corners' coordinate accuracy
    if (pattern == CHESSBOARD && found) cornerSubPix(viewGray, pointbuf, Size(11, 11),
        Size(-1, -1), TermCriteria(TermCriteria::EPS + TermCriteria::COUNT, 30, 0.1));

    if (mode == CAPTURING && found &&
        (!capture.isOpened() || clock() - prevTimestamp > delay*1e-3*CLOCKS_PER_SEC))
    {
        imagePoints.push_back(pointbuf);
        prevTimestamp = clock();
        blink = capture.isOpened();
    }
//标注检测出角点的位置
    if (found)
        drawChessboardCorners(view, boardSize, Mat(pointbuf), found);
开始标定
    string msg = mode == CAPTURING ? "100/100" :
        mode == CALIBRATED ? "Calibrated" : "Press 'g' to start";
    int baseLine = 0;
    Size textSize = getTextSize(msg, 1, 1, 1, &baseLine);
    Point textOrigin(view.cols - 2 * textSize.width - 10, view.rows - 2 * baseLine - 10);

    if (mode == CAPTURING)
    {
        if (undistortImage)
            msg = format("%d/%d Undist", (int)imagePoints.size(), nframes);
        else
            msg = format("%d/%d", (int)imagePoints.size(), nframes);
    }

    putText(view, msg, textOrigin, 1, 1,
        mode != CALIBRATED ? Scalar(0, 0, 255) : Scalar(0, 255, 0));

    if (blink)
        bitwise_not(view, view);

    if (mode == CALIBRATED && undistortImage)
    {
        Mat temp = view.clone();
        undistort(temp, view, cameraMatrix, distCoeffs);
    }

    imshow("Image View", view);
    int key = 0xff & waitKey(capture.isOpened() ? 50 : 500);

    if ((key & 255) == 27)
        break;
///确认是否畸变矫正
    if (key == 'u' && mode == CALIBRATED)
        undistortImage = !undistortImage;

    if (capture.isOpened() && key == 'g')
    {
        mode = CAPTURING;
        imagePoints.clear();
    }
///进入标定主函数
    if (mode == CAPTURING && imagePoints.size() >= (unsigned)nframes)
    {
        if (runAndSave(outputFilename, imagePoints, imageSize,
            boardSize, pattern, squareSize, aspectRatio,
            flags, cameraMatrix, distCoeffs,
            writeExtrinsics, writePoints))
            mode = CALIBRATED;
        else
            mode = DETECTION;
        if (!capture.isOpened())
            break;
    }
}
//显示畸变矫正之后的参数
if (!capture.isOpened() && showUndistorted)
{
    Mat view, rview, map1, map2;
    initUndistortRectifyMap(cameraMatrix, distCoeffs, Mat(),
        getOptimalNewCameraMatrix(cameraMatrix, distCoeffs, imageSize, 1, imageSize, 0),
        imageSize, CV_16SC2, map1, map2);

    for (i = 0; i < (int)imageList.size(); i++)
    {
        view = imread(imageList[i], 1);
        if (view.empty())
            continue;
        //undistort( view, rview, cameraMatrix, distCoeffs, cameraMatrix );
        remap(view, rview, map1, map2, INTER_LINEAR);
        imshow("Image View", rview);
        int c = 0xff & waitKey();
        if ((c & 255) == 27 || c == 'q' || c == 'Q')
            break;
    }
}
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值