def upload_images(training_key):
    trainer = CustomVisionTrainingClient(training_key, endpoint=ENDPOINT)

    # Find the object detection domain
    obj_detection_domain = next(domain for domain in trainer.get_domains() if domain.type == "ObjectDetection")

    print("Creating project...")
    try:
        project = trainer.create_project("LEGO Vision", domain_id=obj_detection_domain.id)
    except HttpOperationError:
        print("Project already exists. Using this one.")
        project = trainer.get_project(project_id="71548120-925d-4e59-ba7e-32f99de50240")

    classes = os.path.join(BASE_DIRECTORY, "class_map.txt")
    tags = dict()
    # Make two tags in the new project
    for _class in list(map(lambda line: line.split('\t')[0], open(classes).readlines())):
        try:
            tags[_class] = trainer.create_tag(project.id, _class)
        except HttpOperationError:
            print("Tag already created, continuing...")
            for tag in trainer.get_tags(project_id="71548120-925d-4e59-ba7e-32f99de50240"):
                tags[tag.name] = tag

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

    for image_path in glob.glob(os.path.join(IMAGES_FOLDER, "*.jpg")):
        file_id, extension = image_path.split(".", 1)
        image = cv2.imread(image_path)
        bboxes = read_bboxes(os.path.join(IMAGES_FOLDER, file_id + ".bboxes.tsv"), scale=1, padding=(0, 0, 0, 0))
        labels = read_labels(os.path.join(IMAGES_FOLDER, file_id + ".bboxes.labels.tsv"))
        regions = [Region(tag_id=tags[_class].id, left=bbox[0] / image.shape[1], top=bbox[1] / image.shape[0],
                          width=abs(bbox[0] - bbox[2]) / image.shape[1], height=abs(bbox[1] - bbox[3]) / image.shape[0])
                   for _class, bbox in zip(labels,
                                           bboxes)]
        with open(image_path, mode="rb") as image_contents:
            tagged_images_with_regions.append(ImageFileCreateEntry(name=file_id, contents=image_contents.read(),
                                                                   regions=regions))
    print("Azure Custom Vision can only accept images in batches of max 64 per batch. Cutting list up in batches..")
    for batch in chunks(tagged_images_with_regions, 64):
        trainer.create_images_from_files(project.id, images=batch, tag_ids=[tag.id for tag in tags.values()])
    print("Finished adding images. Visit customvision.ai to start training via the GUI.")
Example #2
0
def main():
    """
    Training for object detection with Azure Custom Vision
    """
    args = parse_args()
    config = json.load(open(args.config, "r"))
    credentials = ApiKeyCredentials(in_headers={"Training-key": config["training_key"]})
    trainer = CustomVisionTrainingClient(config["ENDPOINT"], credentials)

    print("Creating project...")

    # Find the object detection domain
    obj_detection_domain = next(
        domain
        for domain in trainer.get_domains()
        if domain.type == "ObjectDetection" and domain.name == "General"
    )
    project = trainer.create_project(
        config["project_name"], domain_id=obj_detection_domain.id
    )

    # ======================================================================================

    print("Adding images...")
    image_folder = config["image_folder"]
    annotations = json.load(open("annotation.json", "r"))
    tagged_images_with_regions = []
    for label in annotations.keys():
        tagged_images_with_regions += add_image(
            trainer, label, project.id, annotations[label], image_folder
        )

    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)

    # ======================================================================================
    print("Training...")
    publish_iteration_name = config["publish_iteration_name"]
    prediction_resource_id = config["prediction_resource_id"]
    iteration = trainer.train_project(project.id)
    while iteration.status != "Completed":
        iteration = trainer.get_iteration(project.id, iteration.id)
        print("Training status: " + iteration.status)
        time.sleep(1)

    # The iteration is now trained. Publish it to the project endpoint
    trainer.publish_iteration(
        project.id, iteration.id, publish_iteration_name, prediction_resource_id
    )
    print("Done!")
Example #3
0
    file_name = "curve/{}.jpg".format(image_num)
    with open(base_image_url + "curve/" + file_name, "rb") as image_contents:
        image_list.append(
            ImageFileCreateEntry(name=file_name,
                                 contents=image_contents.read(),
                                 tag_ids=[curve_tag.id]))

for image_num in range(1, 15):
    file_name = "imaging/{}.jpg".format(image_num)
    with open(base_image_url + "imaging/" + file_name, "rb") as image_contents:
        image_list.append(
            ImageFileCreateEntry(name=file_name,
                                 contents=image_contents.read(),
                                 tag_ids=[imaging_tag.id]))

upload_result = trainer.create_images_from_files(project.id, images=image_list)

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)

# Train the classifier and publish
import time

print("Training...")
iteration = trainer.train_project(project.id)
while (iteration.status != "Completed"):
    iteration = trainer.get_iteration(project.id, iteration.id)
    print("Training status: " + iteration.status)
Example #4
0
class LabelUtility:
    """ Utility for interacting with the Custom Vision label tool.
    """
    def __init__(self, ws_name, project_id, project_key):
        endpoint_url = "https://{}.cognitiveservices.azure.com/".format(
            ws_name)
        self.project_id = project_id
        self.client = CustomVisionTrainingClient(project_key,
                                                 endpoint=endpoint_url)
        self.project = self.client.get_project(project_id=project_id)
        self.tags = self.client.get_tags(project_id=project_id)

    def upload_directory(self,
                         data_dir,
                         img_ext="*.jpg",
                         img_dir="images",
                         lbl_file="labels.csv",
                         default_tag_name="important"):
        """
        upload_directory - Upload images from a given directory into the CV workspace

        :param str data_dir: Source folder of the files.
        :param str img_ext: image extension.
        :param str img_dir: image folder.
        :param str lbl_file: labels file.
        :param str default_tag_name: default tag name.

        :returns: None

        """
        label_fn = os.path.join(data_dir, lbl_file)
        img_folder = os.path.join(data_dir, img_dir)

        # Check if required folders exist.
        if not (os.path.isdir(img_folder) and os.path.exists(label_fn)):
            print("Input data not found")
            return

        # Read labels and image list.
        labels_df = pd.read_csv(os.path.join(label_fn))
        image_list = glob.glob(os.path.join(img_folder, img_ext))

        # Upload each image with regions
        for _, path in enumerate(image_list):
            tagged_images_with_regions = []
            regions = []

            file_name = path.split("\\")[-1]
            img = Image.open(path)
            img_width, img_height = img.size

            for _, row in labels_df[labels_df.FileName ==
                                    file_name].iterrows():
                x, y, w, h = row.XMin, row.YMin, row.XMax - row.XMin, row.YMax - row.YMin
                x = x / img_width
                w = w / img_width
                y = y / img_height
                h = h / img_height

                if "DefectType" in row:
                    default_tag_name = row.DefectType

                tag = None
                for a_tag in self.tags:
                    if a_tag.name == default_tag_name:
                        tag = a_tag

                if not tag:
                    tag = self.client.create_tag(self.project_id,
                                                 default_tag_name)
                    self.tags = self.client.get_tags(self.project_id)

                regions.append(
                    Region(tag_id=tag.id, left=x, top=y, width=w, height=h))

            with open(path, mode="rb") as image_contents:
                tagged_images_with_regions.append(
                    ImageFileCreateEntry(name=file_name,
                                         contents=image_contents.read(),
                                         regions=regions))

            upload_result = self.client.create_images_from_files(
                self.project.id, 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)

    def export_images(self, data_dir, img_dir="images", lbl_file="labels.csv"):
        """
        export_images - Export any tagged images that may exist
        and preserve their tags and regions.

        :param str data_dir: Output folder.
        :param str img_ext: image extension.
        :param str img_dir: image folder.
        :param str lbl_file: labels file.

        :returns: None

        """
        img_folder = os.path.join(data_dir, img_dir)
        # Check if required folders exist.
        if not os.path.isdir(img_folder):
            print("Output folder not found")
            return
        count = self.client.get_tagged_image_count(self.project_id)
        print("Found: ", count, " tagged images.")
        exported, idx = 0, 0
        data = []
        while count > 0:
            count_to_export = min(count, 256)
            print("Getting", count_to_export, "images")
            images = self.client.get_tagged_images(self.project_id,
                                                   take=count_to_export,
                                                   skip=exported)
            for image in images:
                file_name = f'file_{idx}.jpg'
                img_fname = os.path.join(img_folder, file_name)
                data += self.download_image(image, img_fname)
                idx += 1

            exported += count_to_export
            count -= count_to_export
        df = pd.DataFrame(data,
                          columns=[
                              "image_name", "DefectName", "xmin", "xmax",
                              "ymin", "ymax"
                          ])
        classes = sorted(list(set(df['DefectName'])))
        class_ids = {}
        f = open(os.path.join(data_dir, 'label_map.pbtxt'), "w+")
        for i, clas in enumerate(classes):
            class_ids[clas] = i + 1
            f.write('item {\n')
            f.write('\tid: ' + str(i + 1) + '\n')
            f.write('\tname: \'' + clas + '\'\n')
            f.write('}\n')
            f.write('\n')
        f.close()
        df['classid'] = [
            class_ids[the_defect] for the_defect in df['DefectName']
        ]
        df.to_csv(os.path.join(data_dir, lbl_file), index=False)

    @staticmethod
    def download_image(image, img_fname):
        """
        download_image - Export an image.

        :param pyImg3 image: Image object.
        :param str img_fname: Filename of the image.
        :returns: None

        """
        regions = []
        if hasattr(image, "regions"):
            regions = image.regions
        url = image.original_image_uri
        width = image.width
        height = image.height

        # Download the image
        responseFromURL = req.get(url).content
        with open(img_fname, 'wb') as f:
            f.write(responseFromURL)
            f.close()

        # Format the regions
        data = []
        for r in regions:
            left, top, wide, high = r.left, r.top, r.width, r.height
            left = left * width
            top = top * height
            wide = wide * width
            high = high * height
            data.append([
                img_fname.split("\\")[-1], r.tag_name,
                int(left),
                int(left + wide),
                int(top),
                int(top + high)
            ])
        return data
Example #5
0
def main(req: func.HttpRequest) -> func.HttpResponse:
    logging.info('Python HTTP trigger function processed a request.')

    logging.info(f'Method: {req.method}')
    if req.method == "OPTIONS":
        return func.HttpResponse(status_code=204,
                                 headers={
                                     'Access-Control-Allow-Headers':
                                     'content-type',
                                     'Access-Control-Allow-Methods': 'POST',
                                     'Access-Control-Max-Age': '180',
                                     'Access-Control-Allow-Origin': '*'
                                 })

    body = req.get_json()

    blob_service = BlockBlobService(account_name=storageAccount,
                                    account_key=storageAccountKey)

    # prep trainer
    trainer = CustomVisionTrainingClient(trainingKey, apiEndpoint)
    #check tags
    check_tags(trainer)

    records = {'images': []}
    image_list = []

    try:
        for item in body['items']:
            # sign
            sign = item['type'].strip()

            # image bits
            img = base64.b64decode(item['image'].replace(
                'data:image/png;base64,', ''))
            stream = BytesIO(img)

            # storage path + save
            image_name = f'{str(uuid.uuid4())}.png'
            blob_name = f'{base_folder}/{sign}/{image_name}'
            sresponse = blob_service.create_blob_from_stream(
                storageContainer, blob_name, stream)

            logging.info(f'Storage Response: {sresponse}')

            # save to custom vision
            image_list.append(
                ImageFileCreateEntry(name=image_name,
                                     contents=img,
                                     tag_ids=[tags[sign].id]))

            # return image
            path = f'{blob_service.protocol}://{blob_service.primary_endpoint}/{storageContainer}/{blob_name}'
            records['images'].append({'sign': sign, 'path': path})

        # save list
        upload_result = trainer.create_images_from_files(projectId,
                                                         images=image_list)
        if not upload_result.is_batch_successful:
            records['error'] = {'type': 'CustomVision Error', 'items': []}
            for image in upload_result.images:
                records['error']['items'].append(
                    {image.source_url: image.status})
        else:
            records['error'] = {}
    except Exception as error:
        logging.exception('Python Error')
        records['error'] = {
            'code': '500',
            'message': f'{type(error).__name__}: {str(error)}',
            'type': 'Python Error'
        }

    return func.HttpResponse(body=json.dumps(records),
                             status_code=200,
                             headers={
                                 'Content-Type': 'application/json',
                                 'Access-Control-Allow-Origin': '*'
                             })
Example #6
0
            regions_lis.append((ind, x, y, w, h))
        images.append((k, regions_lis))

    print("Adding images...")
    print("%d images in total" % len(images))
    SEND_BY_BATCH = 64
    print("Send by batch =", SEND_BY_BATCH)
    tagged_images_with_regions = []
    BATCH_NUM = math.ceil(len(images) / SEND_BY_BATCH)
    for i in range(BATCH_NUM):
        for file_name, regions in images[i * SEND_BY_BATCH:(i + 1) *
                                         SEND_BY_BATCH]:
            regions_saved = []
            for r in regions:
                x, y, w, h = r[1:]
                tag_id = tag_index_to_id[r[0]]
                regions_saved.append(
                    Region(tag_id=tag_id, left=x, top=y, width=w, height=h))
            with open(IMAGES_PATH + "/" + file_name + "." + FILE_EXT,
                      mode="rb") as image_contents:
                tagged_images_with_regions.append(
                    ImageFileCreateEntry(name=file_name,
                                         contents=image_contents.read(),
                                         regions=regions_saved))
        print("Batch no.", i)
        trainer.create_images_from_files(project_id,
                                         images=tagged_images_with_regions)
        tagged_images_with_regions = []

# try to upload generated images
Example #7
0
        images[label_][mode_] = []
        dir_ = os.path.join(base_image_location, label_, mode_)
        names_ = os.listdir(dir_)
        names_ = [os.path.join(dir_, nm_) for nm_ in names_]
        names_ = [nm_ for nm_ in names_ if os.path.isfile(nm_)]
        filenames[label_][mode_] = names_
        for nm_ in names_:
            with open(nm_, 'rb') as img_:
                images[label_][mode_].append(
                    ImageFileCreateEntry(name=nm_,
                                         contents=img_.read(),
                                         tag_ids=[tag_.id]))

#upload the training data to azure
upload_result = trainer.create_images_from_files(
    project.id,
    ImageFileCreateBatch(images=images['seamus']['train'] +
                         images['finley']['train']))
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)

#train! It's as simple as that. Might take a few minutes...
print("Training...")
iteration = trainer.train_project(project.id)
while (iteration.status != "Completed"):
    iteration = trainer.get_iteration(project.id, iteration.id)
    print("Training status: " + iteration.status)
    print("Waiting 10 seconds...")
    time.sleep(10)
yellow = coach_Rives.create_tag(legoProject.id, "yellow")
plane = coach_Rives.create_tag(legoProject.id, "plane")
car = coach_Rives.create_tag(legoProject.id, "car")
racecar = coach_Rives.create_tag(legoProject.id, "racecar")
f1car = coach_Rives.create_tag(legoProject.id, "f1car")
crane = coach_Rives.create_tag(legoProject.id, "crane")
building = coach_Rives.create_tag(legoProject.id, "building")
station = coach_Rives.create_tag(legoProject.id, "station")
orange = coach_Rives.create_tag(legoProject.id, "orange")
'''

file_name = "Images/technic/choper.jpg"
with open(file_name, mode="rb") as image_contents:
    coach_Rives.create_images_from_files(legoProject.id, [
        ImageFileCreateEntry(name=file_name,
                             contents=image_contents.read(),
                             tag_ids=[technic.id])
    ])

file_name = "Images/technic/f1car.jpg"
with open(file_name, mode="rb") as image_contents:
    coach_Rives.create_images_from_files(legoProject.id, [
        ImageFileCreateEntry(name=file_name,
                             contents=image_contents.read(),
                             tag_ids=[technic.id])
    ])

file_name = "Images/technic/truck.jpg"
with open(file_name, mode="rb") as image_contents:
    coach_Rives.create_images_from_files(legoProject.id, [
        ImageFileCreateEntry(name=file_name,
                                 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(base_image_url + "/laranja/" + 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, images=tagged_images_with_regions)
if not upload_result.is_batch_successful:
    print("Falha na tentativa de envia imagem!")
    for image in upload_result.images:
        print("Status da Imagem: ", image.status)
    exit(-1)

#import time
#print ("Treinando...")
#iteration = trainer.train_project(project.id)
#while (iteration.status != "Completo"):
#    iteration = trainer.get_iteration(project.id, iteration.id)
#    print ("Status de treinamento: " + iteration.status)
#    time.sleep(1)

# The iteration is now trained. Publish it to the project endpoint
Example #10
0
    def trainModel(self, database, modelID, parameters, onMessage, onFinished):
        onMessage("Trainer fetching model settings.")
        session = database.cursor()
        session.execute(
            "SELECT remote_id, training_data, extra_info FROM " +
            self._datatableName + " WHERE id = %s", (modelID, ))
        result = session.fetchone()
        session.close()

        if result:
            projectID, trainingData, _ = result

            onMessage("Training starting...")

            onMessage("Retrieving model...")
            trainer = CustomVisionTrainingClient(self._trainingKey,
                                                 endpoint=self._endPoint)
            project = trainer.get_project(projectID)

            onMessage("Downloading/Caching and Analyzing training data...")

            imageList = []
            dataClassList = {}

            try:
                start = time.time()
                # retrieve information of created tags
                createdTags = trainer.get_tags(projectID)
                for tag in createdTags:
                    dataClassList[tag.name] = tag

                imageOK = 0
                imageFailed = 0
                imageTotal = len(trainingData)

                def visualizeImageDownload():
                    return "(" + str(imageOK) + "/" + str(
                        imageFailed) + "/" + str(imageTotal) + ")"

                for photoID in trainingData:
                    image, _, err = self._serverAPI.getResource(
                        database, photoID)

                    if err:
                        imageFailed += 1
                        onMessage("Failed to download image " + str(photoID) +
                                  ". Error: " + err + " " +
                                  visualizeImageDownload())
                    else:
                        imageOK += 1

                        classOfData = str(trainingData[photoID])

                        # create tag if not exists
                        if classOfData not in dataClassList:
                            dataClassList[classOfData] = trainer.create_tag(
                                project.id, classOfData)

                        isOK, encodedImage = cv2.imencode('.png', image)
                        imageList.append(
                            ImageFileCreateEntry(
                                name=str(photoID) + ".png",
                                contents=encodedImage,
                                tag_ids=[dataClassList[classOfData].id]))

                        onMessage(visualizeImageDownload())
                end = time.time()
                onMessage("Image caching done. Used: " + str(end - start))

                start = time.time()
                for i in range(0, len(imageList), 64):
                    batch = imageList[i:i + 64]
                    upload_result = trainer.create_images_from_files(
                        project.id, images=batch)

                    if not upload_result.is_batch_successful:
                        onMessage("Image batch upload failed.")

                        for image in upload_result.images:
                            onMessage("Image status: ", image.status)

                        onFinished(False)
                        return
                end = time.time()
                onMessage("Image upload done. Used: " + str(end - start))

                onMessage("Training model with " + str(imageOK) + " photos...")

                iteration = trainer.train_project(project.id)
                while (iteration.status != "Completed"):
                    iteration = trainer.get_iteration(project.id, iteration.id)
                    onMessage("Training status: " + iteration.status)
                    time.sleep(3)

                # The iteration is now trained. Publish it to the project endpoint
                trainer.publish_iteration(project.id, iteration.id, projectID,
                                          self._resourceID)
                onMessage("Training done.")
                onFinished(True)

            except Exception as err:
                onMessage("Failed to train.")
                onMessage("Error Message: " + str(err))
                onFinished(False)
        else:
            onMessage("The trainer can't recognize the given model any more.")
            onFinished(False)
Example #11
0
                ImageFileCreateEntry(name=img,
                                     contents=image_contents.read(),
                                     tag_ids=[tag.id]))


# Create chunks of 64 images
def chunks(l, n):
    for i in range(0, len(l), n):
        yield l[i:i + n]


batchedImages = chunks(image_list, 64)

# Upload the images in batches of 64 to the Custom Vision Service
for batchOfImages in batchedImages:
    upload_result = trainer.create_images_from_files(project.id,
                                                     images=batchOfImages)

# Train the model
import time
iteration = trainer.train_project(project.id)
while (iteration.status != "Completed"):
    iteration = trainer.get_iteration(project.id, iteration.id)
    print("Training status: " + iteration.status)
    time.sleep(1)

# Publish the iteration of the model
publish_iteration_name = '<INSERT ITERATION NAME>'
resource_identifier = '<INSERT RESOURCE IDENTIFIER>'
trainer.publish_iteration(project.id, iteration.id, publish_iteration_name,
                          resource_identifier)
Example #12
0
class UploadDataset:
    def __init__(self, files_to_upload: list, project_name: str) -> None:
        self.files_to_upload = files_to_upload

        credentials = ApiKeyCredentials(
            in_headers={"Training-key": TRAINING_KEY})
        self.trainer = CustomVisionTrainingClient(TRAINING_ENDPOINT,
                                                  credentials)

        self.project_name = project_name

        self.max_byte_size = 4000000

        self.project: Project = self._connect_to_or_create_project(
            project_name=self.project_name)
        # Make two tags in the new project
        self.green_car_seal_tag = self._get_or_create_tag("green_car_seal")
        self.red_car_seal_tag = self._get_or_create_tag("red_car_seal")
        self.label_to_tag_id = {
            0: self.red_car_seal_tag.id,
            1: self.green_car_seal_tag.id,
        }

    def _connect_to_or_create_project(self, project_name: str) -> Project:
        projects = self.trainer.get_projects()
        project_id = next((p.id for p in projects if p.name == project_name),
                          None)

        if project_id is not None:
            print("Connecting to existing project...")
            return self.trainer.get_project(project_id)

        print("Creating new project...")
        obj_detection_domain = next(
            domain for domain in self.trainer.get_domains()
            if domain.type == "ObjectDetection" and domain.name == "General")
        return self.trainer.create_project(project_name,
                                           domain_id=obj_detection_domain.id)

    def _get_or_create_tag(self, tag_name) -> Tag:
        tags = self.trainer.get_tags(self.project.id)
        for tag in tags:
            if tag.name == tag_name:
                return self.trainer.get_tag(self.project.id, tag.id)

        return self.trainer.create_tag(self.project.id, tag_name)

    def _read_annotation_file(self, annotation_path: str) -> list:
        annotations = []
        with open(annotation_path, "r") as f:

            for line in f:
                line = line.strip()
                parameter_list = line.split(" ")
                label = int(parameter_list[0])
                x, y, w, h = list(map(float, parameter_list[1:]))

                left = x - w / 2
                if left < 0:  # Accounting for previous rounding error
                    left = 0
                top = y - h / 2
                if top < 0:  # Accounting for previous rounding error
                    top = 0

                if left + w > 1:  # Accounting for previous rounding error
                    w = 1 - left
                if top + h > 1:  # Accounting for previous rounding error
                    h = 1 - top

                try:
                    tag_id = self.label_to_tag_id[label]
                except:
                    raise ValueError(
                        f"Wrong label {label} at {annotation_path}")

                annotations.append(
                    Region(
                        tag_id=tag_id,
                        left=left,
                        top=top,
                        width=w,
                        height=h,
                    ))
        return annotations

    def main(self) -> None:
        dataset_path = os.path.join(os.path.dirname(__file__),
                                    "../../../dataset")

        existing_image_count = self.trainer.get_image_count(
            project_id=self.project.id)
        file_number = existing_image_count
        self.files_to_upload = self.files_to_upload[file_number:]

        for file_name in self.files_to_upload:
            tagged_images_with_regions = []

            annotations: list = self._read_annotation_file(
                annotation_path=os.path.join(dataset_path, "annotations",
                                             file_name + ".txt"), )
            image_bytes: bytes = read_and_resize_image(
                image_path=os.path.join(dataset_path, "images",
                                        file_name + ".JPG"),
                max_byte_size=self.max_byte_size,
            )
            print(f"Image {file_name} is {len(image_bytes)} bytes")
            tagged_images_with_regions.append(
                ImageFileCreateEntry(name=file_name,
                                     contents=image_bytes,
                                     regions=annotations))
            print("Upload images...")
            upload_result = self.trainer.create_images_from_files(
                self.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)
            print(
                f"Uploaded file number {file_number+1} of {len(self.files_to_upload)}"
            )
            file_number += 1
Example #13
0
class AzureCVObjectDetectionAPI(object):
    """
     A warper class for simplifying the use of Azure Custom Vision Object Detections
    """
    def __init__(self, endpoint, key, resource_id, project_id=None):
        """ 
        Class Constructor, takes the id from Azure Custom Vision. Here the key will
        be used both for training and predicition
        
        Args:
        ----
        endpoint: str
        key: str
        resource_id: str
        project_id: str
        """

        training_credentials = ApiKeyCredentials(
            in_headers={"Training-key": key})
        prediction_credentials = ApiKeyCredentials(
            in_headers={"Prediction-key": key})

        self.trainer = CustomVisionTrainingClient(endpoint,
                                                  training_credentials)
        self.predictor = CustomVisionPredictionClient(endpoint,
                                                      prediction_credentials)
        self.project_id = project_id
        self.tags = {}

        if project_id is not None:
            for t in self.trainer.get_tags(project_id):
                self.tags[t.name] = t.id

        return

    def create_project(self, project_name):
        """
        Create a object detection project with name as project_name. Swith to this project
        when creation is complete.

        Args:
        ----
        project_name: str
        """
        # Find the object detection domain
        obj_detection_domain = next(
            domain for domain in trainer.get_domains()
            if domain.type == "ObjectDetection" and domain.name == "General")

        # Create a new project
        print("Creating project...")
        project = trainer.create_project(project_name,
                                         domain_id=obj_detection_domain.id)
        self.project_id = project.id

        return

    def create_tag(self, tag_name):
        """
        Create a tag at the current object detection project.

        Args:
        ----
        project_name: str
        """
        assert (self.project_id is not None)
        tag = self.trainer.create_tag(self.project_id, tag_name)
        self.tags[tag.name] = tag.id

        return

    def _upload_one_batch_training_images(self, tagged_images_with_regions):
        """
        Upload one batch (maximum 64) training images to Azure Custom Vision Object Detection.
        Only for internal use with in this class.
        
        Args:
        ----
        tagged_images_with_regions: list of ImageFileCreateEntry 
        
        """

        upload_result = self.trainer.create_images_from_files(
            self.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)

        return

    def upload_training_images(self, training_labeled_images):
        """
        Upload training images to Azure Custom Vision Object Detection.
        
        Args:
        ----
        training_lableded_images: list of labeledImage
        """
        assert (self.project_id is not None)

        print("Adding images...")
        tagged_images_with_regions = []
        batch = 0

        for i in range(len(training_labeled_images)):
            if i > 0 and (i % 64) == 0:
                batch += 1
                print("Adding images: batch ", batch)
                self._upload_one_batch_training_images(
                    tagged_images_with_regions)
                tagged_images_with_regions = []

            # accumulating labels within one batch
            labeled_img = training_labeled_images[i]

            for t, labels in labeled_img.labels.items():

                if t not in self.tags.keys(): self.create_tag(t)

                tag_id = self.tags[t]

                regions = []
                for m in labels:
                    x, y, w, h = normalize_coordinates(m, labeled_img.shape)
                    regions.append(
                        Region(tag_id=tag_id, left=x, top=y, width=w,
                               height=h))

            with open(labeled_img.path, mode="rb") as image_contents:
                tagged_images_with_regions.append(
                    ImageFileCreateEntry(name=labeled_img.name,
                                         contents=image_contents.read(),
                                         regions=regions))

        batch += 1
        if len(tagged_images_with_regions) > 0:
            print("Adding images: batch ", batch)
            self._upload_one_batch_training_images(tagged_images_with_regions)

        return
              "rb") as image_contents:
        image_list.append(
            ImageFileCreateEntry(name=file_name,
                                 contents=image_contents.read(),
                                 tag_ids=[hemlock_tag.id]))

for image_num in range(1, 11):
    file_name = "japanese_cherry_{}.jpg".format(image_num)
    with open(base_image_location + "images/Japanese Cherry/" + file_name,
              "rb") as image_contents:
        image_list.append(
            ImageFileCreateEntry(name=file_name,
                                 contents=image_contents.read(),
                                 tag_ids=[cherry_tag.id]))

upload_result = trainer.create_images_from_files(
    project.id, ImageFileCreateBatch(images=image_list))
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)
# </snippet_upload>

# <snippet_train>
print("Training...")
iteration = trainer.train_project(project.id)
while (iteration.status != "Completed"):
    iteration = trainer.get_iteration(project.id, iteration.id)
    print("Training status: " + iteration.status)
    time.sleep(1)
def train_project(training_key):
    trainer = CustomVisionTrainingClient(training_key, endpoint=ENDPOINT)

    # Find the object detection domain
    obj_detection_domain = next(domain for domain in trainer.get_domains()
                                if domain.type == "ObjectDetection")

    # Create a new project
    print("Creating project...")
    project = trainer.create_project("My Detection Project",
                                     domain_id=obj_detection_domain.id)

    # Make two tags in the new project
    fork_tag = trainer.create_tag(project.id, "fork")
    scissors_tag = trainer.create_tag(project.id, "scissors")

    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],
        "fork_10": [0.05269608, 0.282303959, 0.8088235, 0.452614367],
        "fork_11": [0.05759804, 0.0894935, 0.9007353, 0.3251634],
        "fork_12": [0.3345588, 0.07315363, 0.375, 0.9150327],
        "fork_13": [0.269607842, 0.194068655, 0.4093137, 0.6732026],
        "fork_14": [0.143382356, 0.218578458, 0.7977941, 0.295751631],
        "fork_15": [0.19240196, 0.0633497, 0.5710784, 0.8398692],
        "fork_16": [0.140931368, 0.480016381, 0.6838235, 0.240196079],
        "fork_17": [0.305147052, 0.2512582, 0.4791667, 0.5408496],
        "fork_18": [0.234068632, 0.445702642, 0.6127451, 0.344771236],
        "fork_19": [0.219362751, 0.141781077, 0.5919118, 0.6683006],
        "fork_20": [0.180147052, 0.239820287, 0.6887255, 0.235294119]
    }

    scissors_image_regions = {
        "scissors_1": [0.4007353, 0.194068655, 0.259803921, 0.6617647],
        "scissors_2": [0.426470578, 0.185898721, 0.172794119, 0.5539216],
        "scissors_3": [0.289215684, 0.259428144, 0.403186262, 0.421568632],
        "scissors_4": [0.343137264, 0.105833367, 0.332107842, 0.8055556],
        "scissors_5": [0.3125, 0.09766343, 0.435049027, 0.71405226],
        "scissors_6": [0.379901975, 0.24308826, 0.32107842, 0.5718954],
        "scissors_7": [0.341911763, 0.20714055, 0.3137255, 0.6356209],
        "scissors_8": [0.231617644, 0.08459154, 0.504901946, 0.8480392],
        "scissors_9": [0.170343131, 0.332957536, 0.767156839, 0.403594762],
        "scissors_10": [0.204656869, 0.120539248, 0.5245098, 0.743464053],
        "scissors_11": [0.05514706, 0.159754932, 0.799019635, 0.730392158],
        "scissors_12": [0.265931368, 0.169558853, 0.5061275, 0.606209159],
        "scissors_13": [0.241421565, 0.184264734, 0.448529422, 0.6830065],
        "scissors_14": [0.05759804, 0.05027781, 0.75, 0.882352948],
        "scissors_15": [0.191176474, 0.169558853, 0.6936275, 0.6748366],
        "scissors_16": [0.1004902, 0.279036, 0.6911765, 0.477124184],
        "scissors_17": [0.2720588, 0.131977156, 0.4987745, 0.6911765],
        "scissors_18": [0.180147052, 0.112369314, 0.6262255, 0.6666667],
        "scissors_19": [0.333333343, 0.0274019931, 0.443627447, 0.852941155],
        "scissors_20": [0.158088237, 0.04047389, 0.6691176, 0.843137264]
    }

    # 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(IMAGES_FOLDER, "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(IMAGES_FOLDER, "scissors", file_name + ".jpg"),
                  mode="rb") as image_contents:
            tagged_images_with_regions.append(
                ImageFileCreateEntry(name=file_name,
                                     contents=image_contents.read(),
                                     regions=regions))

    trainer.create_images_from_files(project.id,
                                     images=tagged_images_with_regions)

    print("Training...")
    iteration = trainer.train_project(project.id)
    while (iteration.status != "Completed"):
        iteration = trainer.get_iteration(project.id, iteration.id)
        print("Training status: " + iteration.status)
        time.sleep(1)

    # The iteration is now trained. Make it the default project endpoint
    trainer.update_iteration(project.id, iteration.id, is_default=True)
    print("Done!")
    return project, iteration
Example #16
0
                                 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(base_image_location + "images/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)

print("Training...")
iteration = trainer.train_project(project.id)
while iteration.status != "Completed":
    iteration = trainer.get_iteration(project.id, iteration.id)
    print("Training status: " + iteration.status)
    time.sleep(1)

# The iteration is now trained. Publish it to the project endpoint
trainer.publish_iteration(project.id, iteration.id, publish_iteration_name,
Example #17
0
def main(args):
    status = check_args(args)
    if status != 0:
        return status

    config_path = args[0]
    directory = args[1]
    water_or_boat = args[2]
    tag_str = ''
    has_tags = len(args) == 4
    if has_tags:
        tag_str = args[3]

    resource_dict = get_resource_dict(water_or_boat, config_path)

    credentials = ApiKeyCredentials(
        in_headers={"Training-key": resource_dict['access_key']})
    trainer = CustomVisionTrainingClient(resource_dict['endpoint'],
                                         credentials)

    counter = 0
    image_list = []
    tag_ids = []

    if has_tags:
        tags, existing_tags = get_correct_tags(tag_str, resource_dict, trainer)
        if not tags:
            tags_names = [tag_it.name for tag_it in existing_tags]
            print(f'unrecognized tag {tag_str}')
            print(f'Choose among {tags_names}')
            return 4
        tag_ids = [tag.id for tag in tags]

    with os.scandir(directory) as dir_it:
        for entry in dir_it:

            if not entry.is_file():
                print(f'Skipping not file {entry.name}')
                continue

            counter += 1

            filename = entry.path

            with open(filename, 'rb') as image_content:
                image_list.append(
                    ImageFileCreateEntry(name=filename,
                                         contents=image_content.read(),
                                         tag_ids=tag_ids))

            if counter == 64:
                print('Limit (64)Sending batch')
                upload_result = trainer.create_images_from_files(
                    resource_dict['project_id'], images=image_list)
                if not upload_result.is_batch_successful:
                    print('Failed to send batch')
                    for image in upload_result.images:
                        print('Image status: ', image.status)
                    return 1
                image_list = []
                counter = 0

        if image_list:
            print('Sending last batch')
            upload_result = trainer.create_images_from_files(
                resource_dict['project_id'], images=image_list)
            if not upload_result.is_batch_successful:
                print('Failed to send batch')
            for image in upload_result.images:
                print('Image status: ', image.status)
    return 0