2016-03-04 50 views
4

我正在构建扫描仪应用程序,并尝试从相机的预览回调中确定“预览质量”。如果环境太暗,我想自定义相机的地图AUTO_FLASH_MODE如何从实时相机预览中检测平均像素强度?

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

+0

其实我想自定义相机的AUTO_FLASH_MODE,我发现任何黑暗的环境(以像素为单位),然后打开肉体直到我的扫描仪打开。 –

+1

我删除了** Flash **标签(在使用之前请阅读标签的说明)。无论如何,所有像素的强度值都是0到255 ......所以128是完全亮(255)和暗(0)之间的一半。决定什么数字意味着“太暗”,然后通过在代码中使用for循环来检查预览图像中的像素值。查看直方图,因为这可能比检查每个像素更有用和更快。 –

+1

@ VC.One如何查看直方图比检查每个像素更快。你如何计算直方图? – Piglet

回答

1

要么找出如何访问您的图像的像素值,并自己计算平均强度或使用任何图像处理库来这样做。

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

3

我试过这种方法,但我认为它正在处理位图的不必要的时间,然后得到一个平均的屏幕色彩,

@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

我不是机器人专家。我确定有一种方法可以获取预览图像的字节数据。无论如何,这不是你的字节数组“数据”吗?你使用它作为位图解码的输入.... 如果不是,我建议你在这里创建一个新的简单问题: 如何从Android相机或谷歌获取像素值...我想你的标题是一个有点模糊。 – Piglet