Android Обнаружение объекта различный результат в эмуляторе и реальном устройстве - PullRequest
0 голосов
/ 04 апреля 2020

Я обучил модель обнаружения объектов SSD-MobileNet_V1_Coco для обнаружения определенных продуктов в супермаркете. У него был хороший результат обнаружения в моем эмуляторе P C и Android Studio. Однако при установке в реальное устройство android мои приложения не могут обнаружить какой-либо продукт или имеют очень низкий уровень достоверности.

Я использую natario1 (com.otaliastud ios .cameraview .CameraView) CameraView для захвата изображения для обнаружения и Firebase Custom Model для моей модели обнаружения объектов.

Изображение, снятое для обнаружения объекта в эмуляторе

Результат обнаружения объекта в эмуляторе

Android Манифест

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    package="com.example.finalyearproject">

    <uses-permission android:name="android.permission.CAMERA" />
    <uses-permission android:name="android.permission.INTERNET" />

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme"
        tools:ignore="GoogleAppIndexingWarning">
        <activity android:name=".FavouriteActivity" />

        <meta-data
            android:name="com.google.firebase.messaging.default_notification_icon"
            android:resource="@mipmap/ic_launcher" />

        <meta-data
            android:name="com.google.firebase.messaging.default_notification_color"
            android:resource="@color/colorAccent" />

        <activity
            android:name=".ProductDetails"
            android:screenOrientation="sensorPortrait" />
        <activity
            android:name=".FirebaseDetection"
            android:noHistory="true"
            android:screenOrientation="sensorPortrait" />
        <activity
            android:name=".ScannedResultActivity"
            android:screenOrientation="sensorPortrait" />
        <activity
            android:name=".BarcodeActivity"
            android:noHistory="true"
            android:screenOrientation="sensorPortrait" />
        <activity
            android:name=".MainActivity"
            android:screenOrientation="sensorPortrait">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <service android:name=".MyFirebaseMessagingService">
            <intent-filter>
                <action android:name="com.google.firebase.MESSAGING_EVENT" />
            </intent-filter>
        </service>

        <meta-data
            android:name="com.google.firebase.ml.vision.DEPENDENCIES"
            android:value="barcode" />
    </application>

</manifest>

Макет

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".BarcodeActivity">

    <Button
        android:id="@+id/btnScan"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginStart="12dp"
        android:layout_marginEnd="12dp"
        android:layout_marginBottom="12dp"
        android:text="Scan"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent" />

    <FrameLayout
        android:id="@+id/frameLayout"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <com.otaliastudios.cameraview.CameraView
            android:id="@+id/cameraView"
            android:layout_width="match_parent"
            android:layout_height="match_parent"/>

    </FrameLayout>

</androidx.constraintlayout.widget.ConstraintLayout>

Настройка CameraView

private void setupCamera(){
        //Set up Camera
        cameraView = findViewById(R.id.cameraView);
        cameraView.setAudio(Audio.OFF);
        cameraView.setPlaySounds(false);
        cameraView.mapGesture(Gesture.TAP, GestureAction.AUTO_FOCUS);
        cameraView.setLifecycleOwner(this);
    }

onCreate

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_detection);
        cameraView = findViewById(R.id.cameraView);
        btnScan = findViewById(R.id.btnScan);
        isDetected = false;


        cameraView.addCameraListener(new CameraListener() {
            @Override
            public void onPictureTaken(@NonNull PictureResult result) {
                super.onPictureTaken(result);
                result.toBitmap(new BitmapCallback() {
                    @Override
                    public void onBitmapReady(@Nullable Bitmap bitmap) {
                        objectDetection(bitmap);
                    }
                });
            }
        });

        //Scan Button function
        btnScan.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                loadingDialog = ProgressDialog.show(FirebaseDetection.this, "",
                        "Processing. Please wait...", true);
                cameraView.takePicture();
            }
        });

        //Check Camera Permission
        Dexter.withActivity(FirebaseDetection.this)
                .withPermission(Manifest.permission.CAMERA)
                .withListener(new PermissionListener() {
                    @Override
                    public void onPermissionGranted(PermissionGrantedResponse response) {
                        setupCamera();
                    }

                    @Override
                    public void onPermissionDenied(PermissionDeniedResponse response) {
                        Toast.makeText(FirebaseDetection.this, "Camera Permission is required.", Toast.LENGTH_SHORT).show();
                        finishAffinity();
                    }

                    @Override
                    public void onPermissionRationaleShouldBeShown(PermissionRequest permission, PermissionToken token) {

                    }
                }).check();
    }

Преобразование растрового изображения в плавающее [] [] [] []

private float[][][][] convertBitmapTo4dFloat(Bitmap bitmap) {
        bitmap = Bitmap.createScaledBitmap(bitmap, 300, 300, false);
        int batchNum = 0;
        float[][][][] input = INPUT_FORMAT;
        for (int x = 0; x < 300; x++) {
            for (int y = 0; y < 300; y++) {
                int pixel = bitmap.getPixel(x, y);

                input[batchNum][x][y][0] = (Color.red(pixel) - 127.5f) / 127.5f;
                input[batchNum][x][y][1] = (Color.green(pixel) - 127.5f) / 127.5f;
                input[batchNum][x][y][2] = (Color.blue(pixel) - 127.5f) / 127.5f;
            }
        }
        return input;
    }

Обнаружение объекта

private void objectDetection(Bitmap bitmap){
        FirebaseModelInterpreter interpreter;
        try {
            float [][][][] input = convertBitmapTo4dFloat(bitmap);
            FirebaseCustomLocalModel localModel = new FirebaseCustomLocalModel.Builder()
                    .setAssetFilePath("model.tflite")
                    .build();

            FirebaseModelInterpreterOptions options =
                    new FirebaseModelInterpreterOptions.Builder(localModel).build();
            interpreter = FirebaseModelInterpreter.getInstance(options);

            FirebaseModelInputOutputOptions inputOutputOptions =
                    new FirebaseModelInputOutputOptions.Builder()
                            .setInputFormat(0, FirebaseModelDataType.FLOAT32, new int[]{1, 300, 300, 3})
                            .setOutputFormat(0, FirebaseModelDataType.FLOAT32, new int[]{1, 10, 4}) // bounding box output
                            .setOutputFormat(1, FirebaseModelDataType.FLOAT32, new int[]{1, 10}) // classes number output
                            .setOutputFormat(2, FirebaseModelDataType.FLOAT32, new int[]{1, 10}) // confidence level output
                            .build();
            FirebaseModelInputs inputs = new FirebaseModelInputs.Builder()
                    .add(input)  // add() as many input arrays as your model requires
                    .build();
            interpreter.run(inputs, inputOutputOptions)
                    .addOnSuccessListener(
                            new OnSuccessListener<FirebaseModelOutputs>() {
                                @Override
                                public void onSuccess(FirebaseModelOutputs result) {
                                    float[][][] boxes_array = result.getOutput(0); // position of detected item
                                    float[][] classes_array = result.getOutput(1); // classes number (item in label.txt)
                                    float[][] confidence_array = result.getOutput(2); // confidence level on detected item
                                    float[] classes = classes_array[0];
                                    float[] confidence = confidence_array[0];
                                    ArrayList<String> className = new ArrayList<>();
                                    String[] item = new String[10];
                                    try {
                                        BufferedReader reader = new BufferedReader(
                                                new InputStreamReader(getAssets().open("label.txt")));
                                        String label;
                                        while( (label = reader.readLine()) != null) {
                                            className.add(label);
                                        }

                                    } catch (IOException e) {
                                        e.printStackTrace();
                                    }

                                    for (int i = 0; i<item.length;i++){
                                        int classId = (int) classes[i];
                                        item[i] = className.get(classId);
                                        Log.d("TAG_DETECT",item[i] + ": " + confidence[i]);
                                    }

                                    Bundle detectedProduct = new Bundle();
                                    detectedProduct.putStringArray("name",item);
                                    detectedProduct.putFloatArray("confidence",confidence);
                                    Intent intent = new Intent(getBaseContext(),ScannedResultActivity.class);
                                    intent.putExtra("detectedProduct",detectedProduct);
                                    intent.putExtra("method","detect");
                                    loadingDialog.dismiss();
                                    startActivity(intent);
                                }
                            })
                    .addOnFailureListener(
                            new OnFailureListener() {
                                @Override
                                public void onFailure(@NonNull Exception e) {
                                    Log.d("TAG_ERROR2:", e.getMessage());
                                }
                            });
        } catch (FirebaseMLException e) {
            Log.d("TAG_ERROR:", e.getMessage());
        }

    }

Нужно ли что-то добавить в мои коды для реального Android для работы или что-то еще? Извините, если мои коды грязные. Спасибо

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...