【发布时间】:2018-05-24 12:21:04
【问题描述】:
我正在尝试将使用 Camera 2 API 从 ImageReader 接收到的 Image 转换为 OpenCV 矩阵,并使用 CameraBridgeViewBase 将其显示在屏幕上,更具体地说是函数 deliverAndDrawFrame。读者的ImageFormat 是YUV_420_888,据我所知,它有一个Y 平面,每个像素都有一个灰度值,一个U 平面有一个U/V,每4 个像素有1 个。但是,当我尝试显示此图像时,它看起来好像图像在重复并旋转了 90 度。下面的代码应该将 YUV 数据放入 OpenCV 矩阵(现在只是灰度,不是 rgba):
/**
* Takes an {@link Image} in the {@link ImageFormat#YUV_420_888} and puts it into a provided {@link Mat} in rgba format.
*
* @param yuvImage {@link Image} in the {@link ImageFormat#YUV_420_888} format.
*/
public static void yuv420888imageToRgbaMat(final Image yuvImage, final Mat rgbaMat) {
final Image.Plane
Yp = yuvImage.getPlanes()[0],
UandVp = yuvImage.getPlanes()[1];
final ByteBuffer
Ybb = Yp .getBuffer(),
UandVbb = UandVp.getBuffer();
Ybb .get(mYdata , 0, 480*640 );
UandVbb.get(mUandVData, 0, 480*640 / 2 - 8);
for (int i = 0; i < 640*480; i++) {
for (int j = 0; j < 4; j++) {
mRawRGBAFrameData[i + 640*480*j] = mYdata[i];
}
mRawRGBAFrameData[i*4 ] = mYdata[i];
mRawRGBAFrameData[i*4+1] = mYdata[i];
mRawRGBAFrameData[i*4+2] = mYdata[i];
mRawRGBAFrameData[i*4+3] = -1;
}
}
这是我的 OpenCV 框架代码:
private class CameraFrame implements CvCameraViewFrame {
private Mat mRgba;
@Override
public Mat gray() {
return null;
}
@Override
public Mat rgba() {
mRgbaMat.put(0, 0, mRawRGBAFrameData);
return mRgba;
}
public CameraFrame(final Mat rgba) {
super();
mRgba = rgba;
}
}
接收画框代码:
private final ImageReader.OnImageAvailableListener mOnImageAvailableListener = new ImageReader.OnImageAvailableListener() {
@Override
public void onImageAvailable(ImageReader reader) {
final Image yuvImage = reader.acquireLatestImage();
yuv420888imageToRgbaMat(yuvImage, mRgbaMat);
deliverAndDrawFrame(mFrame);
yuvImage.close();
}
};
还有,这是制作图片阅读器的代码:
mRgbaMat = new Mat(mFrameHeight, mFrameWidth, CvType.CV_8UC4);
mFrame = new CameraFrame(mRgbaMat);
mImageReader = ImageReader.newInstance(mFrameWidth, mFrameHeight, ImageFormat.YUV_420_888, 1);
mImageReader.setOnImageAvailableListener(mOnImageAvailableListener, mBackgroundHandler);
AllocateCache();
这是数组的初始化:
protected static byte[] mRawRGBAFrameData = new byte[640*480*4], mYdata = new byte[640*480], mUandVData = new byte[640*480 / 2];
注意:mFrameWidth 是 480,mFrameHeight 是 640。一件奇怪的事情是,ImageReader 和从它收到的 Image 的高度和宽度具有倒置的尺寸。
这是上面代码的图像:https://i.stack.imgur.com/lcdzf.png
这是yuv420888imageToRgbaMathttps://i.stack.imgur.com/T2MOI.png中的图片
for (int i = 0; i < 640*480; i++) {
mRawRGBAFrameData[i] = mYdata[i];
}
我们可以看到数据在 Y 帧中重复,由于某种原因,这给出了一个实际好看的图像。
【问题讨论】: