Advertisement

argb888与rgb888转换程序_将Android camera2 api YUV_420_888转换为RGB

阅读量:

在我的方法中,我使用OpenCV Mat和脚本

https://gist.github.com/camdenfullmer/dfd83dfb0973663a7974

首先,使用上面链接中的代码将YUV_420_888图像转换为Mat.

  • mImage是我在ImageReader.OnImageAvailableListener中获得的Image对象

Mat mYuvMat = imageToMat(mImage);

public static Mat imageToMat(Image image) {

ByteBuffer buffer;

int rowStride;

int pixelStride;

int width = image.getWidth();

int height = image.getHeight();

int offset = 0;

Image.Plane[] planes = image.getPlanes();

byte[] data = new byte[image.getWidth() * image.getHeight() * ImageFormat.getBitsPerPixel(ImageFormat.YUV_420_888) / 8];

byte[] rowData = new byte[planes[0].getRowStride()];

for (int i = 0; i < planes.length; i++) {

buffer = planes[i].getBuffer();

rowStride = planes[i].getRowStride();

pixelStride = planes[i].getPixelStride();

int w = (i == 0) ? width : width / 2;

int h = (i == 0) ? height : height / 2;

for (int row = 0; row < h; row++) {

int bytesPerPixel = ImageFormat.getBitsPerPixel(ImageFormat.YUV_420_888) / 8;

if (pixelStride == bytesPerPixel) {

int length = w * bytesPerPixel;

buffer.get(data, offset, length);

if (h - row != 1) {

buffer.position(buffer.position() + rowStride - length);

}

offset += length;

} else {

if (h - row == 1) {

buffer.get(rowData, 0, width - pixelStride + 1);

} else {

buffer.get(rowData, 0, rowStride);

}

for (int col = 0; col < w; col++) {

data[offset++] = rowData[col * pixelStride];

}

}

}

}

Mat mat = new Mat(height + height / 2, width, CvType.CV_8UC1);

mat.put(0, 0, data);

return mat;

}

我们有1通道YUV垫.为BGR定义新的Mat(不是RGB)图像:

Mat bgrMat = new Mat(mImage.getHeight(), mImage.getWidth(),CvType.CV_8UC4);

我刚刚开始学习OpenCV,所以这可能不需要4通道Mat,而是3通道,但它对我有用.

现在我使用转换颜色方法将我的yuv Mat改为bgr Mat.

Imgproc.cvtColor(mYuvMat, bgrMat, Imgproc.COLOR_YUV2BGR_I420);

现在我们可以进行所有图像处理,例如查找轮廓,颜色,圆圈等.要在屏幕上打印图像,我们需要将其转换为位图:

Mat rgbaMatOut = new Mat();

Imgproc.cvtColor(bgrMat, rgbaMatOut, Imgproc.COLOR_BGR2RGBA, 0);

final Bitmap bitmap = Bitmap.createBitmap(bgrMat.cols(), bgrMat.rows(), Bitmap.Config.ARGB_8888);

Utils.matToBitmap(rgbaMatOut, bitmap);

我将所有图像处理都放在单独的线程中,以便设置我的ImageView,我需要在UI线程上执行此操作.

runOnUiThread(new Runnable() {

@Override

public void run() {

if(bitmap != null) {

mImageView.setImageBitmap(bitmap);

}

}

});

全部评论 (0)

还没有任何评论哟~