
У меня есть две йо-модели. обнаружение первого лотка для желтков, обнаружение второго лотка для желтков. Обрезка выполняется после обнаружения лотка.
mappedRecognitions.add(result);//rayyolo.tflite первый результат модели yolov5 «откладывает» свои работы
mappedRecognitions.add(result1);// результат модели vggclass.tflite vgg16 "eveningTray" работает
Часть моего вопроса: я хочу запустить свою вторую модель yolov5. (foodtype.tflite) результат метки, например: суп, основное блюдо, напиток, хлеб. Если DinnerTray, модель foodtype.tflite будет работать
Ярлыки для foodtype.tflite верны, но почему такое расположение? Как я могу исправить? Буду рад любому совету.
DetectorActivity.java
публичный класс DetectorActivity расширяет CameraActivity реализует OnImageAvailableListener { частный статический окончательный Logger LOGGER = новый Logger(); частный статический окончательный int TF_OD_API_INPUT_SIZE = 1024; частный статический окончательный логический параметр TF_OD_API_IS_QUANTIZED = false; частная статическая окончательная строка TF_OD_API_MODEL_FILE = "trayyolo.tflite"; частная статическая финальная строка TF_OD_API_LABELS_FILE = «customclasses.txt»; частный статический окончательный int TF_OD_API_INPUT_SIZEE = 608; частная статическая окончательная строка TF_OD_API_MODEL_FILEE = "vggclass.tflite"; частный статический окончательный режим DetectorMode = DetectorMode.TF_OD_API; частный статический конечный float MINIMUM_CONFIDENCE_TF_OD_API = 0.3f; частный статический окончательный логический MAINTAIN_ASPECT = true; частный статический окончательный размер DESIRED_PREVIEW_SIZE = новый размер (640, 640); частное статическое окончательное логическое значение SAVE_PREVIEW_BITMAP = false; частный статический финальный float TEXT_SIZE_DIP = 10; OverlayView отслеживаниеOverlay; частный целочисленный датчик ориентации; частный детектор YoloV5Classifier; частный детектор йени2; частный длинный LastProcessingTimeMs; частный Bitmap rgbFrameBitmap = null; частное растровое изображение CropedBitmap = null; частное растровое изображение CropCopyBitmap = null; частное растровое изображение xyBitmap = null; частное растровое изображение copyOfOfOriginalBitmap = null; частные логические вычисленияОбнаружение = ложь; частная длинная временная метка = 0; частная матрицаframeToCropTransform; частная матрица CropToFrameTransform; частный трекер MultiBoxTracker; частный MultiBoxTracker2 tracker2; частный BorderedText borderedText; частный детектор TFLiteObjectDetectionAPIMode1; @Override public void onPreviewSizeChosen (окончательный размер размера, окончательное вращение int) { окончательное число с плавающей запятой textSizePx = TypedValue.applyDimension( TypedValue.COMPLEX_UNIT_DIP, TEXT_SIZE_DIP, getResources().getDisplayMetrics()); borderedText = новый BorderedText(textSizePx); borderedText.setTypeface(Typeface.MONOSPACE); трекер = новый MultiBoxTracker(это); tracker2 = новый MultiBoxTracker2(это); окончательный int modelIndex = modelView.getCheckedItemPosition(); окончательная строка modelString = modelStrings.get(modelIndex); пытаться { детектор = DetectorFactory.getDetector(getAssets(), modelString); } catch (окончательное IOException e) { е.printStackTrace(); LOGGER.e(e, "Классификатор, инициализирующий исключение!"); Тост тост = Toast.makeText( getApplicationContext(), «Не удалось инициализировать классификатор», Toast.LENGTH_SHORT); тост.шоу(); заканчивать(); } intcropSize = детектор.getInputSize(); предварительный просмотрWidth = size.getWidth(); предварительный просмотрHeight = size.getHeight(); int targetW = (int) (previewWidth/2.0); int targetH = (int) (previewHeight/2.0); SensorOrientation = вращение - getScreenOrientation(); LOGGER.i("Ориентация камеры относительно холста экрана: %d", SensorOrientation); LOGGER.i("Инициализация размером %dx%d",viewWidth,viewHeight); rgbFrameBitmap = Bitmap.createBitmap(previewWidth, PreviewHeight, Config.ARGB_8888); CropedBitmap = Bitmap.createBitmap(cropSize, CropSize, Config.ARGB_8888); xyBitmap = Bitmap.createBitmap(targetW, targetH, Config.ARGB_8888); фреймToCropTransform = ImageUtils.getTransformationMatrix( предварительный просмотрШирина, предварительный просмотрВысота, размер обрезки, SensorOrientation, MAINTAIN_ASPECT); CropToFrameTransform = новая матрица (); FrameToCropTransform.invert(cropToFrameTransform); TrackingOverlay = (OverlayView) findViewById(R.id.tracking_overlay); trackOverlay.addCallback( новый DrawCallback() { @Override public void drawCallback (окончательный холст Canvas) { tracker.draw(холст); если (isDebug()) { tracker.drawDebug(холст); } } }); tracker.setFrameConfiguration(previewWidth, PreviewHeight, SensorOrientation); OverlayView TrackingOverlay2 = (OverlayView) findViewById(R.id.tracking_overlay); trackOverlay2.addCallback( новый DrawCallback() { @Override public void drawCallback (окончательный холст Canvas1) { tracker2.draw(холст1); если (isDebug()) { tracker2.drawDebug(canvas1); } } }); tracker2.setFrameConfiguration(previewWidth, PreviewHeight, SensorOrientation); пытаться { детектор1 = (TFLiteObjectDetectionAPIModel) TFLiteObjectDetectionAPIModel.create( этот, TF_OD_API_MODEL_FILEE, TF_OD_API_LABELS_FILE, TF_OD_API_INPUT_SIZEE, TF_OD_API_IS_QUANTIZED); cropSize = TF_OD_API_INPUT_SIZE; } catch (окончательное IOException e) { е.printStackTrace(); LOGGER.e(e, "Классификатор, инициализирующий исключение!"); Тост тост = Toast.makeText( getApplicationContext(), «Не удалось инициализировать классификатор», Toast.LENGTH_SHORT); тост.шоу(); заканчивать(); } пытаться { окончательная строка modelString1 = modelStrings.get(6); детектор2 = DetectorFactoryaksam.getDetector(getAssets(), modelString1); } catch (окончательное IOException e) { е.printStackTrace(); LOGGER.e(e, "Классификатор, инициализирующий исключение!"); Тост тост = Toast.makeText( getApplicationContext(), «Не удалось инициализировать классификатор», Toast.LENGTH_SHORT); тост.шоу(); заканчивать(); } } защищенный недействительный updateActiveModel () { // Получаем информацию пользовательского интерфейса перед делегированием в фоновый режим окончательный int modelIndex = modelView.getCheckedItemPosition(); окончательный int deviceIndex = deviceView.getCheckedItemPosition(); Строковые потоки = threadsTextView.getText().toString().trim(); окончательный int numThreads = Integer.parseInt(threads); handler.post(() -> { if (modelIndex == currentModel && deviceIndex == currentDevice && numThreads == currentNumThreads) { возвращаться; } текущаяМодель = Индексмодели; CurrentDevice = DeviceIndex; currentNumThreads = numThreads; // Отключаем классификатор при обновлении если (детектор != ноль) { детектор.закрыть(); детектор = ноль; } // Ищем имена параметров. Строка modelString = modelStrings.get(modelIndex); Строковое устройство = deviceStrings.get(deviceIndex); Строка modelString2 = modelStrings.get(6); LOGGER.i("Изменение модели на " + modelString + " устройство " + устройство); // Попытаемся загрузить модель. пытаться { детектор = DetectorFactory.getDetector(getAssets(), modelString); детектор2 = DetectorFactoryaksam.getDetector(getAssets(), modelString2); // Настраиваем интерпретатор в соответствии с типом устройства, которое мы хотим использовать. if (детектор == ноль || детектор2 == ноль) { возвращаться; } } catch(IOException е) { е.printStackTrace(); LOGGER.e(e, «Исключение в updateActiveModel()»); Тост тост = Toast.makeText( getApplicationContext(), «Не удалось инициализировать классификатор», Toast.LENGTH_SHORT); тост.шоу(); заканчивать(); } если (device.equals("ЦП")) { детектор.useCPU(); детектор2.useCPU(); } else if (device.equals("GPU")) { детектор.useGpu(); детектор2.useGpu(); } else if (device.equals("NNAPI")) { детектор.useNNAPI(); детектор2.useNNAPI(); } детектор.setNumThreads(numThreads); детектор2.setNumThreads(numThreads); intcropSize = детектор.getInputSize(); CropedBitmap = Bitmap.createBitmap(cropSize, CropSize, Config.ARGB_8888); фреймToCropTransform = ImageUtils.getTransformationMatrix( предварительный просмотрШирина, предварительный просмотрВысота, размер обрезки, SensorOrientation, MAINTAIN_ASPECT); CropToFrameTransform = новая матрица (); FrameToCropTransform.invert(cropToFrameTransform); }); } @Override защищенный недействительный процессImage() { ++метка времени; окончательный длинный currTimestamp = метка времени; trackOverlay.postInvalidate(); // Мьютекс не требуется, поскольку этот метод не является реентерабельным. если (вычислениеобнаружения) { готовДляСледующегоИзображения(); возвращаться; } ВычислениеОбнаружение = правда; LOGGER.i("Подготовка изображения " + currTimestamp + " для обнаружения в потоке bg."); rgbFrameBitmap.setPixels(getRgbBytes(), 0, PreviewWidth, 0, 0, PreviewWidth, PreviewHeight); готовДляСледующегоИзображения(); окончательный холст холста = новый холст (обрезанный битмап); Canvas.drawBitmap(rgbFrameBitmap,frameToCropTransform, ноль); // Для проверки фактических входных данных TF. если (SAVE_PREVIEW_BITMAP) { ImageUtils.saveBitmap(croppedBitmap); } runInBackground (новый Runnable () { @Override общественный недействительный запуск () { LOGGER.i("Выполняется обнаружение изображения " + currTimestamp); окончательный длинный startTime = SystemClock.uptimeMillis(); окончательный список результаты = детектор.recounceeImage(croppedBitmap); LastProcessingTimeMs = SystemClock.uptimeMillis() - startTime; Log.e("ПРОВЕРИТЬ", "запустить: " + results.size()); CropCopyBitmap = Bitmap.createBitmap(croppedBitmap); окончательный холст Canvas = новый холст (cropCopyBitmap); окончательная краска Paint = новая краска(); краска.setColor(Цвет.КРАСНЫЙ); краска.setStyle(Стиль.ОБРАТ); Paint.setStrokeWidth(2.0f); поплавок минимумConfidence = MINIMUM_CONFIDENCE_TF_OD_API; окончательный список mappedRecognitionsmy = новый LinkedList(); окончательный список mappedRecognitions = новый LinkedList(); for (окончательный результат Classifier.Recognition: результаты) { окончательное местоположение RectF = result.getLocation(); если (местоположение != ноль && result.getConfidence() >= minConfidence) { Canvas.drawRect(местоположение, краска); cropToFrameTransform.mapRect(местоположение); result.setLocation(местоположение); mappedRecognitions.add(результат); //ОБРЕЗАТЬ Растровое изображение copyOfOriginalBitmap = rgbFrameBitmap.copy(rgbFrameBitmap.getConfig(), true); Растровое изображение SecondBitmap = Bitmap.createBitmap(copyOfOriginalBitmap, (int) location.left, (int) location.top, (int) location.right - (int) location.left, (int) location.bottom - (int) location.top); Растровое изображение SecondScaledBitmap = Bitmap.createScaledBitmap( SecondBitmap, 608, 608, true); окончательная строка resultLabel = детектор1.распознатьизображение1(второйScaledBitmap); Плавающая уверенность = -1f; окончательный Классификатор.Результат Распознания1 = новый Классификатор.Распознавание( «0», resultLabel, достоверность, местоположение); result1.setLocation(местоположение); mappedRecognitions.add(результат1); окончательный холст Canvas1 = новый холст (второйScaledBitmap); // Обработка с детектором2 если (второйScaledBitmap!= ноль) { if (resultLabel.equals("eveningTray")) { Матрица матрица = новая матрица(); матрица.postRotate(90); Растровое изображение RotadSecondScaledBitmap = Bitmap.createBitmap( SecondScaledBitmap, 0, 0, SecondScaledBitmap.getWidth(), SecondScaledBitmap.getHeight(), матрица, true); окончательный ArrayList результаты = детектор2.распознатьImage2(rotatedSecondScaledBitmap); for (окончательный ClassifierThree.Recognition result2: результаты) { окончательное местоположение RectF2 = result2.getLocation(); if (location2 != null && result2.getConfidence() >= minConfidence) { Canvas1.drawRect(location2, краска); Canvas1.rotate(90, Canvas1.getWidth()/2, Canvas1.getHeight()/2); cropToFrameTransform.mapRect(location2); result2.setLocation(location2); mappedRecognitionsmy.add(результат2); tracker2.trackResults(mappedRecognitionsmy, currTimestamp); } } } } } } tracker.trackResults(mappedRecognitions, currTimestamp); trackOverlay.postInvalidate(); ВычислениеОбнаружение = ложь; runOnUiThread (новый Runnable () { @Override общественный недействительный запуск () { showFrameInfo(previewWidth + "x" +viewHeight); showCropInfo(cropCopyBitmap.getWidth() + "x" +cropCopyBitmap.getHeight()); showInference (lastProcessingTimeMs + «мс»); } }); } }); } @Override защищенный int getLayoutId() { вернуть R.layout.tfe_od_camera_connection_fragment_tracking; } @Override защищенный размер getDesiredPreviewFrameSize() { вернуть DESIRED_PREVIEW_SIZE; } // Какую модель обнаружения использовать: по умолчанию используется замороженный API обнаружения объектов Tensorflow // контрольные точки. частное перечисление DetectorMode { TF_OD_API; } @Override protected void setUseNNAPI (окончательное логическое значение isChecked) { runInBackground(() -> детектор.setUseNNAPI(isChecked)); } @Override protected void setNumThreads(final int numThreads) { runInBackground(() -> детектор.setNumThreads(numThreads)); } } Здесь работает первый йоло
@Override защищенный недействительный процессImage() { ++метка времени; окончательный длинный currTimestamp = метка времени; trackOverlay.postInvalidate(); // Мьютекс не требуется, поскольку этот метод не является реентерабельным. если (вычислениеобнаружения) { готовДляСледующегоИзображения(); возвращаться; } ВычислениеОбнаружение = правда; LOGGER.i("Подготовка изображения " + currTimestamp + " для обнаружения в потоке bg."); rgbFrameBitmap.setPixels(getRgbBytes(), 0, PreviewWidth, 0, 0, PreviewWidth, PreviewHeight); готовДляСледующегоИзображения(); окончательный холст холста = новый холст (обрезанный битмап); Canvas.drawBitmap(rgbFrameBitmap,frameToCropTransform, ноль); // Для проверки фактических входных данных TF. если (SAVE_PREVIEW_BITMAP) { ImageUtils.saveBitmap(croppedBitmap); } runInBackground (новый Runnable () { @Override общественный недействительный запуск () { LOGGER.i("Выполняется обнаружение изображения " + currTimestamp); окончательный длинный startTime = SystemClock.uptimeMillis(); окончательный список результаты = детектор.recounceeImage(croppedBitmap); LastProcessingTimeMs = SystemClock.uptimeMillis() - startTime; Log.e("ПРОВЕРИТЬ", "запустить: " + results.size()); CropCopyBitmap = Bitmap.createBitmap(croppedBitmap); окончательный холст Canvas = новый холст (cropCopyBitmap); окончательная краска Paint = новая краска(); краска.setColor(Цвет.КРАСНЫЙ); краска.setStyle(Стиль.ОБРАТ); Paint.setStrokeWidth(2.0f); поплавок минимумConfidence = MINIMUM_CONFIDENCE_TF_OD_API; окончательный список mappedRecognitionsmy = новый LinkedList(); окончательный список mappedRecognitions = новый LinkedList(); for (окончательный результат Classifier.Recognition: результаты) { окончательное местоположение RectF = result.getLocation(); if (location != null && result.getConfidence() >= minConfidence) { Canvas.drawRect(местоположение, краска); cropToFrameTransform.mapRect(местоположение); result.setLocation(местоположение); mappedRecognitions.add(результат); Здесь работает второй йоло
if ( SecondScaledBitmap != null) { if (resultLabel.equals("eveningTray")) { Матрица матрица = новая матрица(); матрица.postRotate(90); Растровое изображение RotadSecondScaledBitmap = Bitmap.createBitmap( SecondScaledBitmap, 0, 0, SecondScaledBitmap.getWidth(), SecondScaledBitmap.getHeight(), матрица, true); окончательный ArrayList результаты = детектор2.распознатьImage2(rotatedSecondScaledBitmap); for (окончательный ClassifierThree.Recognition result2: результаты) { окончательное местоположение RectF2 = result2.getLocation(); if (location2 != null && result2.getConfidence() >= minConfidence) { Canvas1.drawRect(location2, краска); Canvas1.rotate(90, Canvas1.getWidth()/2, Canvas1.getHeight()/2); cropToFrameTransform.mapRect(location2); result2.setLocation(location2); mappedRecognitionsmy.add(результат2); tracker2.trackResults(mappedRecognitionsmy, currTimestamp); } } }
Мобильная версия