Как распознать достопримечательности с помощью комплекта Firebase ML? - PullRequest
0 голосов
/ 05 мая 2019

Я создаю приложение для распознавания ориентиров.Когда изображение распознано, результат должен упасть до onSuccess, но вместо этого доходит до onFailure.

В журнале отображается следующее сообщение:

Если вы не настроили выставление счетовперейдите в консоль Firebase, чтобы настроить выставление счетов: https://firebase.corp.google.com/u/0/project/_/overview?purchaseBillingPlan= true

Если вы указываете отладку переопределения ключа API и включаете ограничения ключа API, убедитесь, что ограничения установленыправильно.

Когда я нажимаю на ссылку, я вижу следующую страницу: https://login.corp.google.com/request?s=firebase.corp.google.com:443/uberproxy/&d=https://firebase.corp.google.com/u/0/project/_/overview%3FpurchaseBillingPlan%3Dtrue%26upxsrf%3DAKKYJRc2HD6ROcy9V9DxnYxw-pd8yGnml-oEi37m5hKhkWurWQ:1557057663745&maxAge=1200&authLevel=2000000&keyIds=X-q,k02

Что мне нужно сделать?

открытый класс RecognizeLandmarksextends AppCompatActivity {

EditText mResultEt;
ImageView mPreviewIv;
TextView tvLName, tvLiD, tvLConfidence, tvLlatitude, tvLlongitude;

public static final int CAMERA_REQUEST_CODE = 200;
public static final int STORAGE_REQUEST_CODE = 400;
public static final int IMAGE_PIC_GALLERY_CODE = 1000;
public static final int IMAGE_PIC_CAMERA_CODE = 1001;

private static final String TAG = "MyLog";

String cameraPermission[];
String storagePermission[];

Uri image_uri;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_recognize_landmarks);

    androidx.appcompat.app.ActionBar actionBar = getSupportActionBar();
    actionBar.setSubtitle("Click image button to insert Image");

    mResultEt = findViewById(R.id.resultEt);
    mPreviewIv = findViewById(R.id.imageIv);
    tvLName = findViewById(R.id.tvLName);
    tvLiD = findViewById(R.id.tvLiD);
    tvLConfidence = findViewById(R.id.tvLConfidence);
    tvLlatitude = findViewById(R.id.tvLlatitude);
    tvLlongitude = findViewById(R.id.tvLlongitude);

    //camera permission
    cameraPermission = new String[]{Manifest.permission.CAMERA,
            Manifest.permission.WRITE_EXTERNAL_STORAGE};
    //storage permission
    storagePermission = new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE};
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    //inflate menu
    getMenuInflater().inflate(R.menu.menu_recognize_text, menu);
    return true;
}

//handle actionbar item clicks

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    int id = item.getItemId( );
    if (id == R.id.addImage) {
        showImageImportDialog( );
    }
    if (id == R.id.settings) {
        Toast.makeText(this, "Settings", Toast.LENGTH_SHORT).show( );
    }
    return super.onOptionsItemSelected(item);
}

private void showImageImportDialog() {
    // items to display in dialog
    String[] items = {" Camera", " Gallery"};
    AlertDialog.Builder dialog = new AlertDialog.Builder(this);
    dialog.setTitle("Select Image");
    dialog.setItems(items, new DialogInterface.OnClickListener( ) {
        @Override
        public void onClick(DialogInterface dialogInterface, int i) {
            if (i == 0) {
                //camera option clicked
                /*for os Marshmallow and above we need to ask runtime permission for camera and storage*/
                if (!checkCameraPermission()) {
                    //camera permission not allowed, request it
                    requestCameraPermission();
                } else {
                    //permission allowed, take picture
                    pickCamera();
                }
            }
            if (i == 1) {
                //gallery option clicked
                if (!checkStoragePermission()) {
                    //storage permission not allowed, request it
                    requestStoragePermission();
                } else {
                    //permission allowed, take picture
                    pickGallery();
                }
            }
        }
    });
    dialog.create().show();
}

private void pickGallery() {
    //intent to pick image from gallery
    Intent intent = new Intent(Intent.ACTION_PICK);
    //set intent type to image
    intent.setType("image/*");
    startActivityForResult(intent, IMAGE_PIC_GALLERY_CODE);
}

private void pickCamera() {
    //intent to take image from camera, it will also be save to storage to get high quality image
    ContentValues values = new ContentValues( );
    values.put(MediaStore.Images.Media.TITLE, "NewPic"); //title of the picture
    values.put(MediaStore.Images.Media.DESCRIPTION, "Image to text"); //description
    image_uri = getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);

    Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, image_uri);
    startActivityForResult(cameraIntent, IMAGE_PIC_CAMERA_CODE);
}

private void requestStoragePermission() {
    ActivityCompat.requestPermissions(this, storagePermission, STORAGE_REQUEST_CODE);
}

private boolean checkStoragePermission() {
    boolean result = ContextCompat.checkSelfPermission(this,
            Manifest.permission.WRITE_EXTERNAL_STORAGE) == (PackageManager.PERMISSION_GRANTED);
    return result;
}

private void requestCameraPermission() {
    ActivityCompat.requestPermissions(this, cameraPermission, CAMERA_REQUEST_CODE);
}

private boolean checkCameraPermission() {
    /*Check camera permission and return the result
     * in order to get high quality image we have to save image to external storage first
     * before inserting to image view that`s why storage permission will also be required */
    boolean result = ContextCompat.checkSelfPermission(this,
            Manifest.permission.CAMERA) == (PackageManager.PERMISSION_GRANTED);
    boolean result1 = ContextCompat.checkSelfPermission(this,
            Manifest.permission.WRITE_EXTERNAL_STORAGE) == (PackageManager.PERMISSION_GRANTED);
    return result && result1;
}

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    switch (requestCode) {
        case CAMERA_REQUEST_CODE:
            if (grantResults.length > 0) {
                boolean cameraAccepted = grantResults[0] ==
                        PackageManager.PERMISSION_GRANTED;
                boolean writeStorageAccepted = grantResults[0] ==
                        PackageManager.PERMISSION_GRANTED;
                if (cameraAccepted && writeStorageAccepted) {
                    pickCamera();
                } else {
                    Toast.makeText(this, "permission denied", Toast.LENGTH_SHORT).show( );
                }
            }
            break;
        case STORAGE_REQUEST_CODE:
            if (grantResults.length > 0) {
                boolean writeStorageAccepted = grantResults[0] ==
                        PackageManager.PERMISSION_GRANTED;
                if (writeStorageAccepted) {
                    pickGallery( );
                }
                else {
                    Toast.makeText(this, "permission denied", Toast.LENGTH_SHORT).show( );
                }
            }
            break;
    }
}

@Override
public void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
    //got image from camera or gallery
    super.onActivityResult(requestCode, resultCode, data);
    if (resultCode == RESULT_OK) {
        if (requestCode == IMAGE_PIC_GALLERY_CODE) {
            //got image from gallery now crop it
            CropImage.activity(data.getData( ))
                    .setGuidelines(CropImageView.Guidelines.ON) // enable image guidelines
                    .start(this);
        }
        if (requestCode == IMAGE_PIC_CAMERA_CODE) {
            //got image from camera crop it
            CropImage.activity(image_uri)
                    .setGuidelines(CropImageView.Guidelines.ON) // enable image guidelines
                    .start(this);
        }
    }
    //get cropped image
    if (requestCode == CropImage.CROP_IMAGE_ACTIVITY_REQUEST_CODE) {
        CropImage.ActivityResult result1 = CropImage.getActivityResult(data);
        if (resultCode == RESULT_OK) {
            Uri resultUri = result1.getUri( ); // get image uri
            //set image to image view
            mPreviewIv.setImageURI(resultUri);// past image in iV


            //get drawable bitmap for text recognition
            BitmapDrawable bitmapDrawable = (BitmapDrawable) mPreviewIv.getDrawable( );
            Bitmap bitmap = bitmapDrawable.getBitmap( );

            FirebaseVisionImage image = FirebaseVisionImage.fromBitmap(bitmap);

            FirebaseVisionCloudDetectorOptions options =
                    new FirebaseVisionCloudDetectorOptions.Builder( )
                            .setModelType(FirebaseVisionCloudDetectorOptions.LATEST_MODEL)
                            .setMaxResults(15)
                            .build( );

            FirebaseVisionCloudLandmarkDetector detector = FirebaseVision.getInstance( )
                    .getVisionCloudLandmarkDetector(options);

            Task<List<FirebaseVisionCloudLandmark>> result = detector.detectInImage(image)
                    .addOnSuccessListener(new OnSuccessListener<List<FirebaseVisionCloudLandmark>>( ) {
                        @Override
                        public void onSuccess(List<FirebaseVisionCloudLandmark> firebaseVisionCloudLandmarks) {
                            // Task completed successfully
                            // ...
                            for(FirebaseVisionCloudLandmark landmark : firebaseVisionCloudLandmarks) {

                                //Rect bounds = landmark.getBoundingBox();
                                String landmarkName = landmark.getLandmark( );
                                tvLName.setText(landmarkName);
                                String entityId = landmark.getEntityId( );
                                tvLiD.setText(entityId);
                                float confidence = landmark.getConfidence( );
                                tvLConfidence.setText(Float.toString(confidence));

                                // Multiple locations are possible, e.g., the location of the depicted
                                // landmark and the location the picture was taken.
                                for(FirebaseVisionLatLng loc : landmark.getLocations( )) {
                                    double latitude = loc.getLatitude( );
                                    tvLlatitude.setText(Double.toString(latitude));
                                    double longitude = loc.getLongitude( );
                                    tvLlongitude.setText(Double.toString(longitude));
                                }
                            }

                        }
                    })
                    .addOnFailureListener(new OnFailureListener( ) {
                        @Override
                        public void onFailure(@NonNull Exception e) {
                            // Task failed with an exception
                            // ...
                            Log.d(TAG,e.getMessage());
                            Toast.makeText(RecognizeLandmarks.this, "Recognizing Failed", Toast.LENGTH_SHORT).show( );
                        }
                    });

        } else if (resultCode == CropImage.CROP_IMAGE_ACTIVITY_RESULT_ERROR_CODE) {
            //if there is any error show it
            Exception error = result1.getError( );
            Toast.makeText(this, "" + error, Toast.LENGTH_SHORT).show( );
            }
        }
    }
}

Результат

D / MyLog: если вы не настроили биллинг, перейдите на консоль Firebase, чтобы настроить биллинг: https://firebase.corp.google.com/u/0/project/_/overview?purchaseBillingPlan=true. Если вы указываете отладочную переопределение ключа Api и включаете ограничения Api Key, убедитесь, что ограничения установлены правильно

1 Ответ

1 голос
/ 05 мая 2019

Обнаружение ориентира ML Kit не запускается на самом устройстве, но использует Google Cloud Vision. По этой причине ваш проект должен быть на платном плане, прежде чем вы сможете использовать определение ориентира. Первые 1000 звонков бесплатны, после чего вы будете платить за дополнительные звонки.

...