livox_lidar_camera_calibration学习--图片上像素点的手动提取

开源代码位于: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

猜你喜欢

转载自blog.csdn.net/qq_38650944/article/details/124121952
今日推荐