C ++最有效的方式来表示网格图中的相机覆盖区域

时间:2019-02-21 14:48:14

标签: c++ arrays camera 2d

我目前正在研究一个机器人正在穿越一个以nxn网格图(例如100x100,但将来会更大)表示的环境的项目。作为2D-array中的ints。用相机观察该区域。机器人知道哪个摄像机覆盖了哪个区域,并能够从稍微超过摄像机FOV范围的范围远程停用摄像机。它必须提出一个计划,以使环境不受注意。

现在,我需要知道哪个摄像机捕获了哪个区域。为了简单起见,我们假设所有摄像机都具有圆形FOV。现在,如果camera 1捕获了某个区域,尽管我要在数组的该区域中放置一个1。到目前为止,一切都很好。但是,如果有第二台(也许是第三台)摄像机的视野重叠呢?我将如何在网格图中表示这种重叠?

到目前为止我的想法:

  • 在网格中添加摄像机ID-例如如果camera 1覆盖了某个FOV,则用1's填充它。如果camera 2的FOV重叠,请用1+2=3填充重叠区域。缺点:n台摄像机的可能性是指数级的,并且很难追溯数字的计算方式-例如,6可能camera 5camera 1重叠,但也{{1} }与camera 2重叠。
  • 将相机ID串联在网格中-对于camera 4cam 1的重叠部分,将cam 2放入网格中。对于12的重叠,将cam 1,2 and 3放在网格中。优点:仅整数运算,应该很快。缺点:只有尽可能多的摄像机(整数范围内有数字)(123的{​​{1}}是int_max,因此最多10台摄像机)

有什么帮助或想法吗?甚至解决这类问题的文献或算法?编程语言将为C ++。

1 个答案:

答案 0 :(得分:2)

您可以在int内为每个特定摄像机使用一位。但是,如果处理单个位,则最好使用unsigned int:假设是32位int,由于有符号整数溢出,1 << 31会导致未定义的行为,因此您必须少使用一位,或者对摄像机ID 31(假设从零开始的ID)有一些特殊处理:

unsigned int field;

// setting the bit for camera ID n (zero based):
field |= 1U << n;

// clearing the bit for camera ID n (zero based):
field &= ~(1U << n);

// reading the bit:
bool isSet = (field & ~(1U << n)) != 0;

(当然,您可以将其打包到适当的(内联?)函数中...)

这样,您可以管理CHAR_BIT * sizeof(unsigned int)个摄像机。在大多数现代系统上,这将是32台摄像机,但这取决于编译器/体系结构!根据该标准,保证unsigned int能够保存0到65535之间的值,因此,为了便于移植,您只能依赖16位(long这样可以确保32位,但可以更大) ,例如64位linux上的64位)。如果要确保可用的特定位数,建议使用<cstdint>标头中的数据类型,例如e。 G。 uint32_t(为确保字面量1U具有适当的范围,您应该强制转换:static_cast<uint32_t>(1U)或定义适当类型的常量)。

位处理需要花费一些额外的操作,但是这些操作可以忽略不计(除了一些非常罕见的 extreme 性能场景;在15年以上的专业经验中仅一次遇到过这样的操作...)。

请注意:您可能会发现位域隐藏了摆弄您的位。好吧,可以肯定的是,它们确实可以(但是仍然存在,只是编译器为您完成了工作)。但是它们还有其他缺点(最重要的是:不能保证成员在不同系统上的顺序是相同的,因此如果将它们序列化为TCP或文件,则需要注意!),我个人宁愿避免他们。还是:

struct Field
{
    uint32_t  _0 : 1;
    uint32_t  _1 : 1;
    // ...
    uint32_t _31 : 1;
};