【问题标题】:location based augmented reality android application基于位置的增强现实安卓应用
【发布时间】:2013-03-31 21:14:00
【问题描述】:

我正在开发基于实时位置的增强现实安卓应用程序。 这是一个简单的概念:我的应用程序应该显示我周围的一些地方。我有 对此进行了深入研究,但我仍然遇到问题。我有我的 GPS 坐标 以及目标地点的 GPS 坐标。

我的问题是:如何检索手机摄像头正在查看的内容(例如建筑物)? 解决此类问题的合乎逻辑的方法是什么?

【问题讨论】:

    标签: android augmented-reality


    【解决方案1】:

    增强现实将真实坐标系转移到相机坐标系。在 AR Location-based 中,真实坐标是地理坐标系。我们将 GPS 坐标(纬度、经度、海拔)转换为导航坐标(东、北、上),然后将导航坐标转换为相机坐标并显示在相机视图上。

    我只是为你创建了演示: https://github.com/dat-ng/ar-location-based-android

    【讨论】:

    • 您好,我刚刚导入了您的项目,并在您的位置放置了 mu 坐标。但它没有给出正确的方向。我不知道什么是高度,所以我将它们保留为 0. add(new ARPoint("lirctek", 12.9693, 77.7357, 0)); add(new ARPoint("amrita heights", 12.9703, 77.7354, 0));
    • 如果您设置高度为0,您可能会在手机上得到错误的位置。我猜你的观点在底部。您可以使用 Google Elevation API 获取地球上特定位置的海拔高度
    • 谢谢@Dat 让我试试 :)
    • @DatNguyen 我已经使用了你的演示。我想显示用户位置附近的所有地方。但问题是所有地方都彼此靠近并且彼此碰撞。如何在没有任何冲突的情况下将视图堆叠在一起。
    • 额外提示:谷歌海拔 API 的免费替代品是 api.open-elevation.com/api/v1/lookup?locations=lat,lng
    【解决方案2】:

    首先检查设备中传感器的可用性。如果设备支持 TYPE_ROTATION_VECTOR,则为相同注册一个传感器侦听器,否则检查 TYPE_MAGNETIC_FIELD 和 TYPE_ACCELEROMETER。

    SensorManager mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
    rSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ROTATION_VECTOR);
    if (rSensor == null) {
        mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);
        aSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
    }
    

    然后在 onSensorChanged 函数中计算方位角。

        if (rSensor == null) {
        switch (event.sensor.getType()) {
            case Sensor.TYPE_MAGNETIC_FIELD:
                magnetic = event.values.clone();
                break;
            case Sensor.TYPE_ACCELEROMETER:
                accelerometer = event.values.clone();
                break;
        }
    
        if (magnetic != null && accelerometer != null) {
            Rot = new float[9];
            I = new float[9];
            SensorManager.getRotationMatrix(Rot, I, accelerometer, magnetic);
    
            float[] outR = new float[9];
            SensorManager.remapCoordinateSystem(Rot, SensorManager.AXIS_X,
                    SensorManager.AXIS_Z, outR);
            SensorManager.getOrientation(outR, values);
    
            azimuth = values[0];
            magnetic = null;
            accelerometer = null;
        }
    } else {
        SensorManager.getRotationMatrixFromVector(mRotationMatrix, event.values);
        SensorManager.getOrientation(mRotationMatrix, mValues);
    
        azimuth = Math.toDegrees(mValues[0]));
        }
    }
    

    您可以使用此方位角在相机视图中绘制位置

        double angle = bearing(myLatitude, myLongitude, dLatitude, dLongitude) - azimuth;
    double xAxis, yAxis;
    
    if(angle < 0)
        angle = (angle+360)%360;
    
    xAxis = Math.sin(Math.toRadians(angle)) * dist;
    yAxis = Math.sqrt(Math.pow(dist, 2) - Math.pow(xAxis, 2));
    
    if (angle > 90 && angle < 270)
        yAxis *= -1;
    
    double xAxisPosition = angle * (screenWidth / 90d);
    
    xAxis = xAxisPosition - spotImageWidth/2;
    float x, y;
    if (angle <= 45)
        x = (float) ((screenWidth / 2) + xAxis);
    
    else if (angle >= 315)
        x = (float) ((screenWidth / 2) - ((screenWidth*4) - xAxis));
    
    else
        x = (float) (float)(screenWidth*9);
    
    y = (float)(((screenHeight - 300) - (i * 100)));
    
    protected static double bearing(double lat1, double lon1, double lat2, double lon2) {
        double longDiff = Math.toRadians(lon2 - lon1);
        double la1 = Math.toRadians(lat1);
        double la2 = Math.toRadians(lat2);
        double y = Math.sin(longDiff) * Math.cos(la2);
        double x = Math.cos(la1) * Math.sin(la2) - Math.sin(la1) * Math.cos(la2) * Math.cos(longDiff);
    
        double result = Math.toDegrees(Math.atan2(y, x));
        return (result+360.0d)%360.0d;
    }
    

    x, y 将给出目标位置的坐标。

    【讨论】:

    • 我发现使用方位角很有用..你知道 ARToolKit 吗?如何使用它?
    • @GvSharma 你找到如何使用 ARToolkit 了吗?使用方位角绘制位置时点的稳定程度。
    【解决方案3】:

    您需要的第一步是使用传感器获取后置摄像头的方向。您可以在 http://developer.android.com/reference/android/hardware/SensorManager.html
    阅读有关传感器的更多信息 用传感器完成编码后,回来问下一个问题。

    【讨论】:

    • 事实上我知道如何使用传感器。我得到了像航向、俯仰和滚动这样的传感器值。但我不知道如何使用它们
    • 您需要知道后置摄像头的方向,如果您不知道如何找到它,请使用您的代码发布问题。然后回到这里,我会告诉你下一步是什么。
    • 我不知道如何找到相机的方向。但我读过一些关于方位角的东西。这是相机的方向吗?
    【解决方案4】:

    试试 DroidAR SDK https://github.com/bitstars/droidar 。这是一个适用于 Android 的 AR SDK。你的大部分问题都应该用它来解决。还有视频手册。如果您的项目只需要一些东西,您也可以查看代码。

    【讨论】:

      【解决方案5】:

      本期有两个方向,设备和目标。

      设备方位角如下图:

      这些信息可以由传感器收集。但是,如果设备的方向不固定,你应该做SensorManager.remapCoordinateSystem

      目标方位角如下所示:

      这可能是我在互联网上能找到的最好的数字。 获得设备位置后,可以通过以下方式计算目标位置:

      azi = Math.abs(Math.toDegrees(Math.atan((tlon-lon)/(tlat-lat))));
      

      其中tlattlon 表示目标gps 位置,lat 和lon 是设备位置。 这个等式的值在 -90 到 +90 之间,这不是方位角的真正含义。因此,应该添加 3 个额外的代码。

         if((tlon-lon)>0&&(tlat-lat)<0){
              azi = 180 - azi;
          }
          if((tlon-lon)<0&&(tlat-lat)<0){
              azi = 180 + azi;
          }
          if((tlon-lon)<0&&(tlat-lat)>0){
              azi = 360 - azi;
          }   
      

      这些都完成后,很容易检测目标是否在您的视线范围内。

      希望这些有所帮助。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-10-17
        • 1970-01-01
        • 2012-03-03
        • 2012-03-01
        • 1970-01-01
        • 1970-01-01
        • 2011-09-24
        相关资源
        最近更新 更多