Я работаю над приложением, которое обнаруживает края страницы, а также обнаруживает и анализирует QR-код на этой странице.Видеопоток с камеры доставляется OpenCV с использованием «JavaCameraView», а разбор QR-кода выполняется через библиотеку 'com.google.android.gms:play-services-vision:15.0.2'
.
Это работает на моем телефоне, Huawei P9 Lite 2017 с Android 8, ноне работает на некоторых других телефонах (например, Samsung SM-J510FN с Android 7.1.1, API 25).
Я предполагаю, что камера возвращает кадры разных размеров, и именно поэтому QR-кодне может быть проанализирован (камера на моем Huawei возвращает кадр 960x720, тогда как камера Samsung возвращает кадр 720x720).
Вот код, который получает кадр, а затем пытается обнаружить QR (а затем выполняетОбнаружение края и делает снимок страницы (здесь не показано)):
@Override
public Mat onCameraFrame(CameraBridgeViewBase.CvCameraViewFrame inputFrame) {
if (!isOpenCvFrameDimensionsObtained) {
openCvFrameHeight = inputFrame.rgba().height();
openCvFrameWidth = inputFrame.rgba().width();
isOpenCvFrameDimensionsObtained = true;
screenToOpenCvScreenWidthToFrameHeightRatio = (double) screenWidth / openCvFrameHeight;
screenToOpenCvScreenHeightToFrameWidthRatio = (double) screenHeight / openCvFrameWidth;
}
Mat gray = inputFrame.gray();
Mat dst = inputFrame.rgba();
Mat tmp = new Mat(openCvFrameHeight, openCvFrameWidth, CvType.CV_8U, new Scalar(4));
Imgproc.cvtColor(dst, tmp, Imgproc.COLOR_RGB2BGRA);
//try extracting the QR code from the frame
if (!isQrObtained) try {
Bitmap bmp;
bmp = Bitmap.createBitmap(tmp.cols(), tmp.rows(), Bitmap.Config.ARGB_8888);
Utils.matToBitmap(tmp, bmp);
Frame frame = new Frame.Builder().setBitmap(bmp).build();
SparseArray<Barcode> barcodes = detector.detect(frame);
if (barcodes != null && barcodes.size() > 0) {
barcode = barcodes.valueAt(0);
Gson gson = new Gson();
qrDetectionResult = gson.fromJson(barcode.displayValue, QrDetectionResult.class);
runOnUiThread(() -> Toast.makeText(this, "QR Code Scanned", Toast.LENGTH_SHORT).show());
isQrObtained = true;
Log.i("Barcode", barcode.displayValue);
}
} catch (Exception e) {
Log.d("Exception", e.getMessage());
}
Причина, по которой вы видите блок кода screenToOpenCvScreenWidthToFrameHeightRatio = (double) screenWidth / openCvFrameHeight;
screenToOpenCvScreenHeightToFrameWidthRatio = (double) screenHeight / openCvFrameWidth;
, заключается в том, что камера OpenCV поворачивается вбок, что вызывает еще большепроблемы.
Проблема возникает здесь:
SparseArray<Barcode> barcodes = detector.detect(frame);
Эта строка фактически возвращает штрих-код на моем Huawei, но возвращает "{}" на другом телефоне.
Кто-нибудь знает причину, почему это может быть?Я догадываюсь, что QR получен, но он искажен и поэтому не распознается, но я не уверен.Изменение размера inputFrame (высота, ширина) не решило проблему.
Обратите внимание, что JavaCameraView в OpenCV довольно старый и использует устаревшую Camera (не более новый Camera2 API).