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

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


person GobiasKoffi    schedule 16.07.2010    source источник


Ответы (3)


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

введите здесь описание изображения

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

тангенс(α/2) = (l/2)/d,

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

α = 2*атан(l/2d)

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

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

person David Z    schedule 16.07.2010
comment
А еще лучше сделать его настраиваемым пользователем, чтобы люди, у которых нет Droid Incredible, могли его настроить/откалибровать. - person EboMike; 16.07.2010
comment
@emddudley: правда, я никогда не думал о том, что у телефона есть уровень масштабирования. Несмотря на то, что задан угол обзора при любом уровне масштабирования, должна быть возможность вычислить его для любого другого уровня масштабирования. - person David Z; 16.07.2010
comment
То есть alpha = 2 * atan(l / (2 * d)). - person Yeti; 11.09.2017

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

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

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

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

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

тангенс (Θ/2) = х / 2z

х = 2z тангенс (Θ/2)

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

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

Увеличить

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

тангенс (Θ/2) = x/(2z)

тангенс (Θ'/2) = x / (2z')

Θ' = 2 атан ((z / z') тангенс (Θ/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. Предполагая, что угол обзора по вертикали остается неизменным, а угол обзора по горизонтали изменяется при изменении соотношения сторон, можно рассчитать новый эффективный угол обзора по горизонтали.

тангенс (Θ/2) = v / (2z)

тангенс(Θ'/2) = h/(2z)

2z = v / тангенс (Θ/2)

Θ' = 2 атан ((h/v) тангенс (Θ/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.

person Community    schedule 25.08.2012
comment
Можно ли доверять самим результатам getHorizontalViewAngle() и getVerticalViewAngle() для самых разных устройств? - person Alex Cohn; 27.10.2012
comment
Существуют ли аналогичные методы (getVertical/HorizontalViewingAngle() в API camera2? Я их не видел, и мне было интересно, пропустил ли я их или их нет. Возможно, в CameraCharacteristics? - person Innova; 20.08.2015
comment
@Innova, мне интересно то же самое - возможно, эти значения были слишком упрощенными, но я просмотрел всю документацию camera2 и не нашел какого-либо простого способа сделать это. - person TonyTheJet; 10.10.2016
comment
Вы знаете, почему я получаю вертикальный угол больше, чем горизонтальный? p.getVerticalViewAngle() == 61,8, p.getHorizontalViewAngle() == 56,6 (по горизонтали меньше, как это возможно?) - person user25; 29.06.2017
comment
все эти углы изначально неверны (56,6, 61,8), я вычислил соотношение сторон 16/9 (разрешение 1920x1080) вручную (stackoverflow.com/a /3261794/4548520), и я получил 39 градусов по вертикали и 65 по горизонтали. Итак, изначально для соотношения 4:3 нет прямого угла, поэтому ваш код не будет работать. - person user25; 30.06.2017
comment
@Dorje, пожалуйста, проверьте этот вопрос? stackoverflow.com/questions/67375781/ - person user924; 04.05.2021
comment
В то время как типичная камера имеет соотношение сторон 4:3, предварительный просмотр также может быть доступен в соотношениях сторон 5:3 и 16:9, и это, по-видимому, достигается за счет фактического расширения поля зрения по горизонтали. - Это не относится к устройствам с датчиками с соотношением сторон 4:3 - выходы 16:9 всегда меньше FOV, чем выходы 4:3 на таких датчиках, в вертикальном FOV (горизонтальные FOV будут идентичными). Если у вас датчик 16:9, то у 4:3 будет более узкое горизонтальное поле зрения, чем у выхода 16:9. Но у немногих устройств есть такие. Значения FOV для старого API камеры относятся к наибольшему размеру изображения и его соотношению сторон. - person Eddy Talvala; 06.05.2021

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

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

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

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

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

person Max    schedule 10.09.2010