How to detect average pixel intensity from live camera preview?

后端 未结 2 823
半阙折子戏
半阙折子戏 2021-01-21 17:32

I am building a scanner app, and trying to determine the \"preview quality\" from the preview callback of the camera. I want to customize the camera\'s AUTO_FLASH_MODE

相关标签:
2条回答
  • 2021-01-21 18:09

    Either find out how to access pixel values of your image and calculate the average intensity yourself or use any image processing library to do so.

    Dark pixels have low values, bright pixels have high values. You want to calculate the average of all red, green and blue values divided by three times your pixel count. Define a threshold for when to turn on the flash, but keep in mind that you have to get a new exposure time then. Prefer flash over exposure time increase as long exposure times yield higher image noise.

    0 讨论(0)
  • 2021-01-21 18:17

    I tried this approach but i think it is taking unnecessary time of processing the bitmap and then get an average screen color,

        @Override
        public void onPreviewFrame(byte[] data, Camera camera) {
            Size cameraResolution = resolution;
            PreviewCallback callback = this.callback;
            if (cameraResolution != null && callback != null)
            {
                int format = camera.getParameters().getPreviewFormat();
                SourceData source = new SourceData(data, cameraResolution.width, cameraResolution.height, format, getCameraRotation());
                callback.onPreview(source);
                final int[] rgb = decodeYUV420SP(data, cameraResolution.width, cameraResolution.height);
    
                //Bitmap bmp =  decodeBitmap(source.getData());
                Bitmap bmp = Bitmap.createBitmap(rgb, cameraResolution.width, cameraResolution.height, Bitmap.Config.ARGB_8888);
                if (bmp != null)
                {
                    //bmp = decodeBitmap(source.getData());
                    ByteArrayOutputStream bytes = new ByteArrayOutputStream();
                    // bmp.compress(Bitmap.CompressFormat.JPEG, 70, bytes);
                    Bitmap resizebitmap = Bitmap.createBitmap(bmp,
                            bmp.getWidth() / 2, bmp.getHeight() / 2, 60, 60);
    
                    int color = getAverageColor(resizebitmap);
                    Log.i("Color Int", color + "");
                    // int color = resizebitmap.getPixel(resizebitmap.getWidth()/2,resizebitmap.getHeight()/2);
    
                    String strColor = String.format("#%06X", 0xFFFFFF & color);
                    //String colorname = sColorNameMap.get(strColor);
    
                    Log.d("strColor", strColor);
                    Log.i("strColor", color + "");
                    if(!mIsOn)
                    {
                        if (color == -16777216 || color < -16777216)//minimum color code (full dark)
                        {
    
                            mIsOn = true;
                            setTorch(true);
                            Log.d("Yahooooo", "" + color);
                        }
                    }
    
                    Log.i("Pixel Value",
                            "Top Left pixel: " + Integer.toHexString(color));
                }
            }
            else
            {
                Log.d(TAG, "Got preview callback, but no handler or resolution available");
            }
        }
    }
        private int[] decodeYUV420SP(byte[] yuv420sp, int width, int height)
       {
          final int frameSize = width * height;
    
        int rgb[]=new int[width*height];
        for (int j = 0, yp = 0; j < height; j++) {
            int uvp = frameSize + (j >> 1) * width, u = 0, v = 0;
            for (int i = 0; i < width; i++, yp++) {
                int y = (0xff & ((int) yuv420sp[yp])) - 16;
                if (y < 0) y = 0;
                if ((i & 1) == 0) {
                    v = (0xff & yuv420sp[uvp++]) - 128;
                    u = (0xff & yuv420sp[uvp++]) - 128;
                }
    
                int y1192 = 1192 * y;
                int r = (y1192 + 1634 * v);
                int g = (y1192 - 833 * v - 400 * u);
                int b = (y1192 + 2066 * u);
    
                if (r < 0) r = 0; else if (r > 262143) r = 262143;
                if (g < 0) g = 0; else if (g > 262143) g = 262143;
                if (b < 0) b = 0; else if (b > 262143) b = 262143;
    
                rgb[yp] = 0xff000000 | ((r << 6) & 0xff0000) | ((g >> 2) &
                        0xff00) | ((b >> 10) & 0xff);
    
    
            }
        }
        return rgb;
    }
    
        private int getAverageColor(Bitmap bitmap)
        {
        int redBucket = 0;
        int greenBucket = 0;
        int blueBucket = 0;
        int pixelCount = 0;
    
        for (int y = 0; y < bitmap.getHeight(); y++) {
            for (int x = 0; x < bitmap.getWidth(); x++) {
                int c = bitmap.getPixel(x, y);
    
                pixelCount++;
                redBucket += Color.red(c);
                greenBucket += Color.green(c);
                blueBucket += Color.blue(c);
                // does alpha matter?
            }
        }
    
        int averageColor = Color.rgb(redBucket / pixelCount, greenBucket
                / pixelCount, blueBucket / pixelCount);
        return averageColor;
    }
    
    0 讨论(0)
提交回复
热议问题