c++ - 他们如何将 IR-Lock 像素转换到镜头前 1 米的法平面上的位置

标签 c++ math image-processing

我正在使用四轴飞行器跟踪移动目标。在我的项目中,我使用的是红外相机,它是 Pixy 相机的修改版本,但用于检测红外目标。在研究他们的代码时,我发现了一个我无法理解的部分。我试着用谷歌搜索但没有找到任何相关的东西或任何公式。所以我想知道是否有人可以给我一些关于他们使用的方程式或公式的提示。

这是我不明白的部分。

/*
converts IRLOCK pixels to a position on a normal plane 1m in front of the lens based 
on a characterization of IR-LOCK with the standard lens, focused such that 2.38mm 
of threads are exposed 
*/
void AP_IRLock_I2C::pixel_to_1M_plane(float pix_x, float pix_y, float &ret_x, float &ret_y)
{
ret_x = (-0.00293875727162397f*pix_x + 0.470201163459835f)/
(4.43013552642296e-6f*((pix_x - 160.0f)*(pix_x - 160.0f)) 
+ 4.79331390531725e-6f*((pix_y - 100.0f)*(pix_y - 100.0f)) - 1.0f);
ret_y = (-0.003056843086277f*pix_y + 0.3056843086277f)/
(4.43013552642296e-6f*((pix_x - 160.0f)*(pix_x - 160.0f)) 
+ 4.79331390531725e-6f*((pix_y - 100.0f)*(pix_y - 100.0f)) - 1.0f);

您可以在此处找到其余代码。 IRlock Ardupilot

最佳答案

让我们关注 ret_x 的等式,简化后如下:

ret_x = (-0.0029 * pix_x + 0.47) /
        (4.4e-6 * (pix_x - 160.0)^2 + 4.8e-6 * (pix_y - 100.0)^2 - 1.0);

首先,请注意 160 和 100 魔数(Magic Number)。 Pixy 捕获分辨率为 320x200,因此这些用于将像素坐标从 (0,0) 位于角落的空间转换到它位于中心的位置。因此,如果 pix_x 为 160 且 pix_y 为 100,则它是框架的中心,分母将为 -1。

其余部分似乎是镜头校正。以下是您在有效 pix_xpix_y 输入范围内获得的 ret_x 值:

        0      40      80     120    160     200     240     280     320
  0 -0.56   -0.40   -0.25   -0.12   0.00    0.12    0.25    0.40    0.56
 20 -0.55   -0.39   -0.25   -0.12   0.00    0.12    0.25    0.39    0.55
 40 -0.54   -0.38   -0.25   -0.12   0.00    0.12    0.25    0.38    0.54
 60 -0.53   -0.38   -0.24   -0.12   0.00    0.12    0.24    0.38    0.53
 80 -0.53   -0.38   -0.24   -0.12   0.00    0.12    0.24    0.38    0.53
100 -0.53   -0.38   -0.24   -0.12   0.00    0.12    0.24    0.38    0.53
120 -0.53   -0.38   -0.24   -0.12   0.00    0.12    0.24    0.38    0.53
140 -0.53   -0.38   -0.24   -0.12   0.00    0.12    0.24    0.38    0.53
160 -0.54   -0.38   -0.25   -0.12   0.00    0.12    0.25    0.38    0.54
180 -0.55   -0.39   -0.25   -0.12   0.00    0.12    0.25    0.39    0.55
200 -0.56   -0.40   -0.25   -0.12   0.00    0.12    0.25    0.40    0.56

正如预期的那样,对于中心附近的像素,ret_x 接近 0 (pix_x == 160)。它在极值处达到 +/- 0.56,这表明水平视野约为 120 度(根据三角学,1 米距离处的宽度为 2*0.56 米)。

水平校正受垂直坐标的轻微影响,尤其是在角落附近。这大概是为了校正镜头中的球面畸变(这很常见)。

精明的人会发现方程有一点缺陷:给定 [0,319] 和 [0,199] 中的像素坐标,中心值应该是 159.5 和 99.5,而不是 160 和 100。

关于c++ - 他们如何将 IR-Lock 像素转换到镜头前 1 米的法平面上的位置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52453839/

相关文章:

c++ - Boost记录器静态链接: Not Working

matlab - 来自基本矩阵的 3D 通信

math - 一组给定的群元素是一组陪集代表吗?

matlab - 在 MATLAB 中访问图像中的 RGB channel

c++ - boost::pool 默认 block 数

c++ - MPI_Irecv : Aborting Job 中的 fatal error

c++ - 在 Linux 下执行外部命令并等待它完成

javascript - 如何计算 div 元素的旋转 Angular ?

reactjs - 下一个js图像组件错误 "url"参数有效但上游响应无效

Java Servlet 框架,可以执行将图像重新编码为首选格式等操作