将位图(RGB_565)转换为灰度(8位)Android

Posted

技术标签:

【中文标题】将位图(RGB_565)转换为灰度(8位)Android【英文标题】:Converting Bitmap(RGB_565) to Grayscale(8 bit) Android 【发布时间】:2012-03-30 12:44:54 【问题描述】:

我正在为我的最后一年做一个人脸识别项目。我必须使用本地二进制模式(LBP)在 android 上进行人脸识别。

我在互联网上搜索了很多在 Java 中使用 LBP 进行人脸识别的代码,但找不到任何可在 android 上实现的代码。所以现在我不得不写这一切,我是安卓和图像处理的新手。

我找到了一种从相机捕捉图像的方法。

public class CameraCapture extends Activity 

protected boolean _taken = true;
File sdImageMainDirectory;

protected static final String PHOTO_TAKEN = "photo_taken";

@Override
public void onCreate(Bundle savedInstanceState) 

    try 

        super.onCreate(savedInstanceState);         
                File root = new File(Environment
                        .getExternalStorageDirectory()
                        + File.separator + "myDir" + File.separator);
                root.mkdirs();
                sdImageMainDirectory = new File(root, "myPicName");


            startCameraActivity();
        
     catch (Exception e) 
        finish();
        Toast.makeText(this, "Error occured. Please try again later.",
                Toast.LENGTH_SHORT).show();
    



protected void startCameraActivity() 

    Uri outputFileUri = Uri.fromFile(sdImageMainDirectory);

    Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");
    intent.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri);

    startActivityForResult(intent, 0);


@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) 
    switch (resultCode) 
    case 0:
        finish();
        break;

    case -1:

        try 
            StoreImage(this, Uri.parse(data.toURI()),
                    sdImageMainDirectory);
         catch (Exception e) 
            e.printStackTrace();
        

        finish();
        startActivity(new Intent("com.piit.lbp.form.LBPFORMADD"));

    



@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) 
    if (savedInstanceState.getBoolean(CameraCapture.PHOTO_TAKEN)) 
        _taken = true;
    


@Override
protected void onSaveInstanceState(Bundle outState) 
    outState.putBoolean(CameraCapture.PHOTO_TAKEN, _taken);


    public static void StoreImage(Context mContext, Uri imageLoc, File imageDir) 
    Bitmap bm = null;

    try 
        bm = Media.getBitmap(mContext.getContentResolver(), imageLoc);
        bmGray = toGrayScale(bm);
        FileOutputStream out = new FileOutputStream(imageDir);
        bm.compress(Bitmap.CompressFormat.JPEG, 100, out);
        bm.recycle();
     catch (FileNotFoundException e) 
        e.printStackTrace();
     catch (IOException e) 
        e.printStackTrace();
     catch (Exception e) 
        e.printStackTrace();
    


问题:什么是“位图 bm” - 比如 RGB_565,还是别的什么?以及多少位。

在将位图压缩为 jpeg 之前,我使用以下代码调用 RGB 转灰度方法

public static Bitmap toGrayscale(Bitmap bmpOriginal)
        
    int width, height;
    height = bmpOriginal.getHeight();
    width = bmpOriginal.getWidth();    

    Bitmap bmpGrayscale = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
    Canvas c = new Canvas(bmpGrayscale);
    Paint paint = new Paint();
    ColorMatrix cm = new ColorMatrix();
    cm.setSaturation(0);
    ColorMatrixColorFilter f = new ColorMatrixColorFilter(cm);
    paint.setColorFilter(f);
    c.drawBitmap(bmpOriginal, 0, 0, paint);
    return bmpGrayscale;

然后我希望使用 bmGray 来应用 LBP 算子。 问题:当你使用 ColorMatrix 转换为灰度时,是每像素 8 位吗??

因为我想将 bmGray 转换为字节数组,并且一次只提取 1 个字节。而且我还想知道是否可以将灰度图像转换为像素值的二维矩阵,我知道它已经是像素值的二维矩阵,但是我该如何处理它......就像选择上面和下面的像素当前像素。 ??

【问题讨论】:

【参考方案1】:

这适用于 CameraPicture:

如果从不调用 setPreviewFormat(int),则默认为 YCbCr_420_SP (NV21) 格式。 http://developer.android.com/reference/android/hardware/Camera.Parameters.html#setPreviewFormat%28int%29

位图 bmp 你可以像这样配置:

Bitmap bmp = Bitmap.createBitmap(frameWidth, frameHeight, Bitmap.Config.ARGB_8888); //or RGB_565 if you prefer.

为了访问 bmp 数据,我只发现了这样的内容:http://upload.wikimedia.org/wikipedia/commons/c/c4/BMPfileFormat.png

希望对你有帮助

【讨论】:

以上是关于将位图(RGB_565)转换为灰度(8位)Android的主要内容,如果未能解决你的问题,请参考以下文章

16位bmp文件中RGB555转RGB565算法

RGB565 怎么转 RGB888

基于FPGA的RGB565_YCbCr_Gray算法实现

如何在位图 int 数组 (rgb565) 之间转换 UIImage

RGB888与RGB565互相转换原理

使用 SSE2 优化 RGB565 到 RGB888 的转换