6

I have an Android app where user takes a photo of himself with the front camera and then the photo is being uploaded to my server. I notice that many photos comes to my server too dark (sometimes almost impossible to cleary see the user face).

I would like to filter out such photos and show notification (eg. "Photo is too dark. Take one more picture") to the user in the app side. How I could accomplish such task in Android?

EDIT:

I have found out how to calculate brightness for one single pixel (thank's to this answer: https://stackoverflow.com/a/16313099/2999943):

private boolean isPixelColorBright(int color) {
    if (android.R.color.transparent == color)
        return true;

    boolean rtnValue = false;

    int[] rgb = {Color.red(color), Color.green(color), Color.blue(color)};

    int brightness = (int) Math.sqrt(rgb[0] * rgb[0] * .299 + rgb[1]
            * rgb[1] * .587 + rgb[2] * rgb[2] * .114);

    if (brightness >= 200) {    // light color
        rtnValue = true;
    }

    return rtnValue;
}

But still I don't have clear idea how to determine whole image brightness "status". Any suggestions?

Community
  • 1
  • 1
user2999943
  • 2,419
  • 3
  • 22
  • 34
  • If you can determine the brightness for a singe pixel, why not analyze all pixels in the same way to get the average value, and use that ? – Jonas Czech Mar 10 '16 at 15:29

1 Answers1

10

As a variant you can build a brightness histogram of your photo. Calculate brightness as described here Formula to determine brightness of RGB color. Then initialize array of size 256 and increment by one an array element which index is a brightness of every pixel.

Then look if too much values are on the left side or right one, it means that your picture is too light/dark. For example you can look at 10 right and left values.

Code example:

int histogram[256];
for (int i=0;i<256;i++) {
     histogram[i] = 0;
}

for (int x = 0; x < a.getWidth(); x++) {
    for(int y = 0; y < a.getHeight(); y++) {
        int color = a.getRGB(x, y);

        int r = Color.red(pixel);
        int g = Color.green(pixel);
        int b = Color.blue(pixel);

        int brightness = (int) (0.2126*r + 0.7152*g + 0.0722*b);
        histogram[brightness]++;
    }
}

int allPixelsCount = a.getWidth() * a.getHeight();

// Count pixels with brightness less then 10
int darkPixelCount = 0;
for (int i=0;i<10;i++) {
    darkPixelCount += histogram[i];
}

if (darkPixelCount > allPixelCount * 0.25) // Dark picture. Play with a percentage
else // Light picture.
Community
  • 1
  • 1
Yev Kanivets
  • 1,780
  • 3
  • 22
  • 38
  • Thank's for the answer. I can calculate brigtness level for one single pixel (look at my edited question) according to your provided info. But could you explain further steps in more detail? How exactly I can construct image brightness histogram? Also I don't get fully this sentence: "Then initialize array of size 256 and increment by one an array element which index is a brightness of every pixel." Could you illustrate your idea with short code snippet? – user2999943 Mar 10 '16 at 14:54
  • Added the code example. Ask me if something is not obvious. – Yev Kanivets Mar 10 '16 at 15:42
  • Now I got it. Thanks! – user2999943 Mar 14 '16 at 08:52
  • Thanks! I'm using something similar in my app (needed to workout if background image would require white or black foreground text). But why only count pixels with brightness less then 10? Surely comparing the left half of the histogram (<128) to a percentage of total pixels is OK? – Mateus Nov 06 '16 at 19:22
  • @Mateus, need to try an idea with left\right halves comparing. My idea was to detect an extra white or extra black images. So I checked only extra values from range, like < 10. – Yev Kanivets Nov 07 '16 at 08:29
  • what is pixel ? – 68060 Aug 12 '17 at 20:03
  • @68060, pixel is an one dot from bitmap taken from camera. – Yev Kanivets Aug 14 '17 at 07:46
  • No, a color variable is an int representation of pixel. Not a pixel itself. – Yev Kanivets Aug 14 '17 at 08:58