本文是在阅读opencv sample 所做的笔记。
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_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 位平台不允许的。
calib3d moudle in opencv 包含了很多用来标定用的函数。
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.
if (argc < 2)
{
help();
return 0;
}
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 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;
}
}