当前位置:   article > 正文

自动驾驶AVM环视算法--鱼眼相机的畸变矫正原理和实测(图片和视频测试)_avm标定算法流程

avm标定算法流程

参考:金书世界

测试工程和视频:

链接:https://pan.baidu.com/s/11GNLuIxcONGCeobp0MbXFQ?pwd=0z6l 提取码:0z6l 

1、平面相机的成像和坐标系如下所示

说明

1、f(ud,vd)就是以图像中心为原点坐标(和p(x,y)坐标相对,就是坐表原点不同)。

2、p(x,y)就是在图像坐标系下的坐标点,坐标点的为图像的左上角点,这个和世界图像的保存数据的坐标一直。

3、假设xy坐标系的原点是uv坐标系的中点,相对的偏移量为cx和cy,就可以得出ud=x+cx,vd=y+cy。

4、P(Xc,Yc,Zc)就是相机坐标系下的坐标。

根据相似的三角形可以得出

AB/COuv=AOc/OcOuv=PB/pC=Xc/ud=Zc/f=Yc/vd

得出

Xc/ud=Zc/fx

Yc/vd=Zc/fy

得出

ud=fx(Xc/Zc)

vd=fy(Yc/Zc)

得出

x=fx(Xc/Zc)-cx

y=fy(Yc/Zc)-cy

2、鱼眼相机的成像坐标变换

参考:https://ww2.mathworks.cn/help/vision/ug/fisheye-calibration-basics.html

由上述的公式可以得出

上述公式中的ud和vd就是平面图像的坐标点,u和v 就是鱼眼图像坐标

根据上述的的计算公式就可以实现图像的畸变矫正

测试代码如下所示

  1. void CjsAVMtoolDlg::OnBnClickedButton1()
  2. {
  3. // TODO: 在此添加控件通知处理程序代码
  4. //MFC弹出命令窗体
  5. AllocConsole();
  6. freopen("CONOUT$", "w", stdout);
  7. //MFC弹出命令窗体
  8. // TODO: 在此添加控件通知处理程序代码
  9. float a[4] = { 160,-0.0005,0,0 };
  10. int cx = 640, cy = 360;//图像的中心点
  11. float fx = 100, fy = 100;//虚拟焦距
  12. float p = 0.0;
  13. Mat src = imread("test.jpg");
  14. Mat dst(src.rows, src.cols, CV_8UC3, Scalar(0, 0, 0));
  15. if (src.empty()) {
  16. printf("不能加载图像!\n");
  17. }
  18. namedWindow("原图", WINDOW_AUTOSIZE);
  19. imshow("原图", src);
  20. //像素读取方式:直接读取
  21. int height = src.rows;
  22. int width = src.cols;
  23. int ch = src.channels();
  24. js_Transplane2Fisheye_V1(&dst, src, a, fx, fy, cx, cy);
  25. //js_Transplane2Fisheye_V2(&dst, src, a, fx, fy, cx, cy);
  26. imshow("直接读取像素图", dst);
  27. }
  28. int js_Transplane2Fisheye_V1(Mat *Dst,Mat Src,float *a,float fx,float fy,int cx,int cy)
  29. {
  30. for (int row = 0; row < Src.rows ; row++) {//h
  31. for (int col = 0; col < Src.cols; col++) {//w
  32. float x1 = ((float)(col - cx));
  33. float y1 = ((float)(row - cy));
  34. float p = sqrtf(x1 * x1 + y1 * y1);
  35. float x2 = x1 / (a[0] + a[1] * p * p + a[2] * p * p * p + a[3] * p * p * p * p);
  36. float y2 = y1 / (a[0] + a[1] * p * p + a[2] * p * p * p + a[3] * p * p * p * p);
  37. int ud = fx * x2 + cx + 0.5;
  38. int vd = fy * y2 + cy + 0.5;
  39. if (((ud >= 0) && (ud < Src.cols)) && ((vd >= 0) && (vd < Src.rows)))
  40. {
  41. Dst->at<Vec3b>(vd, ud) = Src.at<Vec3b>(row, col);
  42. }
  43. }
  44. }
  45. return 0;
  46. }

测试图片和测试结果(测试结果图像存在无效的计算点)

输入图像

校正后图像

由于当前计算是完成算法的畸变矫正存在一定的流程缺陷,以下是升级版本后的测试结果

主要是使用迭代的当时计算

f(x+△x)=f(x)+△x*f‘’(x)

得出

(f(x+△x)-f(x))/f‘’(x)=△x

得出

(f(cur)-f(pre))/f'(pre)=cur-pre

得出

cur=pre+(f(cur)-f(pre))/f‘(pre)

每次计算完成后会更新cur之后将cur幅值给pre继续迭代,知道cur和pre的插值达到阈值后停止迭代或者是计算次数达到阈值后停止,就可以计算出坐标点cur的值。

测试视频

鱼眼相机畸变矫正

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/菜鸟追梦旅行/article/detail/627750
推荐阅读
相关标签
  

闽ICP备14008679号