根据与相机的距离缩放AR图像

时间:2012-08-11 08:59:31

标签: iphone camera scaling augmented-reality

我正在开发增强现实 iPhone应用。

当您通过相机查看时,它应该基本上显示分配到地理位置的图片。每个这样的图片可以被理解为具有其地理位置和标题(被理解为其平面和北方向轴之间的角度)的广告牌。

目标是使这些广告牌或多或少地显示为物理对象。如果你靠近它们它们应该更大,而当它们更远时它们应该更小。当你不直接站在他们面前时,他们也应该以正确的视角出现。

我认为我或多或少地实现了这个目标。 通过测量从iPhone到照片的初始标题,我可以决定照相机查看照片的旋转角度(以正确的视角查看)。

然而,如果要根据手机的距离来缩放它们,我想我搞砸了我的方法。我假设最大视图距离是200米。然后距离手机100米的广告牌以其原始尺寸的50%显示。而已。基于最大距离的线性缩放。

这种方法我错过的是广告牌的大小(理解为物理对象)。它们在屏幕上显示的方式取决于它们的大小(仅以像素为单位)。这意味着显示器的分辨率是决定您如何感知它们的因素。所以我假设如果你有两部手机具有相同的屏幕尺寸但分辨率不同,那么相同的图片在两者上都会有不同的尺寸。我是对的吗?

最后,我的问题是如何处理缩放图片以使其在AR视图中看起来很好?

我想我应该考虑一些相机参数。当一个10x10厘米的物体就在相机前面时,它可能会覆盖整个屏幕。但是当你把它放得更远几米时,它就变成了一个小细节。那么如何进行缩放?如果我决定将物理尺寸分配给我的虚拟广告牌,那么如何根据与相机的距离来缩放它们呢?

我是否应该为每张照片指定以米为单位的物理尺寸(无论它们的像素大小是多少),并根据尺寸和相机相关比例因子显示它们? < / p> 你可以帮我解决一下吗?任何线索都会有所帮助。谢谢!

1 个答案:

答案 0 :(得分:2)

我想我设法解决了我的问题。让我解释一下我是如何做到的,如果对其他人有用的话。 如果您发现此方法有误,我将非常感谢您的反馈或任何进一步的线索。

我决定将物理尺寸以米为单位分配给我的虚拟广告牌。 This discussion帮助我找出iPhone 4相机的参数:焦距和尺寸CCD sesnor 。更重要的是,这些值还帮助我计算了我的AR应用程序的正确FOV(参见Calculating a camera's angle of view)。

This website帮我计算了CCD传感器上生成的物理图像的毫米大小。因此,如果我的广告牌有宽度和高度(以米为单位)并且它们与相机的距离以及相机的焦距,我可以在传感器上计算它们的大小。

  

(焦距*物体尺寸)/镜头到物体距离=图像尺寸(在传感器上)

double CalculatePhysicalObjectImageDimensionOnCCD(double cameraFocalLength_mm, double physicalObjectDimension_m, double distanceFromPhysicalObject_m)
{
    double physicalObjectDimension_mm = physicalObjectDimension_m * 1000;
    double distanceFromPhysicalObject_mm = distanceFromPhysicalObject_m * 1000;
    return (cameraFocalLength_mm * physicalObjectDimension_mm) / distanceFromPhysicalObject_mm;
}

我对这件事知之甚少,所以我不确定我采用的方法是否合适,但我决定计算iPhone屏幕与CCD传感器的尺寸相比有多大。因此,通过简单的数学运算,我得到了传感器到屏幕的尺寸比。由于传感器和屏幕的宽高比似乎不同,我以一种胡思乱想的方式计算了比例:

double GetCCDToScreenSizeRatio(double sensorWidth, double sensorHeight, double screenWidth, double screenHeight)
{
    return sqrt(screenWidth * screenHeight) / sqrt(sensorWidth * sensorHeight);
}

然后我得到的比率可以被视为乘数。首先,我计算传感器上虚拟广告牌的尺寸,然后乘以比率。这样我就得到了广告牌的实际大小(以像素为单位)。而已。因此,当我通过提供广告牌的宽度及其距离来调用下面的函数时,它会返回屏幕上显示的广告牌的宽度(以像素为单位)。广告牌的高度相同,以获得两个尺寸。

const double CCD_DIM_LONGER_IPHONE4 = 4.592; //mm
const double CCD_DIM_SHORTER_IPHONE4 = 3.450; //mm
const double FOCAL_LENGTH_IPHONE4 = 4.28; //mm

double CalculatePhysicalObjectImageDimensionOnScreen_iPhone4(double physicalObjectDimension_m, double distanceFromPhysicalObject_m)
{
    double screenWidth = [UIScreen mainScreen].bounds.size.width;
    double screenHeight = [UIScreen mainScreen].bounds.size.height;

    return CalculatePhysicalObjectImageDimensionOnScreen(FOCAL_LENGTH_IPHONE4, physicalObjectDimension_m, distanceFromPhysicalObject_m, CCD_DIM_LONGER_IPHONE4, CCD_DIM_SHORTER_IPHONE4, screenWidth, screenHeight);
}

double CalculatePhysicalObjectImageDimensionOnScreen(double cameraFocalLength_mm, double physicalObjectDimension_m, double distanceFromPhysicalObject_m, double ccdSensorWidth, double ccdSensorHeight, double screenWidth, double screenHeight)
{
    double ccdToScreenSizeRatio = GetCCDToScreenSizeRatio(ccdSensorWidth, ccdSensorHeight, screenWidth, screenHeight);
    double dimensionOnCcd = CalculatePhysicalObjectImageDimensionOnCCD(cameraFocalLength_mm, physicalObjectDimension_m, distanceFromPhysicalObject_m);

    return dimensionOnCcd * ccdToScreenSizeRatio;
}

与以前的愚蠢的线性缩放方法相比,它似乎完美无缺。顺便说一句,我还注意到,在AR视图上注册虚拟对象时,了解相机的FOV非常重要。 Here’s如何根据CCD传感器尺寸和焦距计算FOV。

在任何地方找到这些值都很困难!我想知道为什么他们不能以编程方式访问(至少我的研究告诉我他们不是)。似乎有必要准备硬编码值,然后检查应用程序运行的设备的模型,以决定在执行上述所有计算时选择哪个值: - /。