Рассчитать яркость сцены с помощью задней камеры

Я создаю приложение на Android, используя Samsung Galaxy Tab 10.1". Я хочу получить значение яркости сцены, используя заднюю камеру устройства.

К сожалению, мне не удалось найти способ получить доступ к показаниям датчика освещенности на задней панели устройства напрямую. Поэтому в настоящее время я оцениваю яркость вручную, вычисляя среднее значение каждого кадра в градациях серого. Однако этот метод неточен из-за автокоррекции экспозиции кадра и баланса белого. Например, если вы наведете камеру на очень яркий источник, камера затемнит все изображение, а среднее значение кадра в градациях серого будет слишком низким (поскольку область за пределами яркого источника теперь будет очень темной).

Я искал методы, которые позволили бы мне отключить упомянутые мной автоматические исправления, но ничего не нашел.

Есть ли способ, который позволит мне получить значение яркости сцены с помощью задней камеры?


person 3arbouch    schedule 30.10.2012    source источник


Ответы (2)


К сожалению, вы правы в том, что в настоящее время нет возможности получить эти данные из API камеры Android.

В зависимости от вашего устройства вы можете сделать снимок, а затем прочитать с него данные EXIF. Это может позволить вам увидеть экспозицию (ISO и скорость затвора). Этот метод используют такие приложения, как Tiny Light Meter. Проблема в том, что некоторые устройства не полностью заполняют данные EXIF, поэтому этот метод является случайным.

person Nic Dahlquist    schedule 31.10.2012

На некоторых устройствах (только на новых Android) поддерживается точечный замер. Вы можете использовать обратный вызов JPEG, запускаемый отдельным потоком таймера, таким как AsyncTask, чтобы затем прочитать информацию EXIF, которая будет измеряться в выбранном месте. Чтобы проверить, доступно ли это, вы можете использовать:

//on Event Touch callback on your SurfaceView
x=event.getX();
y=event.getY();
params=camera.getParameters();
... //check for rotation, calculate focus point (x, y: -1000, 1000)
if(params.getMaxNumMeteringAreas() > 0){
    //draw a meter area, however big you want, 1000 is weight (0-1000)
    Camera.Area ca=new Area(new Rect(x-25, y-25, x+25, y+25), 1000);
    List<Camera.Area> areas=new ArrayList<Area>();
    areas.add(ca);
    params.setFocusAreas(areas);
    params.setMeteringAreas(areas);
    camera.setParameters(params);
}else{
    //process the Bitmap and do the below...
}

На старых устройствах (если вам нужна обратная совместимость) вы все равно можете установить точку фокусировки (сохраненную в вашем коде), а затем сделать среднее значение пикселей вокруг этого фокуса (я использую 6% ширины и высоты) по сравнению со значением EXIF. (если темнее, уменьшите экспозицию и т. д.). Для этого вы, вероятно, захотите использовать кнопку «нажми-к-метру» (поскольку старые устройства отстают при выполнении обратного вызова JPEG).

average=((r+g+b)/3-128)/256
myEV=myEV+myEV*average

При использовании обоих методов просто убедитесь, что изображение, которое вы читаете, правильно повернуто (вы можете проверить, поместив его в ImageView и сравнив его с предварительным просмотром).

Из EV вы можете относительно легко конвертировать в люксы или фут-свечи (или в любое другое измерение, которое вы предпочитаете).

person wblaschko    schedule 09.05.2013