File size: 8,902 Bytes
67268c3
2fe8c1c
 
67268c3
 
 
 
2fe8c1c
 
 
67268c3
 
8bc9393
67268c3
a0bc766
 
3c25380
cf4547c
a0bc766
 
cf4547c
 
a0bc766
 
cf4547c
e7f7813
67268c3
a0bc766
 
2ba1175
573674f
 
0ad3b4a
a0bc766
 
 
 
 
 
 
 
 
0ad3b4a
2fe8c1c
a0bc766
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
a94c4e0
a0bc766
67268c3
a0bc766
 
 
 
 
 
 
 
67268c3
 
 
a0bc766
 
 
67268c3
 
a0bc766
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
67268c3
a0bc766
 
 
 
 
 
 
20d983a
a0bc766
 
 
67268c3
a0bc766
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
67268c3
a0bc766
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
67268c3
a0bc766
2fe8c1c
a0bc766
 
2fe8c1c
a0bc766
 
 
 
 
 
20d983a
a0bc766
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2fe8c1c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
---
datasets:
- Borcherding/Depth2RobotsV2_Annotations
tags:
- depth-to-robot
- image-to-image
- cyclegan
- depth-to-anything
base_model:
- keras-io/CycleGAN
---

# CycleGAN_Depth2RobotsV2_Blend Model

This model transforms depth maps into robot-style images, and also transforms robot-style images into estimated depth maps using CycleGAN architecture.

<div style="display: flex; flex-wrap: wrap; justify-content: center;">
  <div style="display: flex; width: 100%; justify-content: center; margin-bottom: 10px;">
    <img src="testOutput/depth2image/custom_real.png" alt="depth map" title="Depth Map (Input)" width="45%">
    <img src="testOutput/depth2image/custom_fake.png" alt="robot-style image" title="Robot-Style Image (Output)" width="45%">
  </div>
  <div style="display: flex; width: 100%; justify-content: center;">
    <img src="testOutput/image2depth/custom_real.png" alt="robot-style image" title="Robot-Style Image (Input)" width="45%">
    <img src="testOutput/image2depth/custom_fake.png" alt="depth map" title="Depth Map (Output)" width="45%">
  </div>
</div>

## Model Description

- This model was trained on robot images generated with SDXL, and their associated depth maps, taken with Depth-Anything-V2:
[Depth2RobotsV2_Annotations](https://huggingface.co/datasets/Borcherding/Depth2RobotsV2_Annotations)
-   using CycleGAN architecture
-   Training notebooks and dataset genertors can be found in the src folder, and can also be found in the github repo !(Ollama-Agent-Roll-Cage/controlnet-2-anything)[https://github.com/Ollama-Agent-Roll-Cage/controlnet-2-anything]
- It supports bidirectional transformation:
  - Depth map → Robot-style imagery
  - Robot-style imagery → Depth map
- The model uses a ResNet-based generator with residual blocks

## Installation

```bash
# Clone the repository
git clone https://github.com/Ollama-Agent-Roll-Cage/controlnet-2-anything
cd cycleGAN_Depth2RobotsV2

# Install dependencies
pip install torch torchvision gradio pyvirtualcam
```

## Usage Options

### Option 1: Simple Test Interface

Run the simple test interface to quickly try out the model:

```bash
python cycleGANtest.py
```

This launches a Gradio interface where you can:
- Upload an image
- Select conversion direction (Depth to Image or Image to Depth)
- Transform the image with a single click

### Option 2: Webcam Integration with Depth Estimation

For a more advanced setup that includes real-time webcam processing with Depth Anything V2:

```bash
# Set the path to Depth Anything V2
export DEPTH_ANYTHING_V2_PATH=/path/to/depth-anything-v2

# Run the integrated application
python discordDepth2AnythingGAN.py
```

This launches a Gradio interface that allows you to:
- Capture webcam input
- Generate depth maps using Depth Anything V2
- Apply winter-themed colormap to depth maps
- Apply CycleGAN transformation in either direction
- Output to a virtual camera for use in video conferencing or streaming

## Using the Model Programmatically

```python
import torch
import numpy as np
import torchvision.transforms as transforms
from PIL import Image
from huggingface_hub import hf_hub_download

# Define the Generator architecture (as shown in the provided code)
class ResidualBlock(nn.Module):
    def __init__(self, channels):
        super(ResidualBlock, self).__init__()
        self.conv_block = nn.Sequential(
            nn.ReflectionPad2d(1),
            nn.Conv2d(channels, channels, 3),
            nn.InstanceNorm2d(channels),
            nn.ReLU(inplace=True),
            nn.ReflectionPad2d(1),
            nn.Conv2d(channels, channels, 3),
            nn.InstanceNorm2d(channels)
        )

    def forward(self, x):
        return x + self.conv_block(x)

class Generator(nn.Module):
    def __init__(self, input_channels=3, output_channels=3, n_residual_blocks=9):
        super(Generator, self).__init__()
        
        # Initial convolution
        model = [
            nn.ReflectionPad2d(3),
            nn.Conv2d(input_channels, 64, 7),
            nn.InstanceNorm2d(64),
            nn.ReLU(inplace=True)
        ]
        
        # Downsampling
        in_features = 64
        out_features = in_features * 2
        for _ in range(2):
            model += [
                nn.Conv2d(in_features, out_features, 3, stride=2, padding=1),
                nn.InstanceNorm2d(out_features),
                nn.ReLU(inplace=True)
            ]
            in_features = out_features
            out_features = in_features * 2
        
        # Residual blocks
        for _ in range(n_residual_blocks):
            model += [ResidualBlock(in_features)]
        
        # Upsampling
        out_features = in_features // 2
        for _ in range(2):
            model += [
                nn.ConvTranspose2d(in_features, out_features, 3, stride=2, padding=1, output_padding=1),
                nn.InstanceNorm2d(out_features),
                nn.ReLU(inplace=True)
            ]
            in_features = out_features
            out_features = in_features // 2
        
        # Output layer
        model += [
            nn.ReflectionPad2d(3),
            nn.Conv2d(64, output_channels, 7),
            nn.Tanh()
        ]
        
        self.model = nn.Sequential(*model)
    
    def forward(self, x):
        return self.model(x)

# Download the model
def download_model(direction="depth2image"):
    if direction == "depth2image":
        filename = "latest_net_G_A.pth"
    else:  # "image2depth"
        filename = "latest_net_G_B.pth"
    
    model_path = hf_hub_download(
        repo_id="Borcherding/CycleGAN_Depth2RobotsV2_Blend", 
        filename=filename
    )
    return model_path

# Image preprocessing
def preprocess_image(image):
    """
    Preprocess image for model input
    
    Args:
        image: PIL Image or numpy array
    
    Returns:
        torch.Tensor: Normalized tensor ready for model input
    """
    if isinstance(image, np.ndarray):
        image = Image.fromarray(image.astype('uint8'), 'RGB')
    
    transform = transforms.Compose([
        transforms.Resize(256),
        transforms.ToTensor(),
        transforms.Normalize(mean=[0.5, 0.5, 0.5], std=[0.5, 0.5, 0.5])
    ])
    
    return transform(image).unsqueeze(0)

# Image postprocessing
def postprocess_image(tensor):
    """
    Convert model output tensor to numpy image
    
    Args:
        tensor: Model output tensor
    
    Returns:
        numpy.ndarray: RGB image array (0-255)
    """
    tensor = tensor.squeeze(0).cpu()
    tensor = (tensor + 1) / 2
    tensor = tensor.clamp(0, 1)
    tensor = tensor.permute(1, 2, 0).numpy()
    return (tensor * 255).astype(np.uint8)

# Example usage
def transform_image(input_image_path, direction="depth2image"):
    """
    Transform an image using the Depth2Robot model
    
    Args:
        input_image_path: Path to input image
        direction: "depth2image" or "image2depth"
    
    Returns:
        numpy.ndarray: Transformed image
    """
    # Load model
    model_path = download_model(direction)
    model = Generator()
    model.load_state_dict(torch.load(model_path, map_location='cpu'), strict=False)
    model.eval()
    
    # Load and preprocess image
    input_image = Image.open(input_image_path).convert('RGB')
    input_tensor = preprocess_image(input_image)
    
    # Generate output
    with torch.no_grad():
        output_tensor = model(input_tensor)
    
    # Postprocess output
    output_image = postprocess_image(output_tensor)
    
    return output_image
```

## Model Checkpoints 

The model checkpoints are available on Hugging Face:
- Repository: [Borcherding/Depth2RobotsV2_Annotations](https://huggingface.co/datasets/Borcherding/Depth2RobotsV2_Annotations)
- Files:
  - `latest_net_G_A.pth` - Generator for Depth to Robot Image transformation
  - `latest_net_G_B.pth` - Generator for Robot Image to Depth transformation

## Integration with Depth Anything V2

The integrated application (`discordDepth2AnythingGAN.py`) also leverages [Depth Anything V2](https://github.com/depth-anything/Depth-Anything-V2) for real-time depth estimation, providing a complete pipeline:

1. Capture webcam input
2. Generate depth maps with Depth Anything V2
3. Apply CycleGAN transformation
4. Output to virtual camera

## Requirements

- Python 3.7+
- PyTorch 1.7+
- torchvision
- gradio
- pyvirtualcam (for webcam integration)
- OpenCV (cv2)
- Depth Anything V2 (for integrated application)

## License

[Insert your license information here]

## Acknowledgments

- This model uses CycleGAN architecture from the paper [Unpaired Image-to-Image Translation using Cycle-Consistent Adversarial Networks](https://arxiv.org/abs/1703.10593) by Zhu et al.
- The implementation is based on [junyanz/pytorch-CycleGAN-and-pix2pix](https://github.com/junyanz/pytorch-CycleGAN-and-pix2pix)
- Integrated application leverages Depth Anything V2 for depth estimation