如何从实时摄像头预览中检测平均像素强度?

时间:2016-03-04 04:49:43

标签: android image-processing mobile video-processing

我正在构建扫描仪应用程序,并尝试从相机的预览回调中确定“预览质量”。我想自定义相机的AUTO_FLASH_MODE,如果环境太暗,它将被打开。

如何检测暗像素的平均值是否高?这意味着(在预览中)我正在变暗,因此需要打开相机的闪光灯。

2 个答案:

答案 0 :(得分:1)

要么找出如何访问图像的像素值并自己计算平均强度,要么使用任何图像处理库来执行此操作。

暗像素值较低,亮像素值较高。 您想要计算所有红色,绿色和蓝色值的平均值除以像素数的三倍。 定义何时打开闪光灯的阈值,但请记住,您必须获得新的曝光时间。 由于长曝光时间会产生更高的图像噪声,因此首选闪光曝光时间会增加。

答案 1 :(得分:1)

我尝试过这种方法,但我认为处理位图需要花费不必要的时间,然后获得平均屏幕颜色,

    @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;
}