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.")
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!")
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)
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
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': '*' })
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
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
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)
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)
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
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
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,
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