sweecodengo
sweecodengo

Reputation: 1

How do I send batch images to the Custom Vision service with there associated label data using the python SDK

I've been working on trying to send my training data to the custom vision service for a couple hours now and keep running into issue after issue. I have a large dataset of 430 images and a accompanying csv containing the associated tags for each(using multi-tag on custom vision). I've spend hours doing research and eventually go the point where the API and SDKs are correctly linked and everything's setup and now keep getting the error "Batch upload failed: 'Image' object has no attribute 'error'".

here is the image processing and batch upload section of my code:

batch_size = 64
publish_iteration_name = "classifyModel"

# 6. Open CSV and Process Images
with open(image_data_file, "r") as csvfile:
    reader = csv.DictReader(csvfile)
    image_batch = []

    for row in reader:
        image_path = os.path.join(image_folder, row["filename"])
        if not os.path.exists(image_path):
            print(f"Warning: Image not found: {image_path}")
            continue

        with open(image_path, "rb") as image_contents:
            image_data = image_contents.read()
            tag_ids = []

            for key, value in row.items():
                if key != "filename" and value == "1":
                    try:
                        tag = trainer.get_tag(PROJECT_ID, key)
                        tag_ids.append(tag.id)
                    except Exception as e:
                        print(f"Error getting tag '{key}': {e}")

            # Add Image File to the Batch
            image_batch.append(ImageFileCreateEntry(
                name=image_path, contents=image_data, tag_ids=tag_ids))

        # Upload Batch if it reaches the size limit
        if len(image_batch) >= batch_size:
            try:
                upload_result = trainer.create_images_from_files(
                    PROJECT_ID, ImageFileCreateBatch(images=image_batch))

                if not upload_result.is_batch_successful:
                    for image in upload_result.images:
                        if image.status != "OK":
                            print(
                                # Check error details inside image.image
                                f"Image '{image.source_url}' upload failed. Status: {image.status}, Error Details: {image.image.error.message if image.image.error else 'Unknown'}"
                            )
                        else:
                            print(
                                f"Image '{image.source_url}' uploaded successfully with ID: {image.image.id}")

            except Exception as e:
                print(f"Batch upload failed: {e}")

my program also handles training but I have been unsuccessful getting to this point as I continue to not have enough images to train. Thanks to anyone who is willing to help out!.

I've scoured the documentation and forums trying to gain insight on what the issue might be(I have a feeling its something simple) and I'm now at a road block. any suggestions are welcome haha

Upvotes: 0

Views: 138

Answers (1)

Sampath
Sampath

Reputation: 3614

The error "Batch upload failed: 'Image' object has no attribute 'error'" indicates that the code is attempting to access an attribute error that does not exist on the Image object returned by the Custom Vision SDK. To resolve this issue, instead of trying to access image.image.error, which was causing the error, I used image.status and image.status_code to determine if there was an issue with uploading the image.

Use the below map of associations to upload each sample image.

base_image_location = os.path.join (os.path.dirname(__file__), "Images")

# Go through the data table above and create the images
print ("Adding images...")
tagged_images_with_regions = []

for file_name in fork_image_regions.keys():
    x,y,w,h = fork_image_regions[file_name]
    regions = [ Region(tag_id=fork_tag.id, left=x,top=y,width=w,height=h) ]

    with open(os.path.join (base_image_location, "fork", file_name + ".jpg"), mode="rb") as image_contents:
        tagged_images_with_regions.append(ImageFileCreateEntry(name=file_name, contents=image_contents.read(), regions=regions))

for file_name in scissors_image_regions.keys():
    x,y,w,h = scissors_image_regions[file_name]
    regions = [ Region(tag_id=scissors_tag.id, left=x,top=y,width=w,height=h) ]

    with open(os.path.join (base_image_location, "scissors", file_name + ".jpg"), mode="rb") as image_contents:
        tagged_images_with_regions.append(ImageFileCreateEntry(name=file_name, contents=image_contents.read(), regions=regions))

upload_result = trainer.create_images_from_files(project.id, ImageFileCreateBatch(images=tagged_images_with_regions))
if not upload_result.is_batch_successful:
    print("Image batch upload failed.")
    for image in upload_result.images:
        print("Image status: ", image.status)
    exit(-1)


Below Python code is to send batch images to the Custom Vision service with their associated label data using the Azure Custom Vision SDK. I have referred to this MSDOC for creating an object detection project with the Custom Vision client library. I have modified as below

ENDPOINT = os.environ["VISION_TRAINING_ENDPOINT"]
training_key = os.environ["VISION_TRAINING_KEY"]
PROJECT_ID = '<your_project_id>'


credentials = ApiKeyCredentials(in_headers={"Training-key": training_key})
trainer = CustomVisionTrainingClient(ENDPOINT, credentials)


batch_size = 64
image_data_file = '<path_to_your_csv_file>'
image_folder = '<path_to_your_image_folder>'
publish_iteration_name = "classifyModel"


with open(image_data_file, "r") as csvfile:
    reader = csv.DictReader(csvfile)
    image_batch = []

    for row in reader:
        image_path = os.path.join(image_folder, row["filename"])
        if not os.path.exists(image_path):
            print(f"Warning: Image not found: {image_path}")
            continue

        with open(image_path, "rb") as image_contents:
            image_data = image_contents.read()
            tag_ids = []

            for key, value in row.items():
                if key != "filename" and value == "1":
                    try:
                        tag = trainer.get_tag(PROJECT_ID, key)
                        tag_ids.append(tag.id)
                    except Exception as e:
                        print(f"Error getting tag '{key}': {e}")

           
            image_batch.append(ImageFileCreateEntry(
                name=row["filename"], contents=image_data, tag_ids=tag_ids))

   
        if len(image_batch) >= batch_size:
            try:
                upload_result = trainer.create_images_from_files(
                    PROJECT_ID, ImageFileCreateBatch(images=image_batch))

                if not upload_result.is_batch_successful:
                    for image in upload_result.images:
                        if image.status != "OK":
                            print(f"Image '{image.source_url}' upload failed. Status: {image.status}, Error Details: {image.status}")
                        else:
                            print(f"Image '{image.source_url}' uploaded successfully with ID: {image.image.id}")

              
                image_batch = []

            except Exception as e:
                print(f"Batch upload failed: {e}")


if image_batch:
    try:
        upload_result = trainer.create_images_from_files(
            PROJECT_ID, ImageFileCreateBatch(images=image_batch))

        if not upload_result.is_batch_successful:
            for image in upload_result.images:
                if image.status != "OK":
                    print(f"Image '{image.source_url}' upload failed. Status: {image.status}, Error Details: {image.status}")
                else:
                    print(f"Image '{image.source_url}' uploaded successfully with ID: {image.image.id}")

    except Exception as e:
        print(f"Batch upload failed: {e}")

print("All images uploaded successfully.")

# Upload and tag images
fork_image_regions = {
    "fork_1": [0.145833328, 0.3509314, 0.5894608, 0.238562092],
    "fork_2": [0.294117659, 0.216944471, 0.534313738, 0.5980392],
    "fork_3": [0.09191177, 0.0682516545, 0.757352948, 0.6143791],
    "fork_4": [0.254901975, 0.185898721, 0.5232843, 0.594771266],
    "fork_5": [0.2365196, 0.128709182, 0.5845588, 0.71405226],
    "fork_6": [0.115196079, 0.133611143, 0.676470637, 0.6993464],
    "fork_7": [0.164215669, 0.31008172, 0.767156839, 0.410130739],
    "fork_8": [0.118872553, 0.318251669, 0.817401946, 0.225490168],
    "fork_9": [0.18259804, 0.2136765, 0.6335784, 0.643790841]

enter image description here

Upvotes: 0

Related Questions