def string_from_image(url_input): #print("here") predictor = CustomVisionPredictionClient( config["cv_id"], endpoint="https://eastus.api.cognitive.microsoft.com/") results = predictor.classify_image_url(config["project_id"], "version0.2", url_input) prediction = results.predictions[0] print(prediction) return prediction.tag_name.replace(' ', '+')
class CVClassifier: def __init__(self, blob_service_client): self.iteration_name = "drawings" self.prediction_credentials = ApiKeyCredentials( in_headers={"Prediction-key": prediction_key}) self.predictor = CustomVisionPredictionClient( ENDPOINT, self.prediction_credentials) def predict(self, url): res = self.predictor.classify_image_url(project_id, self.iteration_name, url) return res.predictions def train(self): pass
def customvision_predict(blob_url): prediction_credentials = ApiKeyCredentials( in_headers={ "Prediction-key": CustomVisionPredConstants.PREDICTION_KEY }) predictor = CustomVisionPredictionClient( CustomVisionPredConstants.ENDPOINT, prediction_credentials) results = predictor.classify_image_url( CustomVisionPredConstants.PROJECT_ID, CustomVisionPredConstants.ITERATION_NAME, blob_url) prediction_dict = {} for prediction in results.predictions: prediction_dict[prediction.tag_name] = round( prediction.probability * 100, 2) return prediction_dict
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, prediction_resource_id) print("Done!") liste = trainer.get_iterations(project.id) print(liste[0].status) # Now there is a trained endpoint that can be used to make a prediction prediction_credentials = ApiKeyCredentials( in_headers={"Prediction-key": prediction_key}) predictor = CustomVisionPredictionClient(ENDPOINT, prediction_credentials) test_image_url = "https://originaldataset.blob.core.windows.net/ambulance/4504435055132672.png" results = predictor.classify_image_url(project.id, publish_iteration_name, test_image_url) # Display the results. for prediction in results.predictions: print("\t" + prediction.tag_name + ": {0:.2f}%".format(prediction.probability * 100))
# 匯入必要模組 from azure.cognitiveservices.vision.customvision.prediction import CustomVisionPredictionClient from msrest.authentication import ApiKeyCredentials import os # 傳入prediction-key及endpoint credentials = ApiKeyCredentials( in_headers={"Prediction-key": '8d30ba3f687644c582153ad00394cd9c'}) predictor = CustomVisionPredictionClient( endpoint='https://westus2.api.cognitive.microsoft.com/', credentials=credentials) # 傳入project.id, publish_iteration_name, url results = predictor.classify_image_url( 'ffdffd19-564f-415a-ab4c-be56c8665ffc', 'Iteration5', url='https://b.ecimg.tw/items/DMAG22A45252914/000001_1524455444.jpg') # 印出預測結果 for prediction in results.predictions: print("\t" + prediction.tag_name + ": {0:.2f}%".format(prediction.probability * 100))
# It is just demo, we use first project in Custom Vison resource project = trainer.get_projects()[0] print('Project: ' + project.name) # It is just demo, we use first iteration in Custom Vison resource iteration = trainer.get_iterations(project.id)[0] print('Iteration: ' + iteration.name) credentials_prediction = ApiKeyCredentials( in_headers={"Prediction-key": prediction_key}) predictor = CustomVisionPredictionClient(ENDPOINT, credentials_prediction) image_urls = ['https://upload.wikimedia.org/wikipedia/commons/5/57/WoodPecker_Pivert_in_59650_%282%29.JPG', \ 'https://upload.wikimedia.org/wikipedia/commons/0/01/Un_passerotto_su_un_olivo_nella_primavera_2020_Uccellino.jpg', \ 'https://upload.wikimedia.org/wikipedia/commons/b/b2/Pica_1450098_Nevit.jpg', \ 'https://upload.wikimedia.org/wikipedia/commons/4/43/Kohlmeise_%2823%29_%2834632808830%29.jpg', \ 'https://upload.wikimedia.org/wikipedia/commons/4/42/Merel_%28Turdus_merula%29.jpg'] for image_url in image_urls: results = predictor.classify_image_url(project.id, iteration.name, url=image_url) print(image_url) # Display the results. for prediction in results.predictions: print("\t" + prediction.tag_name + ": {0:.2f}%".format(prediction.probability * 100)) print()
class Customvision(): """Custom Vision 操作クラス Azure Custom Vision service を操作するためのクラス。 config.pyに設定した Custom Vision 接続キーがインスタンスに必要。 Attributes: predictor: CustomVisionPredictionClient クラスのインスタンス trainer: CustomVisionTrainingClient クラスのインスタンス project_name (str): トレーニング済みの Custom Vision Project の名前 publish_iteration_name (str): 公開されたイテレーションの名前 """ def __init__(self, training_key, prediction_key, endpoint, project_name,\ publish_iteration_name): #コンストラクタの定義 self.predictor = CustomVisionPredictionClient(prediction_key, endpoint=endpoint) self.trainer = CustomVisionTrainingClient(training_key, endpoint=endpoint) self.project_name = project_name self.publish_iteration_name = publish_iteration_name #トレーニング済みの指定プロジェクト検索 def _get_train_project(self): """トレーニング済みの Project を検索して返却 CustomVisionTrainingClientのインスタンスからポータル上で作成された project を取得する。 取得した project の中から指定した project があるかを比較する。 Returns: 指定した project があった場合、 取得した project を返却。 なかった場合は、None を返却する。 """ ret_project = None for project in self.trainer.get_projects(): if project.name == self.project_name: ret_project = project return ret_project #CustomVisionによる解析結果を走行データに格納して返却 def get_prediction(self, blob_url): """走行データリストに Custom Vision 解析結果を格納して返却 Custom Vision ポータルでトレーニング済みの Project を検索。 BlobコンテナのURLを指定して画像を解析させ、画像解析結果を取得する。 Args: entities (list): 走行データのリスト blob_url (str): BlobコンテナへのアクセスURL Returns: """ #トレーニング済みの指定プロジェクト検索 project = self._get_train_project() #CustomVisionによるAI解析開始 results = self.predictor.classify_image_url(project.id,\ self.publish_iteration_name, blob_url) #数値高い順に並び替え predictions = sorted(results.predictions, key=lambda prob: prob.probability, reverse=True) return predictions
# 匯入必要模組 from azure.cognitiveservices.vision.customvision.prediction import CustomVisionPredictionClient from msrest.authentication import ApiKeyCredentials import os # 傳入prediction-key及endpoint credentials = ApiKeyCredentials(in_headers={"Prediction-key": '8d30ba3f687644c582153ad00394cd9c'}) predictor = CustomVisionPredictionClient(endpoint='https://treasuretrain.cognitiveservices.azure.com/', credentials=credentials) # 傳入project.id, publish_iteration_name, url results = predictor.classify_image_url('98f4c3f7-6eb2-4ba7-9fc4-78eb1cf3b3a0', 'Iteration1', url='https://lh3.googleusercontent.com/proxy/OVqisfrc5aQFdeVfUD33YGVNir05aiomFD7T7Tj5hiIFLvIg2uwiZLEBVbmFiBPevT2dEM8VSL-2Ue_uS-VB9jBljjoey1JAxA') # 印出預測結果 for prediction in results.predictions: print("\t" + prediction.tag_name + ": {0:.2f}%".format(prediction.probability * 100))
class Classifier: """ Class for interacting with Custom Vision. Contatins three key methods: - predict_imgage() / predicts a an image - upload_images() / reads image URLs from Blob Storage and uploads to Custom Vision - train() / trains a model """ def __init__(self) -> None: """ Reads configuration file Initializes connection to Azure Custom Vision predictor and training resources. Parameters: blob_service_client: Azure Blob Service interaction client Returns: None """ self.ENDPOINT = Keys.get("CV_ENDPOINT") self.project_id = Keys.get("CV_PROJECT_ID") self.prediction_key = Keys.get("CV_PREDICTION_KEY") self.training_key = Keys.get("CV_TRAINING_KEY") self.base_img_url = Keys.get("BASE_BLOB_URL") self.prediction_resource_id = Keys.get("CV_PREDICTION_RESOURCE_ID") self.prediction_credentials = ApiKeyCredentials( in_headers={"Prediction-key": self.prediction_key}) self.predictor = CustomVisionPredictionClient( self.ENDPOINT, self.prediction_credentials) self.training_credentials = ApiKeyCredentials( in_headers={"Training-key": self.training_key}) self.trainer = CustomVisionTrainingClient(self.ENDPOINT, self.training_credentials) connect_str = Keys.get("BLOB_CONNECTION_STRING") self.blob_service_client = BlobServiceClient.from_connection_string( connect_str) try: # get all project iterations iterations = self.trainer.get_iterations(self.project_id) # find published iterations puplished_iterations = [ iteration for iteration in iterations if iteration.publish_name != None ] # get the latest published iteration puplished_iterations.sort(key=lambda i: i.created) self.iteration_name = puplished_iterations[-1].publish_name with api.app.app_context(): models.update_iteration_name(self.iteration_name) except Exception as e: logging.info(e) self.iteration_name = "iteration1" def predict_image_url(self, img_url: str) -> Dict[str, float]: """ Predicts label(s) of Image read from URL. Parameters: img_url: Image URL Returns: (prediction (dict[str,float]): labels and assosiated probabilities, best_guess: (str): name of the label with highest probability) """ with api.app.app_context(): self.iteration_name = models.get_iteration_name() res = self.predictor.classify_image_url(self.project_id, self.iteration_name, img_url) pred_kv = dict([(i.tag_name, i.probability) for i in res.predictions]) best_guess = max(pred_kv, key=pred_kv.get) return pred_kv, best_guess def predict_image(self, img) -> Dict[str, float]: """ Predicts label(s) of Image read from URL. ASSUMES: -image of type .png -image size less than 4MB -image resolution at least 256x256 pixels Parameters: img_url: .png file Returns: (prediction (dict[str,float]): labels and assosiated probabilities, best_guess: (str): name of the label with highest probability) """ with api.app.app_context(): self.iteration_name = models.get_iteration_name() res = self.predictor.classify_image_with_no_store( self.project_id, self.iteration_name, img) # reset the file head such that it does not affect the state of the file handle img.seek(0) pred_kv = dict([(i.tag_name, i.probability) for i in res.predictions]) best_guess = max(pred_kv, key=pred_kv.get) return pred_kv, best_guess def predict_image_by_post(self, img) -> Dict[str, float]: """ Predicts label(s) of Image read from URL. ASSUMES: -image of type .png -image size less than 4MB -image resolution at least 256x256 pixels Parameters: img_url: .png file Returns: (prediction (dict[str,float]): labels and assosiated probabilities, best_guess: (str): name of the label with highest probability) """ headers = { 'content-type': 'application/octet-stream', "prediction-key": self.prediction_key } res = requests.post(Keys.get("CV_PREDICTION_ENDPOINT"), img.read(), headers=headers).json() img.seek(0) pred_kv = dict([(i["tagName"], i["probability"]) for i in res["predictions"]]) best_guess = max(pred_kv, key=pred_kv.get) return pred_kv, best_guess def __chunks(self, lst, n): """ Helper method used by upload_images() to upload URL chunks of 64, which is maximum chunk size in Azure Custom Vision. """ for i in range(0, len(lst), n): yield lst[i:i + n] def upload_images(self, labels: List, container_name) -> None: """ Takes as input a list of labels, uploads all assosiated images to Azure Custom Vision project. If label in input already exists in Custom Vision project, all images are uploaded directly. If label in input does not exist in Custom Vision project, new label (Tag object in Custom Vision) is created before uploading images Parameters: labels (str[]): List of labels Returns: None """ url_list = [] existing_tags = list(self.trainer.get_tags(self.project_id)) try: container = self.blob_service_client.get_container_client( container_name) except Exception as e: print( "could not find container with CONTAINER_NAME name error: ", str(e), ) for label in labels: # check if input has correct type if not isinstance(label, str): raise Exception("label " + str(label) + " must be a string") tag = [t for t in existing_tags if t.name == label] # check if tag already exists if len(tag) == 0: try: tag = self.trainer.create_tag(self.project_id, label) print("Created new label in project: " + label) except Exception as e: print(e) continue else: tag = tag[0] blob_prefix = f"{label}/" blob_list = container.list_blobs(name_starts_with=blob_prefix) if not blob_list: raise AttributeError("no images for this label") # build correct URLs and append to URL list for blob in blob_list: blob_url = f"{self.base_img_url}/{container_name}/{blob.name}" url_list.append( ImageUrlCreateEntry(url=blob_url, tag_ids=[tag.id])) # upload URLs in chunks of 64 print("Uploading images from blob to CV") img_f = 0 img_s = 0 img_d = 0 itr_img = 0 chunks = self.__chunks(url_list, setup.CV_MAX_IMAGES) num_imgs = len(url_list) error_messages = set() for url_chunk in chunks: upload_result = self.trainer.create_images_from_urls( self.project_id, images=url_chunk) if not upload_result.is_batch_successful: for image in upload_result.images: if image.status == "OK": img_s += 1 elif image.status == "OKDuplicate": img_d += 1 else: error_messages.add(image.status) img_f += 1 itr_img += 1 else: batch_size = len(upload_result.images) img_s += batch_size itr_img += batch_size prc = itr_img / num_imgs print( f"\t succesfull: \033[92m {img_s:5d} \033]92m \033[0m", f"\t duplicates: \033[33m {img_d:5d} \033]33m \033[0m", f"\t failed: \033[91m {img_f:5d} \033]91m \033[0m", f"\t [{prc:03.2%}]", sep="", end="\r", flush=True, ) print() if len(error_messages) > 0: print("Error messages:") for error_message in error_messages: print(f"\t {error_message}") def get_iteration(self): iterations = self.trainer.get_iterations(self.project_id) iterations.sort(key=(lambda i: i.created)) newest_iteration = iterations[-1] return newest_iteration def delete_iteration(self) -> None: """ Deletes the oldest iteration in Custom Vision if there are 11 iterations. Custom Vision allows maximum 10 iterations in the free version. """ iterations = self.trainer.get_iterations(self.project_id) if len(iterations) >= setup.CV_MAX_ITERATIONS: iterations.sort(key=lambda i: i.created) oldest_iteration = iterations[0].id self.trainer.unpublish_iteration(self.project_id, oldest_iteration) self.trainer.delete_iteration(self.project_id, oldest_iteration) def train(self, labels: list) -> None: """ Trains model on all labels specified in input list, exeption is raised by self.trainer.train_projec() is asked to train on non existent labels. Generates unique iteration name, publishes model and sets self.iteration_name if successful. Parameters: labels (str[]): List of labels """ try: email = Keys.get("EMAIL") except Exception: print("No email found, setting to empty") email = "" self.delete_iteration() print("Training...") iteration = self.trainer.train_project( self.project_id, reserved_budget_in_hours=1, notification_email_address=email, ) # Wait for training to complete start = time.time() while iteration.status != "Completed": iteration = self.trainer.get_iteration(self.project_id, iteration.id) minutes, seconds = divmod(time.time() - start, 60) print( f"Training status: {iteration.status}", f"\t[{minutes:02.0f}m:{seconds:02.0f}s]", end="\r", ) time.sleep(1) print() # The iteration is now trained. Publish it to the project endpoint iteration_name = uuid.uuid4() self.trainer.publish_iteration( self.project_id, iteration.id, iteration_name, self.prediction_resource_id, ) with api.app.app_context(): self.iteration_name = models.update_iteration_name(iteration_name) def delete_all_images(self) -> None: """ Function for deleting uploaded images in Customv Vision. """ try: self.trainer.delete_images(self.project_id, all_images=True, all_iterations=True) except Exception as e: raise Exception("Could not delete all images: " + str(e)) def retrain(self): """ Train model on all labels and update iteration. """ with api.app.app_context(): labels = models.get_all_labels() self.upload_images(labels, setup.CONTAINER_NAME_NEW) try: self.train(labels) except CustomVisionErrorException as e: msg = "No changes since last training" print(e, "exiting...") raise excp.BadRequest(msg) def hard_reset_retrain(self): """ Train model on all labels and update iteration. This method sleeps for 60 seconds to make sure all old images are deleted from custom vision before uploading original dataset. """ with api.app.app_context(): labels = models.get_all_labels() # Wait 60 seconds to make sure all images are deleted in custom vision time.sleep(60) self.upload_images(labels, setup.CONTAINER_NAME_ORIGINAL) try: self.train(labels) except CustomVisionErrorException as e: msg = "No changes since last training" print(e, "exiting...") raise excp.BadRequest(msg)
from azure.cognitiveservices.vision.customvision.prediction import CustomVisionPredictionClient prediction_key = '<INSERT PREDICTION KEY>' cv_endpoint = '<INSERT CUSTOM VISION ENDPOINT>' predictor = CustomVisionPredictionClient(prediction_key, endpoint=cv_endpoint) image_url = "https://missedprints.com/wp-content/uploads/2014/03/marge-simpson-lego-minifig.jpg" predictor.classify_image_url(project.id, publish_iteration_name, url=image_url) for prediction in results.predictions: print("\t" + prediction.tag_name + ": {0:.2f}%".format(prediction.probability * 100))