Android: определить яркость (количество света) в окружении телефона с помощью камеры?

Следующее относится к операционной системе Android.

Я пытаюсь оценить, насколько темно (или светло) в комнате, где находится телефон, с помощью камеры.

Идея состоит в том, что камера может возвращать определенный уровень яркости, который я могу использовать для определения количества света вокруг телефона.

Мой вопрос прост: как мне использовать камеру (либо переднюю, либо заднюю камеру), чтобы получить такое количество яркости («количество света»)?

Заранее спасибо.


person Tom    schedule 19.01.2011    source источник
comment
Большинство (все?) телефонов Android имеют два крошечных аппаратных датчика, которые используются для обнаружения дневного света. Обратная связь от этих датчиков — это то, как ваш телефон управляет яркостью дисплея, когда вы устанавливаете настройку на автоматическое управление. Интересно, не могли бы вы подключиться к этим данным. Это было бы в разы надежнее.   -  person user432209    schedule 19.01.2011
comment
Спасибо пользователю 432209, это определенно поможет. Надеюсь этот датчик (как он называется?) есть в открытом доступе, может кто просветит нас на эту тему.   -  person Tom    schedule 19.01.2011


Ответы (5)


Вот как вы регистрируете слушателя на датчике освещенности:

private final SensorManager mSensorManager;
private final Sensor mLightSensor;
private float mLightQuantity;

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    // Obtain references to the SensorManager and the Light Sensor
    mSensorManager = (SensorManager)getSystemService(SENSOR_SERVICE);
    mLightSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_LIGHT);

    // Implement a listener to receive updates
    SensorEventListener listener = new SensorEventListener() {
        @Override
        public void onSensorChanged(SensorEvent event) {
            mLightQuantity = event.values[0];
        }
    }

    // Register the listener with the light sensor -- choosing
    // one of the SensorManager.SENSOR_DELAY_* constants.
    mSensorManager.registerListener(
            listener, lightSensor, SensorManager.SENSOR_DELAY_UI);
}

EDIT: Спасибо @AntiMatter за предложенные обновления.

Документы: SensorEventListener SensorManager SensorEvent Sensor< /а>

person Kevin Coppock    schedule 19.01.2011
comment
Отлично, этот датчик мне очень поможет. Я не уверен, сколько устройств (особенно менее дорогих медиаплееров Archos) имеют этот датчик, но пока этого достаточно. Спасибо. - person Tom; 19.01.2011
comment
Вы можете использовать <uses-feature android:name="android.hardware.sensor.light" /> в манифесте, и устройства, у которых нет этого датчика, не найдут его на рынке. Кроме того, похоже, что вы можете вызвать getSensorList(Sensor.TYPE_LIGHT);, а затем проверить, больше ли размер списка, чем 0, чтобы увидеть, имеет ли устройство требуемый датчик программно. - person Kevin Coppock; 19.01.2011
comment
Я понимаю kcoppock, я думал об альтернативе для поддержки устройств, у которых ее нет. Тем не менее, это то, что мне нужно спросить себя в будущем, поскольку я не уверен, есть ли в этом необходимость. Спасибо еще раз. - person Tom; 20.01.2011
comment
Я получаю сообщение об ошибке lightSensor.registerListener(listener); - метод registerListener (SensorEventListener) не определен для типа Sensor - person Confuse; 23.09.2014
comment
@AntiMatter Я обновил ответ с изменениями в соответствии с вашими предложениями. :) - person Kevin Coppock; 23.09.2014

Если бы вы хотели использовать камеру, например, если бы другие датчики были недоступны, я бы

  1. Отключите автоматическую экспозицию камеры и установите компенсацию экспозиции на 0.
  2. Установите захват на самое низкое качество / размер (зачем беспокоиться о большем)
  3. Сделайте окно предварительного просмотра как можно меньше (может быть, вы даже можете сделать его невидимым и все равно получить кадр для анализа, не уверен)
  4. Получите кадр предварительного просмотра изображения, но они в формате yuv, поэтому для версии 2.1 и более ранних версий потребуется переводчик.

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

Сказав все это, я бы не стал этого делать, так как вам нужно будет проверить множество исключительных ситуаций.

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

В любом случае интересная проблема, но кажется, что много работы для такого небольшого выигрыша, особенно с большинством приличных аппаратных средств, имеющих эти датчики.

person Idistic    schedule 18.06.2011
comment
Что касается пункта 3, по моему опыту, сделать окно предварительного просмотра камеры невидимым не работает, если вы не используете TextureView и не устанавливаете его WindowManager.LayoutParams.alpha в 0. - person Sam; 10.12.2014
comment
Что касается пункта 4, если вы используете TextureView в качестве предварительного просмотра камеры, вы можете просто вызвать TextureView.getBitmap, чтобы получить текущий кадр в RGB. - person Sam; 10.12.2014
comment
Конечно, вам нужен API 14 (я думаю, Android 4.0), чтобы использовать TextureView. - person Sam; 10.12.2014

Мой ответ может быть слишком неполным для ответа, но мне нравится форматирование здесь.

Кроме того, мой ответ не шуточный, так что не бросайте чтение сразу.

Конечно, сначала вам придется сделать снимок. Затем вам нужно будет определить «яркость». У меня нет алгоритма для этого, но я предполагаю, что что-то подобное уже было сделано. Может быть, что-то вроде:

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

Да, это очень краткий (35 000 футов) взгляд на проблему, но он должен дать вам некоторое представление о том, с чего начать.

[edit]
Здесь можно начать ( документация для датчиков Android)
[/edit]

person KevinDTimm    schedule 19.01.2011
comment
Спасибо, это действительно помогает, может быть, кто-то еще сможет расширить 1) встроенный датчик обнаружения дневного света (он подойдет лучше, чем камера) 2) ваше предложение по алгоритму. Если встроенный датчик яркости не может быть задействован, мне, вероятно, придется использовать ваш подход. - person Tom; 19.01.2011
comment
Я должен верить, что алгоритм уже существует, но идея меня заинтриговала, поэтому я быстро и в общих чертах набросал, как это можно сделать. - person KevinDTimm; 19.01.2011
comment
Хорошо, понизьте голосование, но объясните, почему (тем более, что я отредактировал свой ответ, включив в него способ доступа к аппаратному датчику) - person KevinDTimm; 19.01.2011
comment
Я не понимаю, почему кто-то проголосовал за вас. Ваш ответ и обновление полезны. Пожалуйста, проголосуйте, люди. - person Tom; 19.01.2011

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

Android API предлагает функциональные возможности в SensorManager для доступа к аппаратным датчикам (вас интересует датчик типа TYPE_LIGHT). Однако я не уверен, можно ли рассчитывать на доступ к этим датчикам через API, хотя они могут (а могут и не быть) присутствовать.

person jarnbjo    schedule 19.01.2011
comment
Спасибо за информацию о камере, интересно, действительно ли это означает, что устройство без датчика освещенности не может оценить яркость комнаты с помощью камеры (как запасной метод). - person Tom; 19.01.2011

Чтобы снизить яркость, нужно выяснить, как HTC делает это в файле camera.apk. Потому что стандартное приложение Android Camera ужасно для передержки, особенно для DINC.

person Nick    schedule 01.02.2011