Tôi đang cố gắng lưu chuỗi hình ảnh với khung hình cố định (tốt nhất là tối đa 30) trên thiết bị Android có khả năng FULL cho camera2 (Galaxy S7), nhưng tôi không thể a) có tốc độ khung hình ổn định, b) đạt đến 20fps (với mã hóa jpeg). Tôi đã bao gồm các đề xuất từ Android camera2 capture burst is too slow.Android camera2 jpeg framerate
Thời gian khung tối thiểu đối với JPEG là 33,33 mili giây (đối với độ phân giải thấp hơn 1920x1080) theo
characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP).getOutputMinFrameDuration(ImageFormat.JPEG, size);
và stallduration là 0ms cho mỗi kích thước (tương tự cho YUV_420_888).
builder chụp của tôi trông như sau:
captureBuilder.set(CaptureRequest.CONTROL_AE_MODE, CONTROL_AE_MODE_OFF);
captureBuilder.set(CaptureRequest.SENSOR_EXPOSURE_TIME, _exp_time);
captureBuilder.set(CaptureRequest.CONTROL_AE_LOCK, true);
captureBuilder.set(CaptureRequest.SENSOR_SENSITIVITY, _iso_value);
captureBuilder.set(CaptureRequest.LENS_FOCUS_DISTANCE, _foc_dist);
captureBuilder.set(CaptureRequest.CONTROL_AF_MODE, CONTROL_AF_MODE_OFF);
captureBuilder.set(CaptureRequest.CONTROL_AWB_MODE, _wb_value);
// https://stackoverflow.com/questions/29265126/android-camera2-capture-burst-is-too-slow
captureBuilder.set(CaptureRequest.EDGE_MODE,CaptureRequest.EDGE_MODE_OFF);
captureBuilder.set(CaptureRequest.COLOR_CORRECTION_ABERRATION_MODE, CaptureRequest.COLOR_CORRECTION_ABERRATION_MODE_OFF);
captureBuilder.set(CaptureRequest.NOISE_REDUCTION_MODE, CaptureRequest.NOISE_REDUCTION_MODE_OFF);
captureBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER, CaptureRequest.CONTROL_AF_TRIGGER_CANCEL);
// Orientation
int rotation = getWindowManager().getDefaultDisplay().getRotation();
captureBuilder.set(CaptureRequest.JPEG_ORIENTATION,ORIENTATIONS.get(rotation));
Focus khoảng cách được thiết lập để 0.0 (inf), iso được thiết lập đến 100, tiếp xúc với thời gian đáp ứng 5ms. Độ trắng có thể được đặt thành TẮT/TỰ ĐỘNG/BẤT K VALUE GIÁ TRỊ, nó không ảnh hưởng đến thời gian dưới đây.
tôi bắt đầu phiên chụp với lệnh sau đây:
session.setRepeatingRequest(_capReq.build(), captureListener, mBackgroundHandler);
Lưu ý: Nó không tạo sự khác biệt nếu tôi yêu cầu RepeatingRequest hoặc RepeatingBurst ..
Trong preview (chỉ bề mặt kết cấu kèm theo) , mọi thứ ở tốc độ 30 khung hình/giây. Tuy nhiên, ngay sau khi tôi đính kèm một đầu đọc hình ảnh (listener chạy trên HandlerThread) mà tôi nhanh chóng như sau (mà không lưu, thời gian chỉ đo giữa khung):
reader = ImageReader.newInstance(_img_width, _img_height, ImageFormat.JPEG, 2);
reader.setOnImageAvailableListener(readerListener, mBackgroundHandler);
Với mã thời gian đo:
ImageReader.OnImageAvailableListener readerListener = new ImageReader.OnImageAvailableListener() {
@Override
public void onImageAvailable(ImageReader myreader) {
Image image = null;
image = myreader.acquireNextImage();
if (image == null) {
return;
}
long curr = image.getTimestamp();
Log.d("curr- _last_ts", "" + ((curr - last_ts)/1000000) + " ms");
last_ts = curr;
image.close();
}
}
tôi nhận được định kỳ lặp đi lặp lại thời gian khác nhau như thế này:
99 ms - 66 ms - 66 ms - 99 ms - 66 ms - 66 ms ...
Tôi không hiểu tại sao chúng lại tăng gấp đôi hoặc gấp ba lần thời gian mà bản đồ cấu hình luồng được quảng cáo cho jpeg? Thời gian phơi sáng thấp hơn thời lượng khung 33ms. Có một số xử lý nội bộ khác xảy ra mà tôi không biết?
Tôi đã thử cùng định dạng YUV_420_888, dẫn đến chênh lệch thời gian không đổi là 33ms. Vấn đề tôi có ở đây là điện thoại di động thiếu băng thông để lưu trữ hình ảnh đủ nhanh (tôi đã thử phương pháp được mô tả trong How to save a YUV_420_888 image?). Nếu bạn biết cách nào để nén hoặc mã hóa những hình ảnh này đủ nhanh, hãy cho tôi biết.
Chỉnh sửa: Từ tài liệu getOutputStallDuration: "Nói cách khác, sử dụng yêu cầu YUV lặp lại sẽ dẫn đến tốc độ khung hình ổn định (giả sử là 30 FPS). Nếu một yêu cầu JPEG được gửi định kỳ, tốc độ khung hình sẽ ở mức 30 FPS (miễn là chúng tôi đợi cho ảnh JPEG trước đó quay trở lại mỗi lần). Nếu chúng tôi cố gắng gửi yêu cầu YUV + JPEG lặp lại, thì tốc độ khung hình sẽ giảm từ 30 FPS. " Điều này có nghĩa là tôi cần phải định kỳ yêu cầu một lần chụp()?
Chỉnh sửa2: Từ https://developer.android.com/reference/android/hardware/camera2/CaptureRequest.html: "Thông tin cần thiết cho ứng dụng, được cung cấp mô hình ở trên, được cung cấp qua trường Android.scaler.streamConfigurationMap sử dụng getOutputMinFrameDuration (int, Size). Các giá trị này được sử dụng để xác định tốc độ khung hình tối đa/thời lượng khung tối thiểu có thể cho một cấu hình luồng nhất định.
Cụ thể, ứng dụng có thể sử dụng các quy tắc sau đây để xác định thời gian tối thiểu khung nó có thể yêu cầu từ thiết bị camera:
Hãy tập các đầu vào hiện cấu hình/suối đầu ra được gọi là S. Tìm khung tối thiểu thời lượng cho mỗi luồng trong S, bằng cách tìm kiếm nó trong android.scaler.streamConfigurationMap bằng cách sử dụng getOutputMinFrameDuration (int, Size) (với kích thước/định dạng tương ứng của nó). Để khoảng thời gian khung này được gọi là F. Đối với bất kỳ yêu cầu R nào, thời lượng khung tối thiểu được phép cho R là giá trị tối đa trong tất cả các giá trị trong F. Cho phép các luồng được sử dụng trong R được gọi là S_r. Nếu không có luồng nào trong S_r có thời gian dừng (được liệt kê trong getOutputStallDuration (int, Size) sử dụng kích thước/định dạng tương ứng), thì thời lượng khung trong F xác định tỷ lệ khung hình trạng thái ổn định mà ứng dụng sẽ nhận được nếu nó sử dụng R như một yêu cầu lặp lại."
Nếu bạn đang chụp dưới dạng JPEG, bạn cần chờ bộ mã hóa nén mỗi khung hình. Chụp dưới dạng YUV_420_888 lấy hình ảnh máy ảnh thô mà không cần nén. Bạn có khả năng có thể thử chạy JPEG nén trên các chủ đề khác, nhưng sau đó bạn có thể sẽ thấy rằng bạn áp đảo các giới hạn nhiệt của CPU trong một phút chạy. Bạn có chắc chắn rằng ngay cả phần cứng mã hóa JPEG có khả năng chạy ở tốc độ 30fps với độ phân giải đã chọn không? Có vẻ như không phải vậy. Tùy chọn của bạn dường như là: giảm độ phân giải hoặc tốc độ khung hình. – BitBank
Vui lòng xem Chỉnh sửa2, quá dài để nhận xét. Từ tuyên bố này và các giá trị trên, sự hiểu biết của tôi là 30fps jpeg nên có thể. – TobiasWeis
Có vẻ như bạn đã đọc tài liệu chính xác, nhưng nó không thực sự rõ ràng nếu bạn có thể chụp toàn bộ khung hình JPEG. Tôi nghĩ rằng kinh nghiệm của bạn với nó cho thấy rằng nó sẽ không cung cấp tốc độ khung hình mong muốn. – BitBank