Görüntülerdeki iyi bilinen önemli noktaları belirlemek için Firebase ML'yi kullanabilirsiniz.
Başlamadan önce
- Henüz yapmadıysanız Firebase'i Android projenize ekleyin.
-
Modül (uygulama düzeyi) Gradle dosyanıza (genellikle
<project>/<app-module>/build.gradle.kts
veya<project>/<app-module>/build.gradle
), Android için Firebase ML Vision kitaplığının bağımlılığını ekleyin. Kitaplık sürümü oluşturmayı kontrol etmek için Firebase Android BoM'u kullanmanızı öneririz.dependencies { // Import the BoM for the Firebase platform implementation(platform("com.google.firebase:firebase-bom:33.1.1")) // Add the dependency for the Firebase ML Vision library // When using the BoM, you don't specify versions in Firebase library dependencies implementation 'com.google.firebase:firebase-ml-vision' }
Firebase Android BoM kullanıldığında uygulamanız Firebase Android kitaplıklarının her zaman uyumlu sürümlerini kullanır.
(Alternatif) Firebase kitaplığı bağımlılıklarını BoM'u kullanmadan ekleyin
Firebase BoM'yi kullanmamayı seçerseniz her Firebase kitaplık sürümünü bağımlılık satırında belirtmeniz gerekir.
Uygulamanızda birden fazla Firebase kitaplığı kullanıyorsanız kitaplık sürümlerini yönetmek için tüm sürümlerin uyumlu olmasını sağlamak için BoM kullanmanızı kesinlikle öneririz.
dependencies { // Add the dependency for the Firebase ML Vision library // When NOT using the BoM, you must specify versions in Firebase library dependencies implementation 'com.google.firebase:firebase-ml-vision:24.1.0' }
-
Projeniz için Bulut tabanlı API'leri henüz etkinleştirmediyseniz hemen etkinleştirin:
- Firebase konsolunun Firebase ML APIs sayfasını açın.
-
Projenizi henüz Blaze fiyatlandırma planına yükseltmediyseniz bunu yapmak için Yükselt'i tıklayın. (Yalnızca projeniz Blaze planında değilse yükseltme yapmanız istenir.)
Bulut tabanlı API'leri yalnızca Blaze düzeyindeki projeler kullanabilir.
- Bulut tabanlı API'ler etkin değilse Bulut tabanlı API'leri etkinleştir'i tıklayın.
Önemli nokta algılayıcısını yapılandırma
Bulut algılayıcı, varsayılan olarak modelin STABLE
sürümünü kullanır ve 10 adede kadar sonuç döndürür. Bu ayarlardan herhangi birini değiştirmek istiyorsanız bunları bir FirebaseVisionCloudDetectorOptions
nesnesiyle belirtin.
Örneğin, her iki varsayılan ayarı da değiştirmek için aşağıdaki örnekte gösterildiği gibi bir FirebaseVisionCloudDetectorOptions
nesnesi oluşturun:
Kotlin+KTX
val options = FirebaseVisionCloudDetectorOptions.Builder() .setModelType(FirebaseVisionCloudDetectorOptions.LATEST_MODEL) .setMaxResults(15) .build()
Java
FirebaseVisionCloudDetectorOptions options = new FirebaseVisionCloudDetectorOptions.Builder() .setModelType(FirebaseVisionCloudDetectorOptions.LATEST_MODEL) .setMaxResults(15) .build();
Varsayılan ayarları kullanmak için bir sonraki adımda FirebaseVisionCloudDetectorOptions.DEFAULT
kullanabilirsiniz.
Önemli nokta algılayıcısını çalıştırın
Bir görüntüdeki önemli noktaları tanımak içinBitmap
, media.Image
, ByteBuffer
, bayt dizisi veya cihazdaki bir dosyadan FirebaseVisionImage
nesnesi oluşturun. Daha sonra, FirebaseVisionImage
nesnesini FirebaseVisionCloudLandmarkDetector
'ın detectInImage
yöntemine geçirin.
Resminizden bir
FirebaseVisionImage
nesnesi oluşturun.-
media.Image
nesnesindenFirebaseVisionImage
nesnesi oluşturmak için (örneğin, bir cihazın kamerasından resim çekerken)media.Image
nesnesini ve resmin dönüşünüFirebaseVisionImage.fromMediaImage()
konumuna geçirin.KameraX kitaplığını kullanırsanız
OnImageCapturedListener
veImageAnalysis.Analyzer
sınıfları rotasyon değerini sizin için hesaplar. Bu nedenle,FirebaseVisionImage.fromMediaImage()
çağrısı yapmadan önce rotasyonu Firebase ML'ninROTATION_
sabitlerinden birine dönüştürmeniz gerekir:Kotlin+KTX
private class YourImageAnalyzer : ImageAnalysis.Analyzer { private fun degreesToFirebaseRotation(degrees: Int): Int = when(degrees) { 0 -> FirebaseVisionImageMetadata.ROTATION_0 90 -> FirebaseVisionImageMetadata.ROTATION_90 180 -> FirebaseVisionImageMetadata.ROTATION_180 270 -> FirebaseVisionImageMetadata.ROTATION_270 else -> throw Exception("Rotation must be 0, 90, 180, or 270.") } override fun analyze(imageProxy: ImageProxy?, degrees: Int) { val mediaImage = imageProxy?.image val imageRotation = degreesToFirebaseRotation(degrees) if (mediaImage != null) { val image = FirebaseVisionImage.fromMediaImage(mediaImage, imageRotation) // Pass image to an ML Vision API // ... } } }
Java
private class YourAnalyzer implements ImageAnalysis.Analyzer { private int degreesToFirebaseRotation(int degrees) { switch (degrees) { case 0: return FirebaseVisionImageMetadata.ROTATION_0; case 90: return FirebaseVisionImageMetadata.ROTATION_90; case 180: return FirebaseVisionImageMetadata.ROTATION_180; case 270: return FirebaseVisionImageMetadata.ROTATION_270; default: throw new IllegalArgumentException( "Rotation must be 0, 90, 180, or 270."); } } @Override public void analyze(ImageProxy imageProxy, int degrees) { if (imageProxy == null || imageProxy.getImage() == null) { return; } Image mediaImage = imageProxy.getImage(); int rotation = degreesToFirebaseRotation(degrees); FirebaseVisionImage image = FirebaseVisionImage.fromMediaImage(mediaImage, rotation); // Pass image to an ML Vision API // ... } }
Resmin dönüşünü sağlayan bir kamera kitaplığı kullanmıyorsanız bunu cihazın döndürme ve cihazdaki kamera sensörünün yönüne göre hesaplayabilirsiniz:
Kotlin+KTX
private val ORIENTATIONS = SparseIntArray() init { ORIENTATIONS.append(Surface.ROTATION_0, 90) ORIENTATIONS.append(Surface.ROTATION_90, 0) ORIENTATIONS.append(Surface.ROTATION_180, 270) ORIENTATIONS.append(Surface.ROTATION_270, 180) } /** * Get the angle by which an image must be rotated given the device's current * orientation. */ @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) @Throws(CameraAccessException::class) private fun getRotationCompensation(cameraId: String, activity: Activity, context: Context): Int { // Get the device's current rotation relative to its "native" orientation. // Then, from the ORIENTATIONS table, look up the angle the image must be // rotated to compensate for the device's rotation. val deviceRotation = activity.windowManager.defaultDisplay.rotation var rotationCompensation = ORIENTATIONS.get(deviceRotation) // On most devices, the sensor orientation is 90 degrees, but for some // devices it is 270 degrees. For devices with a sensor orientation of // 270, rotate the image an additional 180 ((270 + 270) % 360) degrees. val cameraManager = context.getSystemService(CAMERA_SERVICE) as CameraManager val sensorOrientation = cameraManager .getCameraCharacteristics(cameraId) .get(CameraCharacteristics.SENSOR_ORIENTATION)!! rotationCompensation = (rotationCompensation + sensorOrientation + 270) % 360 // Return the corresponding FirebaseVisionImageMetadata rotation value. val result: Int when (rotationCompensation) { 0 -> result = FirebaseVisionImageMetadata.ROTATION_0 90 -> result = FirebaseVisionImageMetadata.ROTATION_90 180 -> result = FirebaseVisionImageMetadata.ROTATION_180 270 -> result = FirebaseVisionImageMetadata.ROTATION_270 else -> { result = FirebaseVisionImageMetadata.ROTATION_0 Log.e(TAG, "Bad rotation value: $rotationCompensation") } } return result }
Java
private static final SparseIntArray ORIENTATIONS = new SparseIntArray(); static { ORIENTATIONS.append(Surface.ROTATION_0, 90); ORIENTATIONS.append(Surface.ROTATION_90, 0); ORIENTATIONS.append(Surface.ROTATION_180, 270); ORIENTATIONS.append(Surface.ROTATION_270, 180); } /** * Get the angle by which an image must be rotated given the device's current * orientation. */ @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) private int getRotationCompensation(String cameraId, Activity activity, Context context) throws CameraAccessException { // Get the device's current rotation relative to its "native" orientation. // Then, from the ORIENTATIONS table, look up the angle the image must be // rotated to compensate for the device's rotation. int deviceRotation = activity.getWindowManager().getDefaultDisplay().getRotation(); int rotationCompensation = ORIENTATIONS.get(deviceRotation); // On most devices, the sensor orientation is 90 degrees, but for some // devices it is 270 degrees. For devices with a sensor orientation of // 270, rotate the image an additional 180 ((270 + 270) % 360) degrees. CameraManager cameraManager = (CameraManager) context.getSystemService(CAMERA_SERVICE); int sensorOrientation = cameraManager .getCameraCharacteristics(cameraId) .get(CameraCharacteristics.SENSOR_ORIENTATION); rotationCompensation = (rotationCompensation + sensorOrientation + 270) % 360; // Return the corresponding FirebaseVisionImageMetadata rotation value. int result; switch (rotationCompensation) { case 0: result = FirebaseVisionImageMetadata.ROTATION_0; break; case 90: result = FirebaseVisionImageMetadata.ROTATION_90; break; case 180: result = FirebaseVisionImageMetadata.ROTATION_180; break; case 270: result = FirebaseVisionImageMetadata.ROTATION_270; break; default: result = FirebaseVisionImageMetadata.ROTATION_0; Log.e(TAG, "Bad rotation value: " + rotationCompensation); } return result; }
Daha sonra
media.Image
nesnesini ve rotasyon değeriniFirebaseVisionImage.fromMediaImage()
adlı cihaza geçirin:Kotlin+KTX
val image = FirebaseVisionImage.fromMediaImage(mediaImage, rotation)
Java
FirebaseVisionImage image = FirebaseVisionImage.fromMediaImage(mediaImage, rotation);
- Dosya URI'sinden bir
FirebaseVisionImage
nesnesi oluşturmak için uygulama bağlamını ve dosya URI'siniFirebaseVisionImage.fromFilePath()
hedefine iletin. Bu, kullanıcıdan galeri uygulamasından bir resim seçmesini istemek için birACTION_GET_CONTENT
amacı kullandığınızda faydalıdır.Kotlin+KTX
val image: FirebaseVisionImage try { image = FirebaseVisionImage.fromFilePath(context, uri) } catch (e: IOException) { e.printStackTrace() }
Java
FirebaseVisionImage image; try { image = FirebaseVisionImage.fromFilePath(context, uri); } catch (IOException e) { e.printStackTrace(); }
ByteBuffer
veya bayt dizisindenFirebaseVisionImage
nesnesi oluşturmak için önce resim döndürmesini, yukarıdamedia.Image
girişi için açıklandığı gibi hesaplayın.Ardından, resmin yüksekliği, genişliği, renk kodlama biçimi ve dönüşünü içeren bir
FirebaseVisionImageMetadata
nesnesi oluşturun:Kotlin+KTX
val metadata = FirebaseVisionImageMetadata.Builder() .setWidth(480) // 480x360 is typically sufficient for .setHeight(360) // image recognition .setFormat(FirebaseVisionImageMetadata.IMAGE_FORMAT_NV21) .setRotation(rotation) .build()
Java
FirebaseVisionImageMetadata metadata = new FirebaseVisionImageMetadata.Builder() .setWidth(480) // 480x360 is typically sufficient for .setHeight(360) // image recognition .setFormat(FirebaseVisionImageMetadata.IMAGE_FORMAT_NV21) .setRotation(rotation) .build();
FirebaseVisionImage
nesnesi oluşturmak için tamponu veya diziyi ve meta veri nesnesini kullanın:Kotlin+KTX
val image = FirebaseVisionImage.fromByteBuffer(buffer, metadata) // Or: val image = FirebaseVisionImage.fromByteArray(byteArray, metadata)
Java
FirebaseVisionImage image = FirebaseVisionImage.fromByteBuffer(buffer, metadata); // Or: FirebaseVisionImage image = FirebaseVisionImage.fromByteArray(byteArray, metadata);
- Bir
Bitmap
nesnesindenFirebaseVisionImage
nesnesi oluşturmak için:Kotlin+KTX
val image = FirebaseVisionImage.fromBitmap(bitmap)
Java
FirebaseVisionImage image = FirebaseVisionImage.fromBitmap(bitmap);
Bitmap
nesnesiyle temsil edilen resim, ek döndürme gerekmeden dik olmalıdır.
-
FirebaseVisionCloudLandmarkDetector
örneğini alın:Kotlin+KTX
val detector = FirebaseVision.getInstance() .visionCloudLandmarkDetector // Or, to change the default settings: // val detector = FirebaseVision.getInstance() // .getVisionCloudLandmarkDetector(options)
Java
FirebaseVisionCloudLandmarkDetector detector = FirebaseVision.getInstance() .getVisionCloudLandmarkDetector(); // Or, to change the default settings: // FirebaseVisionCloudLandmarkDetector detector = FirebaseVision.getInstance() // .getVisionCloudLandmarkDetector(options);
Son olarak, resmi
detectInImage
yöntemine iletin:Kotlin+KTX
val result = detector.detectInImage(image) .addOnSuccessListener { firebaseVisionCloudLandmarks -> // Task completed successfully // ... } .addOnFailureListener { e -> // Task failed with an exception // ... }
Java
Task<List<FirebaseVisionCloudLandmark>> result = detector.detectInImage(image) .addOnSuccessListener(new OnSuccessListener<List<FirebaseVisionCloudLandmark>>() { @Override public void onSuccess(List<FirebaseVisionCloudLandmark> firebaseVisionCloudLandmarks) { // Task completed successfully // ... } }) .addOnFailureListener(new OnFailureListener() { @Override public void onFailure(@NonNull Exception e) { // Task failed with an exception // ... } });
Tanınan önemli noktalar hakkında bilgi edinin
Önemli nokta tanıma işlemi başarılı olursa başarı işleyiciye birFirebaseVisionCloudLandmark
nesne listesi iletilir. Her FirebaseVisionCloudLandmark
nesnesi, görüntüde tanınan bir önemli noktayı temsil eder. Her önemli nokta için sınır koordinatlarını giriş görüntüsünde, önemli noktanın adını, enlemini ve boylamını, Bilgi Grafiği varlık kimliğini (varsa) ve eşleşmenin güven puanını alabilirsiniz. Örnek:
Kotlin+KTX
for (landmark in firebaseVisionCloudLandmarks) { val bounds = landmark.boundingBox val landmarkName = landmark.landmark val entityId = landmark.entityId val confidence = landmark.confidence // Multiple locations are possible, e.g., the location of the depicted // landmark and the location the picture was taken. for (loc in landmark.locations) { val latitude = loc.latitude val longitude = loc.longitude } }
Java
for (FirebaseVisionCloudLandmark landmark: firebaseVisionCloudLandmarks) { Rect bounds = landmark.getBoundingBox(); String landmarkName = landmark.getLandmark(); String entityId = landmark.getEntityId(); float confidence = landmark.getConfidence(); // 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(); double longitude = loc.getLongitude(); } }
Sonraki adımlar
- Cloud API kullanan bir uygulamayı üretime dağıtmadan önce yetkisiz API erişiminin önlenmesi ve etkilerini azaltmak için birkaç ek adım uygulamanız gerekir.