Trong phương pháp của tôi, tôi sử dụng OpenCV Mat và kịch bản từ https://gist.github.com/camdenfullmer/dfd83dfb0973663a7974
Trước hết bạn chuyển đổi YUV_420_888 hình ảnh của bạn để Mat với mã trong liên kết ở trên.
* mImage là đối tượng hình ảnh của tôi mà tôi nhận được trong ImageReader.OnImageAvailableListener
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;
}
Chúng tôi có 1 kênh YUV Mát. Xác định Mat mới cho BGR (không RGB chưa) hình ảnh:
Mat bgrMat = new Mat(mImage.getHeight(), mImage.getWidth(),CvType.CV_8UC4);
Tôi chỉ mới bắt đầu học OpenCV để propably này không nhất thiết phải là 4-kênh Mat và thay vào đó có thể là 3 kênh nhưng nó làm việc cho tôi. Bây giờ tôi sử dụng phương pháp chuyển đổi màu để thay đổi yuv Mat của tôi thành bgr Mat.
Imgproc.cvtColor(mYuvMat, bgrMat, Imgproc.COLOR_YUV2BGR_I420);
Bây giờ chúng ta có thể làm tất cả những xử lý hình ảnh như tìm đường nét, màu sắc, hình tròn, vv Để in hình ảnh lại trên màn hình chúng ta cần phải chuyển nó sang bitmap:
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);
Tôi có tất cả của tôi xử lý hình ảnh trong chuỗi riêng biệt để thiết lập ImageView của tôi, tôi cần thực hiện điều này trên chuỗi giao diện người dùng.
runOnUiThread(new Runnable() {
@Override
public void run() {
if(bitmap != null) {
mImageView.setImageBitmap(bitmap);
}
}
});
thể trùng lặp của [Chuyển đổi YUV-> RGB (Xử lý ảnh) -> YUV trong onPreviewFrame trong android ?] (http://stackoverflow.com/questions/9325861/converting-yuv-rgbimage-processing-yuv-during-onpreviewframe-in-android) – JAL
Đó là để thực hiện máy ảnh cũ hơn, điều đó không giúp tôi. Cảm ơn bạn mặc dù. –
Có ai đã chuyển YUV_420_888 thành NV21 (YUV_420_SP) không? –