Определить угол обзора камеры смартфона - PullRequest
19 голосов
/ 16 июля 2010

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

Ответы [ 3 ]

58 голосов
/ 25 августа 2012

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

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

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

Basic Math

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

загар (Θ / 2) = х / 2z

x = 2z загар (Θ / 2)

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

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

Увеличить

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

загар (Θ / 2) = х / (2z)

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

Θ '= 2 атан ((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)

загар (Θ '/ 2) = ч / (2z)

2z = v / tan (Θ / 2)

Θ '= 2 атан ((ч / об) 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);

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

14 голосов
/ 16 июля 2010

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

enter image description here

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

загар (α / 2) = (л / 2) / д,

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

α = 2 * атан (л / 2д)

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

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

9 голосов
/ 10 сентября 2010

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

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

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...