как мы можем измерить расстояние между объектом и камерой телефона Android

Я хочу рассчитать расстояние между камерой и распознанным объектом. Для этого я перепробовал множество методов, я попытался найти угол между объектом и камерой с помощью акселерометра, а затем использовать

д = ч * загар а

h - высота от основания, как правило, 1,4

и я попытался вычислить угол, используя метод ориентации. Пожалуйста, дайте мне знать, где я делаю не так. Уже более 2 дней я борюсь с этим требованием. Мы изучили различные приложения камеры, доступные в Android Store, и попытались понять их функциональность, но ничего не дало.

 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);
    }

person Rachit Tyagi    schedule 11.04.2013    source источник
comment
Как угол соотносится с расстоянием? Что делать, если я стою на балконе? Кроме того, как можно измерить расстояние, если вы не знаете размеров захваченного объекта? Кроме того, сколько информации о плотности объектива и оптического сенсора вы используете?   -  person class stacker    schedule 11.04.2013
comment
Приложение предназначено для определения расстояния между объектом и камерой. Предполагая, что оба стоят на одной земле. Мы не пытаемся измерить размер объекта.   -  person Rachit Tyagi    schedule 11.04.2013
comment
Также вы хотите посмотреть stackoverflow.com/q/4588485   -  person class stacker    schedule 11.04.2013
comment
Невозможно использовать только одну камеру. Вы должны знать другую информацию, чтобы позиционировать объект относительно вашего устройства. Недаром в Kinect помимо обычной камеры есть ИК-проектор + ИК-камера. Ориентация вашего устройства не даст вам никакого представления о расстоянии до объекта перед камерой.   -  person Nicolas Dusart    schedule 11.04.2013
comment
Я уже изучал это, но не смог правильно получить угол, в результате чего не смог использовать Tan для определения расстояния. Цель состоит в том, чтобы получить приблизительное расстояние.   -  person Rachit Tyagi    schedule 11.04.2013
comment
Подскажите, что это за 57.29578F?   -  person Anas Ahamed    schedule 09.10.2017


Ответы (2)


Ваш 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)));

Обратите внимание, что вы должны использовать РАДИАНЫ, а не ГРАДУСЫ в функции Math.tan.

Я тестировал здесь, и значения кажутся действительными!

person thiagolr    schedule 20.05.2013
comment
В чем проблема? Вы хотели знать, что делаете неправильно, но неправильно получаете значения. Я использовал тот же самый код с только упомянутыми здесь изменениями, и мне удалось получить значения азимута / тангажа / крена ... - person thiagolr; 21.05.2013
comment
Я также получаю значения, но мне нужно рассчитать расстояние между объектом и камерой с использованием шага (используя d = h * tan (a), где d - расстояние, h - высота датчика, а a - угол наклона). Я искал в Google и реализовал этот метод определения расстояния. Но расстояние, рассчитанное с использованием этого шага, дает неверное значение. - person Rachit Tyagi; 22.05.2013
comment
Спасибо за ответ, теперь получаю действительные значения, и я использую его в ландшафтном режиме, но проблема в том, что рассчитанное расстояние неточно. Например, если расстояние составляет 10 метров, то я получаю 6,04 метра, а если расстояние составляет около 1 метра, то получаю 0,024 метра. Пожалуйста, дайте мне знать, где я делаю не так. Если вы получаете точное расстояние, не могли бы вы поделиться своим полным кодом. - person Rachit Tyagi; 23.05.2013
comment
Что ж, я решил проблему (ы) из вашего вопроса, теперь ваша очередь работать над этим ... Датчики чрезвычайно чувствительны, небольшое движение будет иметь большое влияние на измерения. Именно так и рассчитывают расстояние другие приложения ... - person thiagolr; 23.05.2013
comment
спасибо за ответ. Внеся некоторые изменения в код, теперь я получаю точные значения. - person Rachit Tyagi; 28.05.2013
comment
пожалуйста, разместите здесь весь код, потому что это поможет сообществу. - person Abhijit Chakra; 08.07.2013
comment
пожалуйста, разместите здесь весь код, потому что это поможет сообществу - person Bhaskar; 25.06.2015
comment
как мне узнать высоту датчика - person ; 30.06.2017

Окончательный код

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);
    }
person Rachit Tyagi    schedule 30.05.2013
comment
как мне узнать высоту датчика - person Magesh Pandian; 30.04.2018
comment
для камеры телефона и планшета высота сенсора составляет 3,42 мм - person Divya Thakkar; 02.05.2018
comment
Датчик высоты для перикулярного устройства можно получить по этой ссылке: photoseek.com/2013/ - person Divya Thakkar; 02.05.2018