qq_37675107 2018-12-20 03:10 采纳率: 0%
浏览 5008

opencv undistort函数里面需要用的畸变系数矩阵的单位应该是什么呢?

我有用halcon标定的相机参数,畸变系数K1,K2,K3,P1,P2,然后用opencv处理同一张照片去畸变的时候,输入进halcon标定得到的参数,无法去除畸变,请问有人遇到过类似情况么,应该如何解决,我看halcon得到的畸变系数都是带单位的,是因为这个的问题么?

  • 写回答

1条回答

  • 亚历山大、 2018-12-19 22:02
    关注

    我用的是opencv2.4.13.2,然后是c++的。
    我已经成功获取了摄像机的内参矩阵,以及畸变矩阵。也已经成功畸变矫正。但是我还希望获取原图中心点undistort之后的对应点。

    前置代码

    这部分代码的作用是畸变矫正。实际上和题目关系不大,而且你们也很容易在网上找到(当然是有不少错误的版本)。不过我还是放上来:

    Mat cameraMatrix = Mat::eye(3, 3, CV_64F);
    //内参矩阵, 就算复制代码,也不要用我的参数。摄像头都不一样...
    cameraMatrix.at<double>(0, 0) = 2.075319928848340e+03;
    cameraMatrix.at<double>(0, 1) = 0;
    cameraMatrix.at<double>(0, 2) = 1.273350420020438e+03;
    cameraMatrix.at<double>(1, 1) = 2.073416138777327e+03;
    cameraMatrix.at<double>(1, 2) = 6.898818022397845e+02;
    //畸变参数,不要用我的参数~
    Mat distCoeffs = Mat::zeros(5, 1, CV_64F);
    distCoeffs.at<double>(0, 0) = 0.005961692158170;
    distCoeffs.at<double>(1, 0) = 0.014892085926656;
    distCoeffs.at<double>(2, 0) = -0.007714274148788;
    distCoeffs.at<double>(3, 0) = -0.010548832296675;
    distCoeffs.at<double>(4, 0) = 0;
    Mat view, rview, map1, map2;
    Size imageSize;
    imageSize = image.size();
    initUndistortRectifyMap(cameraMatrix, distCoeffs, Mat(),
    

    getOptimalNewCameraMatrix(cameraMatrix, distCoeffs, imageSize, 1, imageSize, 0),
    imageSize, CV_16SC2, map1, map2);
    remap(image, image, map1, map2, INTER_LINEAR);
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    那么,在remap函数之后,image就是我们畸变矫正的结果了。

    Attempt1:undistortPoints

    首先,我在网上一搜,这个函数就冒了出来。undistortPoints, 矫正后的点,emmmmmmm,看起来很美。从结果来说,实际上是坑爹的。

    std::vector obj_corners(1);
    obj_corners[0] = Point2d((double)input_center_point.x,(double)input_center_point.y);
    std::vector scene_corners(1);
    //obj_corners:输入
    //scene_corners:输出
    undistortPoints(obj_corners,scene_corners,cameraMatrix,distCoeffs);
    1
    2
    3
    4
    5
    6
    结果怎么这么小?

    11-24 23:03:38.971 9133-9410/? I/MyCV: scene_corners width is 0.034107
    11-24 23:03:38.971 9133-9410/? I/MyCV: scene_corners height is 0.031944
    1
    2
    实际上,在得到结果之后,还要有一步:

    //Focus_length: 焦距,分fx和fy的。看不懂的同学请从头学习内参矩阵或者考虑换个导师或者科研题目
    //Principle_Point.x:主点坐标,也是内参矩阵的一部分,同上
    //scene_corners[0]: 上面undistortPoints函数的输出
    result_point.x = scene_corners[0].x*Focus_length.x+Principle_Point.x;
    result_point.y = scene_corners[0].y*Focus_length.y+Principle_Point.y;
    1
    2
    3
    4
    5
    这样,就能够算出结果。
    我自己的输入是:(1344,756),而我的输出是:

    11-24 23:03:38.971 9133-9410/? I/MyCV: result width is 1344.132696
    11-24 23:03:38.971 9133-9410/? I/MyCV: result height is 756.114362
    1
    2
    根本没多大变化啊?!
    所以,就如我在开头说的,这个是坑爹的…它应该有其他作用,但是并不能解决我现在的问题。

    attempt2:initUndistortRectifyMap()的map

    然后我又查查找找,最终找到下面两个:
    https://stackoverflow.com/questions/34265650/can-i-get-the-point-position-using-remap-in-opencv
    https://stackoverflow.com/questions/22323410/opencvremap-how-to-remap-an-image-to-another-image-with-different-size
    它们都说的是什么呢?两个说了一件事:那就是通过initUndistortRectifyMap函数:

    initUndistortRectifyMap(cameraMatrix, distCoeffs, Mat(),
    getOptimalNewCameraMatrix(cameraMatrix, distCoeffs, imageSize, 1, imageSize, 0),
    imageSize, CV_16SC2, map1, map2);
    1
    2
    3
    返回的map1,map2来直接获得undistort之后的对应点。
    于是我就试试试,这个怎么样?

    map1.at(row,col)
    map2.at(row,col)
    1
    2
    这个又怎么样?

    map1.at(row,col)
    map2.at(row,col)
    1
    2
    具体结果我忘了,但是都明显不对。原因是map1,和map2的格式早就由initUndistortRectifyMap函数决定了。仔细看看其中的参数,CV_16SC2定义了map1的格式。map2的type我打出来是:

    11-24 23:03:37.687 9133-9426/? I/MyCV: map2 16UC1
    1
    于是我根据这里的type和mat格式的对应关系又试了这个:

    map1.at(row,col)
    map2.at(row,col)
    1
    2

    结果还是不对。

    作者:夜风皓月改
    来源:CSDN
    原文:https://blog.csdn.net/qq_20289205/article/details/78632542
    版权声明:本文为博主原创文章,转载请附上博文链接!

    评论

报告相同问题?

悬赏问题

  • ¥15 计算二重积分∫∫e^(x+y)dxdy,其中0≤x≤1,0≤y≤1,试分别用复合辛普森公式(取n=4)以及高斯求积公式(取n=4)计算积分 给出matlab程序
  • ¥15 opencv 无法读取视频
  • ¥15 用matlab 实现通信仿真
  • ¥15 按键修改电子时钟,C51单片机
  • ¥60 Java中实现如何实现张量类,并用于图像处理(不运用其他科学计算库和图像处理库))
  • ¥20 5037端口被adb自己占了
  • ¥15 python:excel数据写入多个对应word文档
  • ¥60 全一数分解素因子和素数循环节位数
  • ¥15 ffmpeg如何安装到虚拟环境
  • ¥188 寻找能做王者评分提取的