Now that we have our image instance which we wish to analyse, we are ready to perform landmark recogntion. And whether or not we are providing an instance of the options, we can prepare our FirebaseVision detector. If we are using the default options we can simply retrieve the instance as it is:

val detector = FirebaseVision.getInstance()

.visionCloudLandmarkDetector

Otherwise we can pass in our options reference when retrieving the detector:

val detector = FirebaseVision.getInstance()

.getVisionCloudLandmarkDetector(options)

Next, we simply need to call the detectInImage() function on our detector instance, passing in the reference to our image that we previously prepared:

detector.detectInImage(image)

.addOnSuccessListener {

// Task succeeded!

for (landmark in it) {

// Do something with landmark

}

}

.addOnFailureListener {

// Task failed with an exception

}

Now, if this call succeeds then we will be given a list of FirebaseVisionCloudLandmark instances. If no landmarks have been detected then this will be empty, so you need to handle this if this situation occurs. Otherwise, we have access to a collection of landmarks that we now need to do something with. For each FirebaseVisionCloudLandmark instance, we have access to a collection of properties that we can use here:

getBoundingBox() — Retrieve the region of the image which contains the recognised landmark

val bounds = landmark.boundingBox

getLandmark() — Retrieve the name of the detected landmark

val landmarkName = landmark.landmark

getConfidence() — Retrieve the confidence that the given result matches the provided image

val confidence = landmark.confidence

getLocations() — Retrieve a list of FirebaseVisionLatLng instances which represents locations such as the location of the landmark and the location of where the photo was taken.

val locations = landmark.locations

getEntityId() — Retrieve the given ID for the recognition process

val entityId = landmark.entityId

If we then run a few images through this recognition flow, we can see the kind of results we get from some well known landmarks:

It looks like MLKit is pretty confident on it’s result there. I’ve used the bounding box to draw around the recognised landmark and then simply shown the landmarkName and confidence properties beneath. Let’s try running a picture of Big Ben through the recogniser:

Not so confident on this one, we can also see that there are multiple instances of the landmark that has been detected. Because I am looping through the landmarks, the last instance of the landmark has been used to display the confidence. Let’s try this again but with just the first result:

A little better here, it’s also easier just having the single bounding box here. What you would likely do here is take all of the results from the recognised landmark and manipulate the collection of confidences to make the decision on the confidence within your app for this landmark.

Finally, let’s run another image through this:

I wanted to run this one through so that we could test out and see if MLKit would still recognise this famous landmark if we only showed a partial image:

Now I know this landmark is pretty well known so that is probably why there is still a high confidence with a partial image, but it’s great to see that it still has the capability to recognise the landmark in this state (and it’s actually more confident that the landmark is the Eiffel tower!).