Azure Blob Storage

Azure Blob Storage から Roboflow に画像をアップロードする

Azure Blob Storage における画像データの保存と Roboflow へのアップロードを扱う場合、一般的に 2 つの選択肢があります: 署名付き URL を使用する方法、または画像をローカルに手動でダウンロードして(Azure CLI 経由で)ローカルからアップロードする方法です。どちらの方法を選ぶかは、データ処理や管理に関する具体的なニーズによります。

  • Signed URLs(サイン付き URL):この方法は、画像をローカルマシンにダウンロードするという追加の手順や時間の消費を回避したい場合に特に有利です。署名付き URL を使用すれば、画像データを一度もローカルに保存することなく、Azure Blob Storage から直接 Roboflow API にアップロードできます。その結果、処理が速くなり、ローカルシステムへの負荷も軽減されます。

  • CLI Locally(ローカル CLI):画像をまずローカル環境にダウンロードしたいというケースもあるかもしれません。たとえば、画像を事前処理したり、Roboflow にアップロードする前に手動で確認したりする必要がある場合、ローカルにコピーを保持しておくことが有益です。

適切な方法の選択は、データ転送の速度、事前処理の必要性、画像の手動検査など、あなたの具体的なユースケース要件に依存します。

Azure 接続文字列

Storage Account を作成した後、Azure ポータルの「Security + networking」の「Access keys」セクションでアクセスキーや接続文字列を確認できます。これらの資格情報はアプリケーションの認証に使用されます。

オプション 1: サイン付き URL 経由でのアップロード:

Azure SDK for Python を使用して、Azure Blob Storage の画像に対する署名付き URL を生成できます。

def get_blob_sas_url(blob_service_client, container_name: str, blob_name: str) -> str:
    """Azure Blob の SAS URL を生成する。"""
    from azure.storage.blob import generate_blob_sas, BlobSasPermissions
    from datetime import datetime, timedelta

    sas_token = generate_blob_sas(
        blob_service_client.account_name,
        container_name,
        blob_name,
        account_key=blob_service_client.credential.account_key,
        permission=BlobSasPermissions(read=True),
        expiry=datetime.utcnow() + timedelta(hours=1)
    )
    
    blob_url = f"https://{blob_service_client.account_name}.blob.core.windows.net/{container_name}/{blob_name}?{sas_token}"
    return blob_url

上のコードスニペットでは、blob service client、コンテナ名、および blob 名が必要です。画像の署名付き URL が生成され、返されます。

これを基に、Azure Blob Storage 内の利用可能なオブジェクトをすべて取得してから、それらを Roboflow に API 経由でアップロードする完全なソリューションを生成できます。このソリューションの概要は以下のとおりです:

from azure.storage.blob import BlobServiceClient
import requests
import urllib.parse

# ************* SET THESE VARIABLES *************
AZURE_CONNECTION_STRING = "YOUR_AZURE_CONNECTION_STRING"
AZURE_CONTAINER_NAME = "YOUR_AZURE_CONTAINER_NAME"
ROBOFLOW_API_KEY = "YOUR_ROBOFLOW_API_KEY"
ROBOFLOW_PROJECT_NAME = "YOUR_ROBOFLOW_PROJECT_NAME"
# ***********************************************

def get_blob_sas_url(blob_service_client, container_name: str, blob_name: str) -> str:
    """Azure Blob の SAS URL を生成する。"""
    from azure.storage.blob import generate_blob_sas, BlobSasPermissions
    from datetime import datetime, timedelta

    sas_token = generate_blob_sas(
        blob_service_client.account_name,
        container_name,
        blob_name,
        account_key=blob_service_client.credential.account_key,
        permission=BlobSasPermissions(read=True),
        expiry=datetime.utcnow() + timedelta(hours=1)
    )
    
    blob_url = f"https://{blob_service_client.account_name}.blob.core.windows.net/{container_name}/{blob_name}?{sas_token}"
    return blob_url

def get_azure_blob_objects(container_name: str) -> list:
    """指定した Azure Blob コンテナ内の blob 名のリストを取得する。"""
    blob_service_client = BlobServiceClient.from_connection_string(AZURE_CONNECTION_STRING)
    container_client = blob_service_client.get_container_client(container_name)
    
    blobs = []
    blob_list = container_client.list_blobs()
    for blob in blob_list:
        blobs.append(blob.name)
    return blobs

def upload_to_roboflow(api_key: str, project_name: str, presigned_url: str, img_name='', split="train"):
    """画像を Roboflow にアップロードする。"""
    API_URL = "https://api.roboflow.com"
    if img_name == '':
        img_name = presigned_url.split("/")[-1]

    upload_url = "".join([
        API_URL + "/dataset/" + project_name + "/upload",
        "?api_key=" + api_key,
        "&name=" + img_name,
        "&split=" + split,
        "&image=" + urllib.parse.quote_plus(presigned_url),
    ])
    response = requests.post(upload_url)

    # レスポンスコードを確認
    if response.status_code == 200:
        print(f"Successfully uploaded {img_name} to {project_name}")
        return True
    else:
        print(f"Failed to upload {img_name}. Error: {response.content.decode('utf-8')}")
        return False

if __name__ == "__main__":
    # 利用可能なブロブのリストを取得
    available_blobs = get_azure_blob_objects(AZURE_CONTAINER_NAME)
    
    # オプション: ここでブロブをフィルタリング
    # 例: available_blobs = [blob for blob in available_blobs if "some_condition"]
    
    # Azure Blob Service Client を初期化
    blob_service_client = BlobServiceClient.from_connection_string(AZURE_CONNECTION_STRING)
    
    # ブロブを Roboflow にアップロード
    for blob in available_blobs:
        blob_url = get_blob_sas_url(blob_service_client, AZURE_CONTAINER_NAME, blob)
        upload_to_roboflow(ROBOFLOW_API_KEY, ROBOFLOW_PROJECT_NAME, blob_url)

オプション 2: Azure からデータをローカルにダウンロードする

まず、 azcopy コマンドラインユーティリティをインストールします。このユーティリティを使うと Azure Storage からファイルやフォルダをダウンロードできます。次に、Shared Access Signature を使用して Azure アカウントに認証します。 Shared Access Signature トークンについての詳細は、 SAS トークンの取得方法 azcopy のドキュメントで確認できます。

一度 azcopy 準備が整ったら、ファイルやフォルダをダウンロードするために次のコマンドを実行します:

azcopy copy "C:\local\path" <sas-token> --recursive=true

次の部分を置き換えてください C:\local\path はダウンロードしたいフォルダまたはファイルのパスです。 <sas-token> の値を認証用の SAS トークンに置き換えてください。ファイルやフォルダを再帰的にダウンロードしたい場合は、上記のように --recursive=true 引数を指定してください。そうでない場合はこの引数を削除します。

Roboflow へデータをアップロード

データをダウンロードしたら、次に示すいずれかの方法で Roboflow にアップロードできます: Upload Web Interface(アップロード Web インターフェース) または Roboflow CLI.

でヘルプを投稿できます。

Last updated

Was this helpful?