2013-04-11 11 views
8

Chcę obliczyć odległość między kamerą a rozpoznanym obiektem. Do tego próbowałem wielu metod, próbowałem znaleźć kąt między obiektem a kamerą za pomocą przyspieszenia, a następnie użyćjak zmierzyć odległość między obiektem a kamerą z telefonu z Androidem

d = h * tan do

h wysokość od od podstawy, która jest na ogół 1,4

i próbuje obliczyć kąt uzyskać za pomocą sposobu orientacji. Uprzejmie daj mi znać, gdzie robię źle. Jego ponad 2 dni zmagałem się z tym wymogiem. Przyjrzeliśmy się różnym aplikacjom Camera, które są dostępne w sklepie Android Store i staraliśmy się zrozumieć funkcjonalność tego samego, ale nic nie było owocne.

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

Jak kąt odnosi się do odległości? Co jeśli stanę na balkonie? Jak możesz zmierzyć odległość, jeśli nie znasz wymiarów przechwyconego obiektu? A do jakiego stopnia używasz informacji o gęstości soczewek i optycznych czujników? –

+0

Celem aplikacji jest znalezienie odległości między obiektem a kamerą. Zakładając, że oba stoją na tej samej ziemi. Nie próbujemy mierzyć rozmiaru obiektu. –

+0

Również chcesz obejrzeć http://stackoverflow.com/q/4588485 –

Odpowiedz

5

Twój getRotationMatrix prawdopodobnie zwróci false! Powinieneś skopiować wartości do własnych wektorów, aby się nie pomyliły! Użyj metody clone(), aby to zrobić!

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

Korzystanie kod plusa tę zmianę udało mi się uzyskać wartości azymutu/pitch/roll, bez tego zmienić flagę powodzenia zwraca fałsz:

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 

Należy użyć wartości PITCH jeśli ciebie trzymają telefon w trybie pionowym, jeśli trzymasz telefon w trybie poziomym, powinieneś użyć wartości ROLL.

Jeśli trzymając telefon w wysokości 1,4 potem trzeba będzie:

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

Należy pamiętać, że należy użyć radianach a nie stopniach funkcję Math.tan.

Testowałem tutaj i wartości wydają się być poprawne!

+0

próbowałem, ale nadal istnieje problem. –

+0

Co to jest PROBLEM? Chcesz wiedzieć, co robisz źle, a nie otrzymujesz poprawnych wartości. Użyłem dokładnie tego samego kodu z tylko wymienioną tu zmianą i udało mi się uzyskać wartości azymutu/pitch/roll ... – thiagolr

+0

Otrzymuję również wartości, ale muszę obliczyć odległość między obiektem a kamerą za pomocą pitch (Używając d = h * tan (a), gdzie d jest odległością h jest wysokość czujnika, a a jest kątem nachylenia).Przeszukałem google i wdrożyłem tę metodę uzyskiwania odległości. Ale odległość obliczona przy użyciu tej wysokości daje niewłaściwą wartość. –

1

Ostateczny kod jest

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); 
    } 
Powiązane problemy