Подтвердить что ты не робот

Определить угол зрения камеры смартфона

Я пытаюсь определить размер степени поля зрения Droid Incredible smartphone camera. Мне нужно знать это значение для приложения, которое я разрабатываю. Кто-нибудь знает, как я могу узнать/вычислить его программно?

4b9b3361

Ответ 1

Если для этого не существует какой-либо API-запрос (я не программист на Android, я бы не знал), я бы просто щелкнул изображение линейки с известной дистанции, посмотрим, какая часть линейки показана в изображение, затем используйте тригонометрию, чтобы найти угол, подобный this:

enter image description here

теперь у вас есть два расстояния l и d от рисунка. С помощью некоторой простой гониометрии можно получить:

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

следовательно,

α = 2 * atan (l/2d)

Таким образом, с помощью этой формулы вы можете рассчитать горизонтальное поле зрения вашей камеры. Конечно, измеряя вертикаль f.o.v. идет точно так же, за исключением того, что вам необходимо просмотреть объект в его вертикальном положении.

Затем вы можете жестко закодировать его как константу в своей программе. (Именованная константа, конечно, так что было бы легко изменить: -p)

Ответ 2

Функции Camera.Parameters getHorizontalViewAngle() и getVerticalViewAngle() предоставляют вам базовые углы обзора. Я говорю "base", потому что они применимы только к самой Камере в необозримом состоянии, а значения, возвращаемые этими функциями, не изменяются, даже когда сам угол обзора.

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

Две вещи вызывают изменение вашего "эффективного" угла обзора: масштабирование и использование пропорций предварительного просмотра, которые не соответствуют формату кадра камеры.

Базовая математика

Тригонометрия поля зрения (Θ) довольно проста:

tan (Θ/2) = x/2z

x = 2z tan (Θ/2)

x - линейное расстояние, просматриваемое на расстоянии z; т.е. если вы подняли линейку на расстоянии z = 1 метр, вы сможете увидеть x метров этой линейки.

Например, на моей камере горизонтальное поле зрения составляет 52,68 °, а вертикальное поле зрения - 40,74 °. Преобразуйте их в радианы и подключите их к формуле с произвольным значением z 100 м, и вы получите значения х 99,0 м (по горизонтали) и 74,2 м (по вертикали). Это соотношение сторон 4: 3.

Увеличить

Применение этой математики для увеличения масштаба лишь немного сложнее. Теперь x остается постоянным, а z изменяется в известном соотношении; мы должны определить Θ.

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

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

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

Если z - базовый уровень масштабирования (100), z - текущий уровень масштабирования (из CameraParameters.getZoomRatios), Θ является базовым горизонтальным/вертикальным полем обзора, а Θ 'является эффективным полем обзора. Добавление в градусы > радианные преобразования делает это довольно многословным.

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

Соотношение сторон

В то время как типичная камера имеет соотношение сторон 4: 3, предварительный просмотр также может быть доступен в соотношении 5: 3 и 16: 9, и это, по-видимому, достигается путем фактического расширения горизонтального поля обзора. Это кажется недокументированным, следовательно ненадежным, но, предполагая, что он работает, мы можем вычислить поле зрения.

Математика аналогична вычислениям масштабирования; однако в этом случае z остается постоянным и изменяется x. Предполагая, что вертикальный угол обзора остается неизменным, в то время как горизонтальный угол обзора изменяется по мере изменения формата, можно вычислить новый эффективный горизонтальный угол обзора.

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

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

2z = v/tan (Θ/2)

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

Здесь h/v - отношение размеров, а Θ - базовое вертикальное поле зрения, а Θ '- эффективное горизонтальное поле зрения.

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

Как я уже говорил выше, поскольку это, как представляется, недокументировано, это просто предположение, что оно будет применяться ко всем устройствам; его следует считать взломом. Правильное решение будет разделять новый набор функций getCurrentHorizontalViewAngle и getCurrentVerticalViewAngle.

Ответ 3

У меня также есть Droid Incredible. Android 2.2 представила функции, которые вы ищете. В моем коде у меня есть:

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

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

Однако для этого требуется, чтобы камера была открыта. Мне было бы интересно узнать, есть ли способ "лучшей практики", чтобы не открывать камеру каждый раз, чтобы получить эти значения.

@Давид Заславский - как? Какова математическая взаимосвязь между уровнями масштабирования? Я не могу найти его нигде (я спросил в этом вопросе: Что представляют собой числа масштабирования камеры Android, математически представляющие?)