做网站给韩国卖高仿,wordpress 图片路径加密,学科网站建设标准,苏州网站建设书生商友背景#xff1a;最近的项目中用到的图像去畸变的知识#xff0c;刚开始是直接调用opencv中提供的函数cv::initUndistortRectifyMap()和cv::remap()函数#xff0c;实现图像的全局去畸变#xff0c;但是由于图像的分辨率很高#xff0c;再加上#xff0c;实际过程中我们只…背景最近的项目中用到的图像去畸变的知识刚开始是直接调用opencv中提供的函数cv::initUndistortRectifyMap()和cv::remap()函数实现图像的全局去畸变但是由于图像的分辨率很高再加上实际过程中我们只用到了很小一块的图像所以为了降低电脑的负担则想选用局部图像去畸变的方法来代替全局图像去畸变。
于是我想到了《SLAM十四讲》书中在相机模型中有相关的去畸变的代码我就直接使用测试了效果还不错。
void LocalZoneUndistortion(cv::Mat localImage, cv::Mat undistortLocalImage) {undistortLocalImage cv::Mat(localImage.rows, localImage.cols, CV_8UC1);for (int row 0; row localImage.rows; row) {for (int col 0; col localImage.cols; col) {double x (col - cx_) / fx_;double y (row - cy_) / fy_;double r sqrt(x * x y * y);double xDistorted x * (1 k1_ * r * r k2_ * r * r * r * r) 2 * p1_* x * y p2_ * (r * r 2 * x * x);double yDistorted y * (1 k1_ * r * r k2_ * r * r * r * r) p1_ * (r * r 2 * y * y) 2 * p2_* x * y;double uDistorted fx_ * xDistorted cx_;double vDistorted fy_ * yDistorted cy_;if (uDistorted 0 vDistorted 0 uDistorted localImage.cols vDistorted localImage.rows) {undistortLocalImage.atuchar(row, col) localImage.atuchar((int)vDistorted,(int)uDistorted);}else {undistortLocalImage.atuchar(row, col) 0;} }}}
当然在使用的时候要把相机内参和畸变系数传进去呦我这里是把它们定义为成员变量就没有传进去。其实我之前一直对这个去畸变的过程很困惑的这明明是一个添加畸变的过程为啥可以达到去畸变的效果呢时隔多日之后再次使用这个函数其实我还是没怎么关心她背后的逻辑直到我同时又需要完成对点添加畸变的任务这个时候我才重新审视这两个过程背后的逻辑。
添加畸变的函数如下
void Tracking::DistortPoints(cv::Point2f undistPoint, cv::Point2f distPoint) {double x (undistPoint.x - cx_) / fx_;double y (undistPoint.y - cy_) / fy_;double r2 x * x y * y;// Radial distorsiondouble xDistort x * (1 k1_ * r2 k2_ * r2 * r2 k3_ * r2 * r2 * r2);double yDistort y * (1 k1_ * r2 k2_ * r2 * r2 k3_ * r2 * r2 * r2);// Tangential distorsionxDistort xDistort (2 * p1_ * x * y p2_ * (r2 2 * x * x));yDistort yDistort (p1_ * (r2 2 * y * y) 2 * p2_ * x * y);// Back to absolute coordinates.xDistort xDistort * fx_ cx_;yDistort yDistort * fy_ cy_;distPoint cv::Point2f((float)xDistort, (float)yDistort);};
我们平时遇到的都是将带有畸变的点转换为不带畸变的点很少会遇到在不带畸变的点上添加畸变因为我要在一个带有畸变的图像上标注一个不带畸变的点那标注出的位置和我们真正的目标之间就有一定的偏差了这个时候只有在这些不带畸变的点上添加上畸变这样才能适应带有畸变的图像。
我们可以发现上面两个过程去畸变和添加畸变刚开始的部分都是在添加畸变的过程
首先是将像素位置点从像平面内转换到归一化平面内
double x (col - cx_) / fx_;
double y (row - cy_) / fy_;
double x (undistPoint.x - cx_) / fx_;
double y (undistPoint.y - cy_) / fy_;
然后再分别添加径向畸变和切向畸变
// Radial distorsion
double xDistort x * (1 k1_ * r2 k2_ * r2 * r2 k3_ * r2 * r2 * r2);
double yDistort y * (1 k1_ * r2 k2_ * r2 * r2 k3_ * r2 * r2 * r2);// Tangential distorsion
xDistort xDistort (2 * p1_ * x * y p2_ * (r2 2 * x * x));
yDistort yDistort (p1_ * (r2 2 * y * y) 2 * p2_ * x * y);
然后在把点转换到像平面内。
// Back to absolute coordinates.
xDistort xDistort * fx_ cx_;
yDistort yDistort * fy_ cy_;
以上这些步骤两个过程是一样的最后一步是不一样的。
在去畸变过程中我们相当于给不带畸变的坐标PointA添加畸变得到带有畸变的点PointB而这正是我们直接获取得到的带有畸变的图像I上的点这个时候我们可以将带有畸变的图像上的PointB位置处的灰度值映射赋值给PointA的位置处这样操作图像I上所有有效点就完成了对带有畸变的图像I的去畸变操作。
if (uDistorted 0 vDistorted 0 uDistorted localImage.cols vDistorted localImage.rows) {undistortLocalImage.atuchar(row, col) localImage.atuchar((int)vDistorted,(int)uDistorted);
} else {undistortLocalImage.atuchar(row, col) 0;
}
而添加畸变的过程就比较好理解了就是给不带有畸变的点添加上径向畸变和切向畸变直接得到带畸变的点。