开源代码位于:GitHub - Shelfcol/livox_camera_lidar_calibration_modified: livox_camera_lidar_calibration
功能:给定一个文件夹,遍历里面的所有图片,每张图片鼠标左键按顺序点击标定板角点,右键结束点击。
1. 读取指定文件夹内的所有图片
// 遍历path下面的所有文件,保存在filenames里面
void GetFileNames(string path,vector<string>& filenames)
{
DIR *pDir;
struct dirent* ptr;
if(!(pDir = opendir(path.c_str()))){
std::cerr<<path<<" open failed"<<std::endl;
return;
}
while((ptr = readdir(pDir))!=0) {
if (strcmp(ptr->d_name, ".") != 0 && strcmp(ptr->d_name, "..") != 0)
filenames.push_back(path + "/" + ptr->d_name);
}
// for_each(filenames.begin(),filenames.end(),[&](auto a){
// printf("%s\n",a.c_str());
// });
closedir(pDir);
}
1. 图片去畸变
cv::Mat view, rview, map1, map2;
cv::Size imageSize = src_img.size();
cv::initUndistortRectifyMap(cameraMatrix, distCoeffs, cv::Mat(),cv::getOptimalNewCameraMatrix(cameraMatrix, distCoeffs, imageSize, 1, imageSize, 0), imageSize, CV_16SC2, map1, map2);
cv::remap(src_img, src_img, map1, map2, cv::INTER_LINEAR); // correct the distortion
2.鼠标点击获取角点像素坐标
原本的代码需要手动在终端输入获取到的角点坐标,这里进行改进。
从左下角点开始顺时针鼠标左键点击,鼠标右键点击结束。
主要使用了setMouseCallback("source",OnMouse,&src_img);函数
void OnMouse(int EVENT, int x, int y, int flags, void* userdata)
{
cv::Mat hh = *(cv::Mat*)userdata;
cv::Point p(x,y);
switch(EVENT)
{
case cv::EVENT_LBUTTONDOWN:
{
// printf("b=%d\t", hh.at<cv::Vec3b>(p)[0]);
// printf("g=%d\t", hh.at<cv::Vec3b>(p)[1]);
// printf("r=%d\n", hh.at<cv::Vec3b>(p)[2]);
printf("pixel (%d,%d)\n",x,y);
corners.push_back(cv::Point2f(x,y));
cv::circle(hh, p, 2, cv::Scalar(255),3);
break;
}
case cv::EVENT_RBUTTONDOWN: // 结束坐标获取
{
end_mouse = 1;
printf("end mouse\n");
break;
}
}
}
int main(){
...
cv::namedWindow("source");
setMouseCallback("source",OnMouse,&src_img);
while (!end_mouse)
{
cv::imshow("source", src_img);
cv::waitKey(40);
}
cv::destroyWindow("source");
...
}
3.计算亚像素坐标
cv::cvtColor(src_img, gray_img, cv::COLOR_BGR2GRAY);
cv::cornerSubPix(gray_img, corners, winSize, zerozone, criteria); // 根据角点获取亚像素
4. 写入文件
第一张图片时将结果文件里面数据清空
void writeData(const string filename, const float x, const float y, uint mode) {
ofstream outfile;
static bool write_first = true;
if(write_first){
write_first = false;
outfile = ofstream(filename.c_str(), ios_base::trunc); // 读取并清空文件夹
} else
{
outfile = ofstream(filename.c_str(), ios_base::app); // 追加模式
}
if (!outfile) {
cout << "Can not open the file: " << filename << endl;
exit(0);
}
switch(mode) {
case(0):
outfile << "photo" << endl;
outfile << "1" << endl;
break;
case(1):
outfile << "2" << endl;
break;
case(2):
outfile << "3" << endl;
break;
case(3):
outfile << "4" << endl;
break;
default:
cout << "[writeData] - Code error, unknown mode" << endl;
exit(0);
}
outfile << float2str(x) << " " << float2str(y) << endl;
}
5. 中途效果图
结果数据corner_photo.h
photo
1
689.197 335.045
2
695.334 47.353
3
884.436 45.1674
4
882.443 335.021