3

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

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

4

5 回答 5

8

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

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

于 2017-01-16T07:49:54.713 回答
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]));
    }
}

您可以使用此方位角在 cameraview 中绘制位置

    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 将给出目标位置的坐标。

于 2015-07-24T09:50:48.373 回答
0

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

于 2013-03-31T21:19:45.607 回答
0

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

于 2013-04-03T07:54:26.157 回答
0

这个问题有两个方向,设备和目标。

设备方位角如下图:

方位角

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

目标方位角如下所示:

在此处输入图像描述

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

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

wheretlattlon表示目标 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;
    }   

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

希望这些有所帮助。

于 2013-06-19T09:21:29.237 回答