当前位置: 首页 > 知识库问答 >
问题:

我们如何测量物体和Android手机摄像头之间的距离

唐声
2023-03-14

我想计算相机和被识别物体之间的距离。为此我尝试了很多方法,我试图用加速度计找到物体和相机之间的角度,然后用

d=h*tan a

H是距离底座的高度,一般为1.4

我试着用get方向方法计算角度。请让我知道我做错了什么。已经超过2天了,我一直在努力满足这个要求。我们已经研究了Android商店上的各种相机应用程序,并试图理解它们的功能,但没有任何结果。

 mSensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
            accSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
            magnetSensor = mSensorManager
                    .getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);
    @Override
    public void onAccuracyChanged(Sensor sensor, int accuracy) {
        // TODO Auto-generated method stub

    }

    @Override
    public void onSensorChanged(SensorEvent event) {
        // TODO Auto-generated method stub
        if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER)
            gravity = event.values;
        if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD)
            geoMagnetic = event.values;
        if (gravity != null && geoMagnetic != null) {
            float R[] = new float[9];
            float I[] = new float[9];
            boolean success = SensorManager.getRotationMatrix(R, I, gravity,
                    geoMagnetic);
            if (success) {
                /* Orientation has azimuth, pitch and roll */
                float orientation[] = new float[3];
                //SensorManager.remapCoordinateSystem(R, 1, 3, orientation);
                SensorManager.getOrientation(R, orientation);
                azimut = 57.29578F * orientation[0];
                pitch = 57.29578F * orientation[1];
                roll = 57.29578F * orientation[2];
            }
        }
    }


        captureButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // get an image from the camera

                double d = (Math.tan(Math.toRadians(Math.abs(pitch))) * sensorHeight);
                Toast.makeText(
                        getApplicationContext(),
                        "Distance = "
                                + String.valueOf(d)
                                        + "m  Angle = "
                                        + String.valueOf(Math.toRadians(Math.abs(pitch))),
                        Toast.LENGTH_LONG).show();


            }
        });



protected void onResume() {
        super.onResume();
        mSensorManager.registerListener(this, accSensor,
                SensorManager.SENSOR_DELAY_NORMAL);
        mSensorManager.registerListener(this, magnetSensor,
                SensorManager.SENSOR_DELAY_NORMAL);
    }

共有2个答案

蓝侯林
2023-03-14

最后的代码

mSensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
            accSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
            magnetSensor = mSensorManager
                    .getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);
    @Override
    public void onAccuracyChanged(Sensor sensor, int accuracy) {
        // TODO Auto-generated method stub

    }

    @Override
    public void onSensorChanged(SensorEvent event) {
        // TODO Auto-generated method stub
        if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER)
            gravity = event.values;
        if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD)
            geoMagnetic = event.values;
        if (gravity != null && geoMagnetic != null) {
            float R[] = new float[9];
            float I[] = new float[9];
            boolean success = SensorManager.getRotationMatrix(R, I, gravity,
                    geoMagnetic);
            if (success) {
                /* Orientation has azimuth, pitch and roll */
                float orientation[] = new float[3];
                //SensorManager.remapCoordinateSystem(R, 1, 3, orientation);
                SensorManager.getOrientation(R, orientation);
                azimut = 57.29578F * orientation[0];
                pitch = 57.29578F * orientation[1];
                roll = 57.29578F * orientation[2];
            }
        }
    }


        captureButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // get an image from the camera

                float d = Math.abs((float) (1.4f * Math.tan(pitch * Math.PI / 180)));
                Toast.makeText(
                        getApplicationContext(),
                        "Distance = "
                                + String.valueOf(d)
                                        + "m  Angle = "
                                        + String.valueOf(Math.toRadians(Math.abs(pitch))),
                        Toast.LENGTH_LONG).show();


            }
        });



protected void onResume() {
        super.onResume();
        mSensorManager.registerListener(this, accSensor,
                SensorManager.SENSOR_DELAY_NORMAL);
        mSensorManager.registerListener(this, magnetSensor,
                SensorManager.SENSOR_DELAY_NORMAL);
    }
轩辕华辉
2023-03-14

你的getRotationMatrix可能返回false!你应该把这些值复制到你自己的向量中,这样它们就不会混淆了!使用clone()方法来执行此操作!

    if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER)
        gravity = event.values.clone();
    if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD)
        geoMagnetic = event.values.clone();

使用您的代码加上这个更改,我能够获得方位角/俯仰角/滚动值,如果没有这个更改,成功标志将返回false:

Log.d("a", "orientation values: " + azimut + " / " + pitch + " / " + roll);
05-21 16:07:55.743: D/a(29429): orientation values: 77.71578 / 43.352722 / -152.39603
05-21 16:07:55.883: D/a(29429): orientation values: 175.26134 / 23.031355 / -148.72844
05-21 16:07:56.793: D/a(29429): orientation values: -146.3089 / 4.1098075 / -14.46417

如果您以竖屏方式握住手机,则应使用PITCH值;如果您以横向模式握住手机,则应使用ROLL值。

如果您将手机保持在1.4的高度,则您将拥有:

float dist = Math.abs((float) (1.4f * Math.tan(pitch * Math.PI / 180)));

请注意,你应该在数学上使用弧度,而不是度。晒黑功能。

我在这里进行了测试,这些值似乎是有效的!

 类似资料:
  • 我知道关于这个话题已经有了一些答案,但我不太清楚如何测量相机和物体之间的距离。 我的目标是: 我用OpenCV通过颜色检测成功地追踪了一个红色的球。现在我试着在红球的中间点一个激光。当红球移动时,激光器应始终跟随红球。我用一个小伺服电机来转动激光。 我在想,如果我能测量物体和相机之间的距离,我就能计算出伺服需要转动的角度。。。 我试图跟踪卡梅伦·洛厄尔·帕尔默的帖子。 我所做的: 我校准了我的Pi

  • 我想知道人与摄像机之间的距离。我使用的是android摩托罗拉平板电脑。 我使用的是android的摄像头api——api级别14。 我使用以下公式: imageHeight是我预览屏幕的高度<我从相机api获得的焦距:4.42毫米 我输入的物体高度是人的身高,单位为mm:1620mm 我想计算人与摄像机的距离。 通过使用这个公式,我得到了错误的距离,它给了我60毫米,但实际上它超过了2500毫米

  • 我创建了xamarin表单,它可以从相机中拍摄照片,但当我单击相机打开按钮时,它不会打开相机。我的代码在这里“https://github.com/Malith1994124/Kiosk/blob/master/Kiosk_V2/Kiosk_V2/Helpers/Utilities.cs“我在android部分中提供了所有必需的权限。 谁能帮帮我吗。我是xamarin的新手,现在在这里呆了一个多星

  • 我想修复Android中相机预览的帧率,即20fps或30fps。但是,我们发现帧率不稳定。 在android文档中,据说帧率在getSupport dPreviewFpsRange中定义的最小帧率和最大帧率之间波动。https://developer.android.com/reference/android/hardware/Camera.Parameters.html#getSupporte

  • 本文向大家介绍Android实现手机摄像头的自动对焦,包括了Android实现手机摄像头的自动对焦的使用技巧和注意事项,需要的朋友参考一下 如何实现Android相机的自动对焦,而且是连续自动对焦的。当然直接调用系统相机就不用说了,那个很简单的。下面我们主要来看看如如何自己实现一个相机,并且实现自动连续对焦。 代码如下: 以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持呐喊教程

  • 我正在启动一个项目,开发一个移动应用程序,我将需要访问手机的摄像头,并检索一张图片/照片。 然而,在进入原生应用程序之前,我想知道Dart(当然是编译成JavaScript的)是否可以访问Android Phone的摄像头并检索到那张照片。在这种情况下,应用程序将是基于web的。 Dart能做到吗?还是我需要一个原生应用程序?