Transformers documentation
単眼深度推定
単眼深度推定
単眼深度推定は、単一の画像からシーンの深度情報を予測するコンピュータビジョンのタスクです。言い換えれば、単一のカメラ視点からシーン内のオブジェクトまでの距離を推定するプロセスです。
単眼深度推定は、3D再構成、拡張現実(AR)、自動運転、ロボティクスなど、さまざまな応用分野があります。このタスクは、シーン内のオブジェクト間の複雑な関係と、それに対応する深度情報をモデルが理解する必要があり、照明条件、遮蔽、テクスチャなどの要因の影響を受ける可能性があるため、困難な課題です。
深度推定には、主に2つのカテゴリがあります。
絶対深度推定: このタスクのバリアントは、カメラからの正確な深度測定値を提供することを目的としています。この用語は、メートルやフィートなどの正確な単位で深度が提供されるメトリック深度推定と、同義に使用されます。絶対深度推定モデルは、実世界の距離を表す数値を含む深度マップを出力します。
相対深度推定: 相対深度推定は、正確な測定値を提供せずに、シーン内のオブジェクトや点の深度順序を予測することを目的としています。これらのモデルは、A と B までの実際の距離を示すことなく、シーンのどの部分が互いに近いか遠いかを示す深度マップを出力します。
このガイドでは、最先端のゼロショット相対深度推定モデルであるDepth Anything V2と、絶対深度推定モデルであるZoeDepthを用いた推論のやり方について説明します。
Depth Estimationタスクのページを参照し、互換性のあるアーキテクチャとチェックポイントのすべてを確認してください。
開始に先立ち、Transformers の最新バージョンをインストールする必要があります。
pip install -q -U transformers
深度推定パイプライン
深度推定に対応するモデルで推論を試す最も簡単な方法は、対応するpipeline()を使用することです。 Hugging Face Hub上のチェックポイントからパイプラインをインスタンス化します:
>>> from transformers import pipeline
from accelerate import Accelerator
>>> import torch
>>> device = Accelerator().device
>>> checkpoint = "depth-anything/Depth-Anything-V2-base-hf"
>>> pipe = pipeline("depth-estimation", model=checkpoint, device=device)次に、分析する画像を選択します:
>>> from PIL import Image
>>> import requests
>>> url = "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/bee.jpg"
>>> image = Image.open(requests.get(url, stream=True).raw)
>>> image
画像をパイプラインに渡します。
>>> predictions = pipe(image)パイプラインは2つのエントリを持つ辞書を返します。1つ目のpredicted_depthは、各ピクセルの深度をメートル単位で表した値を持つテンソルです。2つ目のdepthは、深度推定の結果を可視化したPIL画像です。
可視化された結果を見てみましょう:
>>> predictions["depth"]
手動による深度推定推論
深度推定パイプラインの使い方を確認したので、次は同じ結果を手動で再現する方法を見ていきましょう。
Hugging Face Hub上のチェックポイントからモデルと関連するプロセッサを読み込むことから始めます。 ここでは、以前と同じチェックポイントを使用します:
>>> from transformers import AutoImageProcessor, AutoModelForDepthEstimation
>>> checkpoint = "Intel/zoedepth-nyu-kitti"
>>> image_processor = AutoImageProcessor.from_pretrained(checkpoint)
>>> model = AutoModelForDepthEstimation.from_pretrained(checkpoint).to(device)image_processor を使用して、リサイズや正規化などの必要な画像変換を処理し、モデル用の画像入力を準備します:
>>> pixel_values = image_processor(image, return_tensors="pt").pixel_values.to(device)準備した入力をモデルに渡します:
>>> import torch
>>> with torch.no_grad():
... outputs = model(pixel_values)結果を後処理して、パディングを除去し、深度マップを元の画像サイズにリサイズしましょう。post_process_depth_estimation は、"predicted_depth" を含む辞書のリストを出力します。
>>> # ZoeDepth dynamically pads the input image. Thus we pass the original image size as argument
>>> # to `post_process_depth_estimation` to remove the padding and resize to original dimensions.
>>> post_processed_output = image_processor.post_process_depth_estimation(
... outputs,
... source_sizes=[(image.height, image.width)],
... )
>>> predicted_depth = post_processed_output[0]["predicted_depth"]
>>> depth = (predicted_depth - predicted_depth.min()) / (predicted_depth.max() - predicted_depth.min())
>>> depth = depth.detach().cpu().numpy() * 255
>>> depth = Image.fromarray(depth.astype("uint8"))元の実装では、ZoeDepthモデルは元画像と反転画像の両方で推論を実行し、その結果を平均化します。
post_process_depth_estimation関数は、反転された出力を任意のoutputs_flipped引数に渡すことで、この処理を代行してくれます。>>> with torch.no_grad(): ... outputs = model(pixel_values) ... outputs_flipped = model(pixel_values=torch.flip(inputs.pixel_values, dims=[3])) >>> post_processed_output = image_processor.post_process_depth_estimation( ... outputs, ... source_sizes=[(image.height, image.width)], ... outputs_flipped=outputs_flipped, ... )
