畸变矫正、透视变换加速(OpenCV C++)

前两周,同事和我说检测时间超时,其中对图像做畸变矫正和投影变换就要花费25ms(3000×3000的图)。而此时我们已经用上了文章opencv图像畸变矫正加速、透视变换加速方法总结中的方法。突然我想到了我去年笔记OpenCV笔记(10) 相机模型与标定中的一个函数cv::undistortPoints(),对感兴趣点进行畸变矫正。在应用之前,需要测试下两种方法计算出来的点的差值,即remap和undistortPoints的不同。结论:对全图进行畸变矫正,再找点 VS 找点后,对点进行畸变矫正,两者的差值小于0.1个像素,可行!同样的方法可以运用在投影变换上。在尺寸测量方面,这样可以节省掉畸变矫正和投影变换的时间。

1 只对感兴趣的点进行畸变矫正

// 读取相机参数文件
FileStorage fs("D:/distortionLens.xml", FileStorage::READ);
Mat intrinsic_matrix = Mat(3, 3, CV_32FC1, Scalar::all(0));
Mat distortion_coeffs = Mat(1, 5, CV_32FC1, Scalar::all(0));
fs["intrinsic_matrix"] >> intrinsic_matrix;
fs["distortion_coeffs"] >> distortion_coeffs;
Mat mapx = Mat(s, CV_32FC1);
Mat mapy = Mat(s, CV_32FC1);
// 根据内参和畸变系数,建立查找表
//intrinsic_matrix = getOptimalNewCameraMatrix(intrinsic_matrix, distortion_coeffs, s, 1, s, 0);
initUndistortRectifyMap(intrinsic_matrix, distortion_coeffs, Mat(),
intrinsic_matrix, s, CV_32FC1, mapx, mapy);
// 方法1:畸变矫正后找角点
Mat distortionMat;
remap(src, distortionMat, mapx, mapy, INTER_CUBIC);
vector distortPoints;
findChessboardCornersSB(src, Size(21, 21), distortPoints, 64);
// 方法2:找角点后畸变矫正
vector oriPoints, sparsePoints;
findChessboardCornersSB(src, Size(21, 21), oriPoints, 64);
undistortPoints(oriPoints, sparsePoints, intrinsic_matrix, distortion_coeffs, Mat(), intrinsic_matrix);
// 打印比较
cout 

部分数据如下所示,可以看出,两者差值小于0.1个像素,加速10ms完成,接下来再对投影变换加速一下。

畸变矫正、透视变换加速(OpenCV C++)插图

2 只对感兴趣的点进行投影变换

// 读取变换矩阵
fs = FileStorage("D:/transMat.txt", FileStorage::READ);
Mat transMat = Mat(3, 3, CV_32FC1, Scalar::all(0));
fs["transMat"] >> transMat;

// 方法1:进行透视变换后找角点
Mat warpMat;
warpPerspective(src, warpMat, transMat, s, INTER_LINEAR, BORDER_CONSTANT, Scalar(255));
vector warpPoints;
findChessboardCornersSB(warpMat,Size(21, 21), warpPoints, 64);
// 方法2:找角点后进行透视变换
vector outPoints;
for (int i = 0; i  oriPoint(3, 1);
    oriPoint(0, 0) = oriPoints[i].x;
    oriPoint(1, 0) = oriPoints[i].y;
    oriPoint(2, 0) = 1;
    Mat dstPoints = transMat * oriPoint;
    double a1 = dstPoints.at(0, 0);
    double a2 = dstPoints.at(1, 0);
    double a3 = dstPoints.at(2, 0);
    outPoints.push_back(Point2f(a1 * 1.0 / a3, a2 * 1.0 / a3));
}
//打印 cout

 畸变矫正、透视变换加速(OpenCV C++)插图1

3 合并

3.1 读取文件

void GetMap()
{
    FileStorage fs(path+"distortionLens.xml", FileStorage::READ);
    if (fs.isOpened())
    {
        intrinsic_matrix = Mat(3, 3, CV_64FC1, Scalar::all(0));
        distortion_coeffs = Mat(1, 5, CV_64FC1, Scalar::all(0));
        fs["intrinsic_matrix"] >> intrinsic_matrix;
        fs["distortion_coeffs"] >> distortion_coeffs;
    }
    fs = FileStorage(path+"transMat.txt", FileStorage::READ);
    if (fs.isOpened())
    {
        transMat = Mat(3, 3, CV_64FC1, Scalar::all(0));
        fs["transMat"] >> transMat;
    }
}

3.2 变换感兴趣点

void remapPoints(vector& points) {
    for (int i = 0; i  oriPoint(3, 1);
        oriPoint(0, 0) = points[i].x;
        oriPoint(1, 0) = points[i].y;
        oriPoint(2, 0) = 1;
        Mat dstPoint = transMat * oriPoint;
        double a1 = dstPoint.at(0, 0);
        double a2 = dstPoint.at(1, 0);
        double a3 = dstPoint.at(2, 0);
        points[i] = Point2f(a1 * 1.0 / a3, a2 * 1.0 / a3);
    }
    undistortPoints(points, points, intrinsic_matrix, distortion_coeffs, Mat(), intrinsic_matrix);

}

 

文章来源于互联网:畸变矫正、透视变换加速(OpenCV C++)

THE END
分享
二维码