Using object detection in AI Builder against images in Dataverse

Recently in one of my solutions where I’m using the trainable object detection model in AI Builder, I had to be able to input photos to this model in a Power Automate flow which had come from Dataverse. I had a few troubles achieving… READ MORE [https://lewisdoes.dev/blog/using-object-detection-
high angle photo of robot
Photo by Alex Knight on Pexels.com
In: Low Code Lewis Content 🚀

Recently in one of my solutions where I’m using the trainable object detection model in AI Builder, I had to be able to input photos to this model in a Power Automate flow which had come from Dataverse. I had a few troubles achieving this where things weren’t quite as easy as using the get file content steps that OneDrive and SharePoint provide, but I figured it out, so I’m here to share how you can do it! 🙂

Some background

So, a little background into how my solution works. Effectively I have a Power Pages site with a basic form on it. That form has settings for uploading attachments enabled which then get saved on the timeline of the new record being submitted/created.

I now want to be able to pass the attached photo which is on the timeline (in the Note table), through my AI model and make actions based on the models findings.

Some issues with the download a file or image action – Dataverse

So, my first thought was that I’d need to use the download a file or image action from Dataverse to get my file content so I could use this in my object detection model. I tried to do this, and the action did run successfully, but I was only ever getting plain text back which was returning the file name. I’m not sure what was happening here as I didn’t investigate too much further, but rather took a different approach!

We don’t actually need to use this step as all of the content we need is already on the record with a file or image column, in this case my note record.

Creating the flow

So, lets take a look at how we can process an image in Dataverse through an AI Builder object detection model that we’ve previously trained to identify certain objects.

So for my flow trigger, I’m using the Dataverse trigger, ‘When a row is added, modified or deleted’.

Now I’m about to use a condition which I could just make an Odata expression on this trigger, but either works, so feel free to use either method.

Here I’m saying that I want my flow to trigger when anyone in the organisation creates a new issue, which will be the action carried out from my Power Pages site by anyone who can access my basic form there.

Now I only want my flow to continue to make steps if the issue type reported is a certain type which I’m then going to confirm using my AI model.

Remember in Dataverse, you need to find the numeric value for a choice and make a comparison using this. This is the value the dynamic content for a choice column will return, as opposed to the text value for that column. To return a text value and not need to use the numeric value as a static value to compare with, check out this post.

Retrieving the formatted label text from a choice in Power Automate when using Dataverse – Low Code Lewis

Now I’m going to get my related record on my note table which has my attachment so I can use this. Given there could be many records in my timeline due to the nature of my relationship here, I need to use a list rows against my note table and filter the rows to only get the ones where the records have a relationship with my issue record.

So in the yes branch of my condition, I need to start with my list rows action to retrieve my note record which will have an attachment.

Now I know because I’m running this flow as soon as my parent record of my ‘note’ is created, and there is only one note being created at the time that the parent issue records is being created, that this step should only ever return one record. I know that if it returns more than 1 there is something that has gone wrong in my solution.

What I could do here to confirm this, is add a condition and use length to count the number of rows returned. If that is more than 1, then I’ll want to notify a system admin or relevant person that I have some incorrect or ‘corrupt’ data. If I do just return 1 record, then I’ll want to resume with my process.

Avoiding the apply to each

Now because I know I’m only going to return 1 record, and I might have even checked this before, to avoid an apply to each I’m going to retrieve values from the value within my body outputted by the list rows action using a first() function.

I’m going to add two compose actions for debugging purposes so I can see what my functions are doing in my flow run history more easily.

There are two things I need to get out of my note record which will form my file for use in my AI builder object detection step. One is my MIME type or ‘content type’, and the other is my actual file content or ‘document body’. The correct column names here are ‘mimetype’ and ‘documentbody’ when referencing a Dataverse file.

In my first compose, I’m going to get the MIME type for my first record returned which should be my only record…

first(outputs('List_rows')?['body/value'])?['mimetype']

Then in my second compose action, I’m going to get my file content or ‘documentbody’ for my first record returned which again should be my only record…

first(outputs('List_rows')?['body/value'])?['documentbody']

Creating an image object

Now, first I tried to just pass image content or file content to the AI builder step, but it needs a little more than this. From looking at the content passed in as an input when we use something like ‘File Content’ dynamic content from a OneDrive get file content step, I was able to see that this step does actually want an image object to work with which will give it both the file type and the content of the file. We now need to construct this object using the data we’ve taken out of our list rows action.

In another compose I’m going to create my image object using the following JSON.

{
  "$content-type": "outputs('List_Rows_First_Record_MIME_Type_for_File')",
  "$content": "outputs('List_Rows_First_Record_Document_Body_for_File')"
}

Now I’ve got my object image, I am ready to use this in my AI builder step.

Add the ‘detect and count objects in images’ step to your flow, and select the model you have created that you wish to use here. Then for the image input, use the outputs from your previous compose action which in my case was called ‘List Rows – Object Image’

AI Builder step in a Power Automate flow

Now things should be working! 🙂

Written by
Lewis Baybutt
Microsoft Business Applications MVP • Power Platform Consultant • Blogger • Community Contributor • #CommunityRocks • #SharingIsCaring
Great! You’ve successfully signed up.
Welcome back! You've successfully signed in.
You've successfully subscribed to LewisDoesDev.
Your link has expired.
Success! Check your email for magic link to sign-in.
Success! Your billing info has been updated.
Your billing was not updated.