# Depth Anything V2

## 개요

Depth Anything V2는 Lihe Yang 외 연구진이 발표한 [동명의 논문](https://huggingface.co/papers/2406.09414)에서 소개되었습니다. 기존 [Depth Anything 모델](depth_anything)과 동일한 아키텍처를 사용하지만, 합성 데이터와 더 큰 용량의 teacher 모델을 활용하여 훨씬 정밀하고 견고한 깊이 예측을 수행합니다.

해당 논문의 초록은 다음과 같습니다:

*본 연구에서는 Depth Anything V2를 소개합니다. 화려한 기법을 추구하기보다, 강력한 단안 깊이 추정 모델을 구축하기 위한 중요한 발견을 제시하는 것을 목표로 합니다. 특히 V1과 비교할 때, 이 버전은 세 가지 핵심 관행을 통해 훨씬 더 정밀하고 견고한 깊이 예측을 생성합니다: 1) 모든 라벨이 붙은 실제 이미지를 합성 이미지로 대체, 2) teacher 모델의 용량 확장, 3) 대규모 의사 라벨이 붙은 실제 이미지를 매개로 student 모델 학습. Stable Diffusion을 기반으로 구축된 최신 모델과 비교할 때, 우리의 모델은 훨씬 더 효율적(10배 이상 빠름)이고 정확합니다. 다양한 시나리오를 지원하기 위해 다양한 규모(25M에서 1.3B 파라미터 범위)의 모델을 제공합니다. 이러한 모델의 강력한 일반화 능력을 활용하여, metric depth 라벨로 fine-tuning하여 metric depth 모델을 획득했습니다. 또한, 현재 테스트 세트의 제한된 다양성과 빈번한 노이즈를 고려하여, 정밀한 주석과 다양한 장면으로 구성된 범용 평가 벤치마크를 구축하여 향후 연구를 촉진합니다.*

<img src="https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/transformers/model_doc/depth_anything_overview.jpg"
alt="drawing" width="600"/>

 Depth Anything 개요. 원 논문에서 가져왔습니다.

Depth Anything 모델은 [nielsr](https://huggingface.co/nielsr)에 의해 기여되었습니다. 원래 코드는 [여기](https://github.com/DepthAnything/Depth-Anything-V2)에서 찾을 수 있습니다.

## 사용 예시

Depth Anything V2를 사용하는 주요 방법은 두 가지입니다. 모든 복잡성을 추상화해 주는 pipeline API를 사용하는 방법과, `DepthAnythingForDepthEstimation` 클래스를 직접 사용하는 방법입니다.

### Pipeline API

pipeline을 사용하면 몇 줄의 코드로 모델을 사용할 수 있습니다:

```python
import requests
from PIL import Image

from transformers import pipeline

# load pipe
pipe = pipeline(task="depth-estimation", model="depth-anything/Depth-Anything-V2-Small-hf")

# load image
url = 'http://images.cocodataset.org/val2017/000000039769.jpg'
image = Image.open(requests.get(url, stream=True).raw)

# inference
depth = pipe(image)["depth"]
```

### 모델 직접 사용

사전 처리와 사후 처리를 직접 수행하려면 다음을 따르세요:

```python
import requests
import torch
from PIL import Image

from transformers import AutoImageProcessor, AutoModelForDepthEstimation

url = "http://images.cocodataset.org/val2017/000000039769.jpg"
image = Image.open(requests.get(url, stream=True).raw)

image_processor = AutoImageProcessor.from_pretrained("depth-anything/Depth-Anything-V2-Small-hf")
model = AutoModelForDepthEstimation.from_pretrained("depth-anything/Depth-Anything-V2-Small-hf", device_map="auto")

# prepare image for the model
inputs = image_processor(images=image, return_tensors="pt").to(model.device)

with torch.no_grad():
    outputs = model(**inputs)

# interpolate to original size and visualize the prediction
post_processed_output = image_processor.post_process_depth_estimation(
    outputs,
    target_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"))
```

## 리소스

Depth Anything를 시작하는 데 도움이 되는 공식 Hugging Face 및 커뮤니티(🌎로 표시) 리소스 목록입니다.

- [단안 깊이 추정 작업 가이드](../tasks/monocular_depth_estimation)
- [Depth Anything V2 데모](https://huggingface.co/spaces/depth-anything/Depth-Anything-V2).
- [DepthAnythingForDepthEstimation](/docs/transformers/main/ko/model_doc/depth_anything#transformers.DepthAnythingForDepthEstimation)를 사용한 추론을 보여주는 노트북은 [여기](https://github.com/NielsRogge/Transformers-Tutorials/blob/master/Depth%20Anything/Predicting_depth_in_an_image_with_Depth_Anything.ipynb)에서 확인할 수 있습니다. 🌎
- [Apple Silicon에서 사용하기 위한 `small` 변형의 Core ML 변환](https://huggingface.co/apple/coreml-depth-anything-v2-small).

여기에 포함할 리소스를 제출하고 싶으시면 Pull Request를 열어 주시면 검토하겠습니다! 기존 리소스와 중복되지 않고 새로운 것을 보여주는 것이 이상적입니다.

## DepthAnythingConfig[[transformers.DepthAnythingConfig]]

#### transformers.DepthAnythingConfig[[transformers.DepthAnythingConfig]]

```python
transformers.DepthAnythingConfig(transformers_version: str | None = None, architectures: list[str] | None = None, output_hidden_states: bool | None = False, return_dict: bool | None = True, dtype: str | torch.dtype | None = None, chunk_size_feed_forward: int = 0, is_encoder_decoder: bool = False, id2label: dict[int, str] | dict[str, str] | None = None, label2id: dict[str, int] | dict[str, str] | None = None, problem_type: Literal['regression', 'single_label_classification', 'multi_label_classification'] | None = None, backbone_config: dict | transformers.configuration_utils.PreTrainedConfig | None = None, patch_size: int | list[int] | tuple[int, int] = 14, initializer_range: float = 0.02, reassemble_hidden_size: int = 384, reassemble_factors: list[int | float] | tuple[int | float, ...] = (4, 2, 1, 0.5), neck_hidden_sizes: list[int] | tuple[int, ...] = (48, 96, 192, 384), fusion_hidden_size: int = 64, head_in_index: int = -1, head_hidden_size: int = 32, depth_estimation_type: str = 'relative', max_depth: int | None = 1)
```

[소스](https://github.com/huggingface/transformers/blob/main/src/transformers/models/depth_anything/configuration_depth_anything.py#L25)

**매개변수:**

backbone_config (`Union[dict, ~configuration_utils.PreTrainedConfig]`, *선택*) : 백본 모델의 구성입니다.

patch_size (`Union[int, list[int], tuple[int, int]]`, *선택*, 기본값 `14`) : 각 패치의 크기(해상도).

initializer_range (`float`, *선택 사항*, 기본값 `0.02`) : 모든 가중치 행렬을 초기화하는 truncated_normal_initializer의 표준 편차입니다.

reassemble_hidden_size (`int`, *선택 사항*, 기본값 384) : reassemble 레이어의 입력 채널 수입니다.

reassemble_factors (`list[int]`, *선택 사항*, 기본값 `[4, 2, 1, 0.5]`) : reassemble 레이어의 업/다운샘플링 계수입니다.

neck_hidden_sizes (`list[str]`, *선택 사항*, 기본값 `[48, 96, 192, 384]`) : 백본의 feature maps를 투영할 hidden sizes입니다.

fusion_hidden_size (`int`, *선택 사항*, 기본값 64) : 퓨전 전의 채널 수입니다.

head_in_index (`int`, *선택 사항*, 기본값 -1) : 깊이 추정 헤드에서 사용할 기능의 인덱스입니다.

head_hidden_size (`int`, *선택 사항*, 기본값 32) : 깊이 추정 헤드(depth estimation head)의 두 번째 컨볼루션의 출력 채널 수입니다.

depth_estimation_type (`str`, *선택 사항*, 기본값 `"relative"`) : 사용할 깊이 추정 유형입니다. `["relative", "metric"]` 중 하나여야 합니다.

max_depth (`float`, *선택 사항*) : "metric" 깊이 추정 헤드에 사용할 최대 깊이입니다. 실내 모델에는 20, 야외 모델에는 80을 사용해야 합니다. "relative" 깊이 추정의 경우 이 값은 무시됩니다.

이것은 Depth AnythingModel의 구성을 저장하기 위한 구성 클래스입니다. 지정된 인자에 따라 Depth Anything 모델을 인스턴스화하여 모델 아키텍처를 정의하는 데 사용됩니다. 기본값으로 구성을 인스턴스화하면 [LiheYoung/depth-anything-small-hf](https://huggingface.co/LiheYoung/depth-anything-small-hf)와 유사한 구성이 생성됩니다.

Configuration 객체는 [PreTrainedConfig](/docs/transformers/main/ko/main_classes/configuration#transformers.PreTrainedConfig)를 상속하며, 모델 출력을 제어하는 데 사용할 수 있습니다. 자세한 내용은 [PreTrainedConfig](/docs/transformers/main/ko/main_classes/configuration#transformers.PreTrainedConfig)의 문서를 참고하세요.

예:

```python
>>> from transformers import DepthAnythingConfig, DepthAnythingForDepthEstimation

>>> # Initializing a DepthAnything small style configuration
>>> configuration = DepthAnythingConfig()

>>> # Initializing a model from the DepthAnything small style configuration
>>> model = DepthAnythingForDepthEstimation(configuration)

>>> # Accessing the model configuration
>>> configuration = model.config
```

## DepthAnythingForDepthEstimation[[transformers.DepthAnythingForDepthEstimation]]

#### transformers.DepthAnythingForDepthEstimation[[transformers.DepthAnythingForDepthEstimation]]

```python
transformers.DepthAnythingForDepthEstimation(config: DepthAnythingConfig)
```

[소스](https://github.com/huggingface/transformers/blob/main/src/transformers/models/depth_anything/modeling_depth_anything.py#L316)

**매개변수:**

config ([DepthAnythingConfig](/docs/transformers/main/ko/model_doc/depth_anything#transformers.DepthAnythingConfig)) : 모델의 모든 매개변수를 포함하는 모델 구성 클래스입니다. 구성 파일로 초기화하는 것은 모델과 관련된 가중치를 로드하지 않으며, 구성 정보만 로드합니다. 모델 가중치를 로드하려면 [from_pretrained()](/docs/transformers/main/ko/main_classes/model#transformers.PreTrainedModel.from_pretrained) 메서드를 확인하세요.

KITTI, NYUv2 등에 사용되는, 상단에 깊이 추정 헤드(3개의 합성곱 계층으로 구성)가 있는 Depth Anything Model

이 모델은 [PreTrainedModel](/docs/transformers/main/ko/main_classes/model#transformers.PreTrainedModel)에서 상속됩니다. 라이브러리가 모든 모델에 대해 구현하는 일반적 메서드(다운로드 또는 저장, 입력 임베딩 크기 조정, 헤드 프루닝 등)에 대해서는 상위 클래스 문서를 확인하세요.

이 모델은 또한 PyTorch [torch.nn.Module](https://pytorch.org/docs/stable/nn.html#torch.nn.Module)의 하위 클래스입니다. 일반적인 PyTorch Module처럼 사용하며, 일반적인 사용법과 동작에 관한 모든 사항은 PyTorch 문서를 참조하세요.

#### forward[[transformers.DepthAnythingForDepthEstimation.forward]]

```python
forward(pixel_values: Tensor, labels: typing.Optional[torch.LongTensor] = None, output_attentions: bool | None = None, output_hidden_states: bool | None = None, return_dict: bool | None = None, **kwargs)
```

[소스](https://github.com/huggingface/transformers/blob/main/src/transformers/models/depth_anything/modeling_depth_anything.py#L327)

**매개변수:**

pixel_values (`torch.Tensor`, shape `(batch_size, num_channels, image_size, image_size)`) : 입력 이미지에 해당하는 텐서입니다. [DPTImageProcessor](/docs/transformers/main/ko/model_doc/dpt#transformers.DPTImageProcessor)를 사용하여 픽셀 값을 얻을 수 있습니다. 자세한 내용은 [DPTImageProcessor.__call__()](/docs/transformers/main/ko/model_doc/molmo2#transformers.Molmo2ImageProcessor.__call__)를 참조하세요 (`processor_class`는 이미지를 처리하는 데 [DPTImageProcessor](/docs/transformers/main/ko/model_doc/dpt#transformers.DPTImageProcessor)를 사용합니다).

labels (`torch.LongTensor`, shape `(batch_size, height, width)`, *선택 사항*) : 손실을 계산하기 위한 ground truth depth estimation 맵.

output_attentions (`bool`, *선택 사항*) : 모든 어텐션 레이어의 어텐션 텐서를 반환할지 여부. 자세한 내용은 반환 텐서 섹션의 `attentions`를 참조하세요.

output_hidden_states (`bool`, *선택 사항*) : 모든 레이어의 hidden states를 반환할지 여부. 자세한 내용은 반환되는 텐서 중 `hidden_states` 항목을 참조하세요.

return_dict (`bool`, *선택 사항*) : 일반 튜플 대신 [ModelOutput](/docs/transformers/main/ko/main_classes/output#transformers.utils.ModelOutput)를 반환할지 여부.

**반환값:** [DepthEstimatorOutput](/docs/transformers/main/ko/main_classes/output#transformers.modeling_outputs.DepthEstimatorOutput) 또는 `tuple(torch.Tensor)`

[DepthEstimatorOutput](/docs/transformers/main/ko/main_classes/output#transformers.modeling_outputs.DepthEstimatorOutput) 또는 `torch.Tensor`의 튜플(`return_dict=False`이 전달되었거나 `config.return_dict=False`인 경우)로, 구성([DepthAnythingConfig](/docs/transformers/main/ko/model_doc/depth_anything#transformers.DepthAnythingConfig)) 및 입력에 따라 다양한 요소를 포함합니다.

[DepthAnythingForDepthEstimation](/docs/transformers/main/ko/model_doc/depth_anything#transformers.DepthAnythingForDepthEstimation)의 forward 메서드는 `__call__` 특수 메서드를 오버라이드합니다.

`Module` 인스턴스는 전처리 및 후처리 단계를 실행하는 것을 처리하지만, 이 함수는 해당 단계를 조용히 무시하므로, 순전파(forward pass) 레시피를 이 함수 내에서 정의해야 하더라도 이후에는 이 함수 대신 `Module` 인스턴스를 호출해야 합니다.

- **loss** (`torch.Tensor`, shape `(1,)`, *선택*, `labels`이 제공될 때 반환됨) -- 분류(또는 config.num_labels==1인 경우 회귀) 손실.
- **predicted_depth** (shape가 `(batch_size, height, width)`인 `torch.Tensor`) -- 각 픽셀에 대한 예측된 깊이.
- **hidden_states** (`tuple(torch.Tensor)`, *선택 사항*, `output_hidden_states=True`가 전달되었거나 `config.output_hidden_states=True`인 경우 반환됨) -- `torch.Tensor`의 튜플(모델에 임베딩 레이어가 있는 경우 임베딩 출력 1개 + 각 레이어의 출력 1개)로, 모양은 `(batch_size, num_channels, height, width)`입니다.

  각 레이어의 출력에서 모델의 Hidden-states와 선택적 초기 임베딩 출력을 포함합니다.
- **attentions** (`tuple(torch.Tensor)`, *선택 사항*, `output_attentions=True`가 전달되었거나 `config.output_attentions=True`인 경우 반환) -- 각 레이어당 하나씩, shape가 `(batch_size, num_heads, patch_size, sequence_length)`인 `torch.Tensor`의 튜플.

  self-attention 헤드에서 가중 평균을 계산하는 데 사용되는 attention softmax 이후의 attention 가중치입니다.

예:
```python
>>> from transformers import AutoImageProcessor, AutoModelForDepthEstimation
>>> import torch
>>> import numpy as np
>>> from PIL import Image
>>> from huggingface_hub.utils import httpx
>>> from io import BytesIO

>>> url = "http://images.cocodataset.org/val2017/000000039769.jpg"
>>> with httpx.stream("GET", url) as response:
...     image = Image.open(BytesIO(response.read()))

>>> image_processor = AutoImageProcessor.from_pretrained("LiheYoung/depth-anything-small-hf")
>>> model = AutoModelForDepthEstimation.from_pretrained("LiheYoung/depth-anything-small-hf")

>>> # prepare image for the model
>>> inputs = image_processor(images=image, return_tensors="pt")

>>> with torch.no_grad():
...     outputs = model(**inputs)

>>> # interpolate to original size
>>> post_processed_output = image_processor.post_process_depth_estimation(
...     outputs,
...     target_sizes=[(image.height, image.width)],
... )

>>> # visualize the prediction
>>> predicted_depth = post_processed_output[0]["predicted_depth"]
>>> depth = predicted_depth * 255 / predicted_depth.max()
>>> depth = depth.detach().cpu().numpy()
>>> depth = Image.fromarray(depth.astype("uint8"))
```

