Android: detect brightness (amount of light) in phone's surroundings using the camera?
Asked Answered
I

5

10

The following applies to the Android operating system.

I am trying to estimate how dark (or light) it is in the room where the phone is located using the camera.

The idea is that the camera can return a certain brightness level, which I can use to determine the amount of light in the surroundings of the phone.

My question is simple: how do I use the camera (either the front of back camera) to get this amount of brightness (the "amount of light")?

Thanks in advance.

Intemperance answered 19/1, 2011 at 17:5 Comment(2)
Most (all?) Android phones have two tiny hardware sensors that are used for "daylight detection." The feedback from these sensors are how your phone controls the brightness of the display when you set the setting to auto-control. I wonder if you could tap into that data. It would be many times more reliable.Isothermal
Thanks user432209, that would definitely help. I hope this sensor (what is it called?) is publicly available, maybe someone can enlighten us on this subject.Intemperance
R
24

Here is how you register a listener on the light sensor:

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: Thanks to @AntiMatter for the suggested updates.

Docs: SensorEventListener SensorManager SensorEvent Sensor

Roomful answered 19/1, 2011 at 18:15 Comment(5)
Great, this sensor will help me a lot. I am unsure howmany devices (especially the less expensive archos media players) have this sensor implemented though, but this will do for now. Thanks.Intemperance
You could use <uses-feature android:name="android.hardware.sensor.light" /> in the manifest, and devices that don't have this sensor wouldn't find it in the market. Alternatively, it looks like you could call getSensorList(Sensor.TYPE_LIGHT); and then check whether the list size is greater than 0 to see whether or not the device has the required sensor programmatically.Roomful
I understand kcoppock, I was thinking about an alternative to support devices that lack it though. However, this is something I need to ask myself in the future as I am not sure if there even is a need for this. Thanks again.Intemperance
I'm getting error on lightSensor.registerListener(listener); - The method registerListener(SensorEventListener) is undefined for the type SensorCavalla
@AntiMatter I've updated the answer with changes per your suggestions. :)Roomful
G
6

If you wanted to use the camera, for instance if the other sensors were not available then I would

  1. Set the camera's auto exposure to off, and set exposure compensation to 0
  2. Set capture to lowest quality / size (why bother with more)
  3. Make the preview window as small as possible (maybe you could even set it to invisible and still get a frame to analyze, not sure)
  4. Get an image preview frame, but those are in yuv format so 2.1 and earlier would need an a translator.

Then I would compute the histogram for the images luminosity and work right (brightest) to left (dimmest) until you found the first significant value higher than N, which would determine your scene brightness.

Having said all of that I would not do it since you would need to test for a lot of outlier situations.

Course not sure what you use case is, if it's a situation where you are using it to adjust "brightness" in a car, then forward facing camera would be effected by headlights etc.

Anyway interesting problem but seems like a lot of work for such little gain, especially with most decent pieces of hardware having those sensors

Gowen answered 18/6, 2011 at 5:10 Comment(3)
Regarding point 3, in my experience, making the camera preview window invisible doesn't work unless you use TextureView and set its WindowManager.LayoutParams.alpha to 0.Ethridge
Regarding point 4, if you use a TextureView as the camera preview, you can just call TextureView.getBitmap to get the current frame in RGB.Ethridge
Of course, you need API 14 (Android 4.0, I think) to use TextureView.Ethridge
M
2

My response may be too incomplete for an answer, but I like the formatting here.

Additionally, my answer is not facetious, so don't stop reading right away.

Of course, first you'll have to take a picture. Then you'll have to define 'brightness'. I don't have the algorithm to do so, but I'm guessing something like that has already been done. Maybe something like :

Determine which pixel values are bright, which are dark and which are in between (and each of them can have a variable amount of brightness). You'll then have to apply that algorithm to your photograph to get a brightness value.

Yes, this is a very short (35,000 foot) view of the problem, but it should give you some ideas about where to start.

[edit]
Here is a place to start (the android documentation for sensors)
[/edit]

Mattias answered 19/1, 2011 at 17:28 Comment(4)
Thanks, this does help, maybe someone else will be able to expand on 1) the inbuild daylight detection sensor (it would suit better than the camera) 2) your algorithm suggestion. If the inbuild brightness sensor cannot be tapped, I probably have to use your approach.Intemperance
I have to believe that the algorithm already exists, but the idea intrigued me, so I gave a quick, thumb-nail sketch of how it could be done.Mattias
Fine, downvote - but give a reason why (especially since I edited my response to include how to access the hardware sensor)Mattias
I do not understand why someone downvoted you. Your answer and update are both helpful. Please upvote, people.Intemperance
N
1

Using the camera is pointless, since the camera will adjust the exposure time and aperture to the surrounding light, so that the recorded images will have very similar overall brightness independent of the actual available light (at least in an ideal world).

The Android API offer functionality in the SensorManager to access the hardware sensors (you are interested in the sensor of type TYPE_LIGHT). I am not sure however, if you can rely on access to these sensors through the API, although they may (or may not) be present.

Nilgai answered 19/1, 2011 at 17:55 Comment(1)
Thanks for the information about the camera, I wonder if this indeed means that a device without a light sensor cannot estimate the room's brightness with the camera (as a fallback method).Intemperance
C
0

The big deal at wanting to nail the brightness down is to figure out how HTC is doing it in their camera.apk . Because the stock Android Camera app is horrible for overexposure especially for the DINC.

Certitude answered 1/2, 2011 at 18:18 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.