设备相机方向不包括设备 landscape/portrait 方向

Device camera direction excluding device landscape/portrait orientation

我需要获取前置摄像头的方向,不包括设备方向 (landscape/portrait)。我尝试使用 Core Motion 和访问设备态度来表示这一点。在这里,我尝试访问欧拉角并排除偏航,但这似乎不起作用,因为当旋转设备超过一个欧拉角值变化时。我也在考虑使用方向四元数,但我没有使用它们的经验。我需要以可序列化的方式获取此信息,因为稍后我需要确定不同设备的摄像头是否指向同一方向(该设备可能是 iOS 或 Android)。

重申一下:如果用户将他的 phone 相机(主相机不是自拍相机)指向自由女神像,无论用户是否拿着phone 纵向或横向,如果另一个用户在同一位置,他会知道将相机指向哪个方向?

有4种类型。一个已弃用:

  1. public 静态最终整数 ORIENTATION_UNDEFINED = 0;
  2. public static final int ORIENTATION_PORTRAIT = 1;
  3. public static final int ORIENTATION_LANDSCAPE = 2:
  4. @已弃用 public static final int ORIENTATION_SQUARE = 3;

你可以和

一起学习
val orientation: Int = resources.configuration.orientation

如果您想了解特定的角度和位置,您应该使用带有 this.sensorManager = getSystemService(Context.SENSOR_SERVICE) as SensorManager

的传感器服务

以及确切位置

sensorManager.getDefaultSensor(Sensor.TYPE_ROTATION_VECTOR)?.let { this.rotationVector = it}

这个 class 也有不同的功能,例如。

TYPE_ACCELEROMETER

测量在所有三个物理轴(x、y 和 z)上应用于设备的 m/s2 加速力,包括重力。

运动检测(摇晃、倾斜等)。

TYPE_GRAVITY

测量在所有三个物理轴(x、y、z)上施加到设备的 m/s2 中的重力。

运动检测(摇晃、倾斜等)。

TYPE_GYROSCOPE

测量设备围绕三个物理轴(x、y 和 z)中的每一个 rad/s 的旋转速率。

旋转检测(旋转、转动等)。

TYPE_LINEAR_ACCELERATION

在没有重力的情况下测量在所有三个物理轴(x、y 和 z)上应用于设备的 m/s2 加速力。

沿单轴监控加速度。

TYPE_ROTATION_VECTOR

通过提供设备旋转矢量的三个元素来测量设备的方向。

运动检测和旋转检测。

我相信,为了实现这一点,您可以使用CLLocation。 由于您的主要 objective 是找到 phone 指向的 基点 ,您可以执行以下操作:

fun locationManager(_ manager: CLLocationManager, didUpdateHeading heading: CLHeading) {
   let angle = newHeading.trueHeading.toRadians // convert from degrees to radians
   // do what you please with this information
}

this tutorial所述:

The trueHeading is the angle between that vector and the vector starting from the same point but pointing towards the true north. If your phone points exactly to the True North you’ll get a heading of 0 (zero) degrees, if it points towards East you’ll get 90 degrees etc.

现在,如前所述here,设备方向可能会造成一些麻烦:

Unfortunately, if the user orientates the device into Landscape Mode, the reported headings will be incorrect, or at least look incorrect to the user. This will become especially important when you look at augmented reality interfaces later in the book; such interfaces are generally viewed in Landscape Left mode.

但是!这个问题有一个解决方案:

您可以使用类似这样的方法来检索您要查找的标题:

-(float)magneticHeading:(float)heading 
        fromOrientation:(UIDeviceOrientation) orientation {

    float realHeading = heading;
    switch (orientation) {1
          case UIDeviceOrientationPortrait:
               break;
          case UIDeviceOrientationPortraitUpsideDown:
               realHeading = realHeading + 180.0f;
               break;
          case UIDeviceOrientationLandscapeLeft:
               realHeading = realHeading + 90.0f;
               break;
          case UIDeviceOrientationLandscapeRight:
               realHeading = realHeading - 90.0f;
               break;
          default:
               break;
    }
    while ( realHeading > 360.0f ) {
          realHeading = realHeading - 360;
    }
    return realHeading;
}

对于不同的语言感到抱歉 (Swift - Objective C),但为了完全理解问题并找到完整的解决方案,我建议阅读源代码:

希望对您有所帮助!让我知道。

在android中,我使用setRotation()方法旋转相机。

setRotation(camera, parameters, requestedCameraId);

private void setRotation(Camera camera, Camera.Parameters parameters, int cameraId) {
    WindowManager windowManager =
            (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
    int degrees = 0;

    //get current display rotation
    int rotation = windowManager.getDefaultDisplay().getRotation();

    switch (rotation) {
        case Surface.ROTATION_0:
            degrees = 0;
            break;
        case Surface.ROTATION_90:
            degrees = 90;
            break;
        case Surface.ROTATION_180:
            degrees = 180;
            break;
        case Surface.ROTATION_270:
            degrees = 270;
            break;
        default:
            Log.e(TAG, "Bad rotation value: " + rotation);
    }

    CameraInfo cameraInfo = new CameraInfo();
    Camera.getCameraInfo(cameraId, cameraInfo);

    int angle;
    int displayAngle;
    if (cameraInfo.facing == CameraInfo.CAMERA_FACING_FRONT) {
        angle = (cameraInfo.orientation + degrees) % 360;
        displayAngle = (360 - angle) % 360; // compensate for it being mirrored
    } else {  // back-facing
        angle = (cameraInfo.orientation - degrees + 360) % 360;
        displayAngle = angle;
    }

    // This corresponds to the rotation constants.
    // mRotation = angle / 90;

    camera.setDisplayOrientation(displayAngle);
    parameters.setRotation(angle);
}

我希望这对你有用。