2010-07-16 11 views

Respuesta

10

A menos que haya alguna llamada a la API para que (no soy un programador de Android, no sabría), me acaba de tomar una foto de un gobernante de una distancia conocida, ver la cantidad de la regla se muestra en la imagen, a continuación, utilizar la trigonometría para encontrar el ángulo como this:

enter image description here

ahora usted tiene las dos distancias L y D de la figura. Con algunos simples goniometría, se puede obtener:

tan (α/2) = (l/2)/d,

por lo tanto

α = 2 * atan (l/2d)

Con esta fórmula puede calcular el campo de visión horizontal de su cámara. Por supuesto, medir la vertical f.o.v. va exactamente de la misma manera excepto que luego necesita ver el objeto en su posición vertical.

Luego puede codificarlo como una constante en su programa. (Una constante llamada, por supuesto, por lo que sería fácil de cambiar :-p)

+1

Mejor aún, hazlo configurable por el usuario para que las personas que no tienen un Droid Incredible puedan ajustarlo/calibrarlo. – EboMike

+0

Este valor cambiaría con el nivel de zoom, por supuesto. –

+0

@emddudley: cierto, nunca pensé que el teléfono tuviera un nivel de zoom. Aunque dado el ángulo de visión en cualquier nivel de zoom, debería ser posible calcularlo en cualquier otro nivel de zoom. –

9

Tengo un Droid Incredible también. Android 2.2 introdujo las funciones que está buscando. En mi código, que tengo:

public double getHVA() { 
    return camera.getParameters().getHorizontalViewAngle(); 
} 

public double getVVA() { 
    return camera.getParameters().getVerticalViewAngle(); 
} 

Sin embargo, éstas requieren que tenga la cámara abierta. Me interesaría saber si hay una forma de "mejores prácticas" para no tener que abrir la cámara cada vez para obtener esos valores.

@David Zaslavsky - cómo? ¿Cuál es la relación matemática entre los niveles de zoom? No puedo encontrarlo en ningún lado (lo hice en esta pregunta: What do the Android camera zoom numbers mathematically represent?)

55

Las funciones Camera.Parameters getHorizontalViewAngle() y getVerticalViewAngle() le proporcionan los ángulos de vista base. Digo "base", porque estos se aplican solo a la propia cámara en un estado sin zócalo, y los valores devueltos por estas funciones no cambian, incluso cuando el ángulo de visión sí lo hace.

Camera.Parameters p = camera.getParameters(); 
double thetaV = Math.toRadians(p.getVerticalViewAngle()); 
double thetaH = Math.toRadians(p.getHorizontalViewAngle()); 

Dos cosas hacen que su ángulo de "eficaz" para cambiar la vista: zoom, y utilizando una relación de aspecto de vista previa que no coincide con la relación de aspecto de la cámara.

matemáticas básicas

La trigonometría de campo de visión (Θ) es bastante simple:

tan (Θ/2) = x/2z

x = 2z tan (Θ/2)

x es la distancia lineal visible a la distancia z; es decir, si sostienes una regla a una distancia z = 1 metro, podrás ver x metros de esa regla.

Por ejemplo en mi cámara, el campo de visión horizontal es 52.68 ° mientras que el campo de visión vertical es 40.74 °. Convierta estos a radianes y conéctelos a la fórmula con un valor z arbitrario de 100 m, y obtendrá valores x de 99.0 m (horizontal) y 74.2 m (vertical). Esta es una relación de aspecto de 4: 3.

zoom

La aplicación de este matemáticas para ampliar los niveles es sólo un poco más difícil. Ahora, x permanece constante y es z que cambia en una relación conocida; debemos determinar Θ.

tan (Θ/2) = x/(2z)

tan (Θ '/ 2) = x/(2z')

Θ'= 2 atan ((z/z ') tan (Θ/2))

donde Z es el nivel de zoom base (100), z' es el nivel de zoom actual (de CameraParameters.getZoomRatios), Θ es la horizontal campo base/vertical de vista y Θ 'es el campo de visión efectivo. Agregar conversiones degree-> radian hace esto bastante detallado.

private static double zoomAngle(double degrees, int zoom) { 
    double theta = Math.toRadians(degrees); 
    return 2d * Math.atan(100d * Math.tan(theta/2d)/zoom); 
} 

Camera.Parameters p = camera.getParameters(); 
int zoom = p.getZoomRatios().get(p.getZoom()).intValue(); 
double thetaH = zoomAngle(p.getHorizontalViewAngle(), zoom); 
double thetaV = zoomAngle(p.getVerticalViewAngle(), zoom); 

Relación de aspecto

Mientras la cámara típico es una proporción de 4: 3, la vista previa también pueden estar disponibles en 5: 3 y 16: 9 y esto parece ser logrado por realidad se extiende la campo de visión horizontal. Esto parece estar indocumentado, por lo tanto no es confiable, pero asumiendo que así es como funciona podemos calcular el campo de visión.

La matemática es similar a los cálculos de zoom; sin embargo, en este caso z permanece constante y es x lo que cambia. Al asumir que el ángulo de visión vertical permanece sin cambios mientras que el ángulo de visión horizontal varía a medida que cambia la relación de aspecto, es posible calcular el nuevo ángulo de visión horizontal efectivo.

tan (Θ/2) = v/(2z)

tan (Θ '/ 2) = h/(2z)

2z = v/tan (Θ/2)

Θ '= 2 atan ((h/v) tan (Θ/2))

Aquí h/v es la relación de aspecto y Θ es el campo vertical de base de vista, mientras que Θ' es el campo de visión horizontal efectivo.

Camera.Parameters p = camera.getParameters(); 
int zoom = p.getZoomRatios().get(p.getZoom()).intValue(); 
Camera.Size sz = p.getPreviewSize(); 
double aspect = (double) sz.width/(double) sz.height; 
double thetaV = Math.toRadians(p.getVerticalViewAngle()); 
double thetaH = 2d * Math.atan(aspect * Math.tan(thetaV/2)); 
thetaV = 2d * Math.atan(100d * Math.tan(thetaV/2d)/zoom); 
thetaH = 2d * Math.atan(100d * Math.tan(thetaH/2d)/zoom); 

como he dicho anteriormente, ya que éste parece ser indocumentado, es simplemente una conjetura que aplicará a todos los dispositivos; debería considerarse un truco. La solución correcta sería dividir un nuevo conjunto de funciones getCurrentHorizontalViewAngle y getCurrentVerticalViewAngle.

+1

¿Pueden los resultados getHorizontalViewAngle() y getVerticalViewAngle() ser confiables para una amplia variedad de dispositivos? –

+1

¿Hay métodos similares (getVertical/HorizontalViewingAngle() en la API de la cámara2? No los vi, y me preguntaba si los perdí, o si no están presentes.¿Probablemente en CameraCharacteristics? – Innova

+0

@Innova, me pregunto lo mismo, puede ser que esos valores sean demasiado simplistas, pero he buscado en toda la documentación de la cámara2, y no he encontrado ningún tipo de forma directa de hacerlo. – TonyTheJet

Cuestiones relacionadas