Spaces:
Running
on
Zero
Running
on
Zero
Claude
commited on
Add SHARP 3D Gaussian Splats Generator for Hugging Face Spaces
Browse files- Implement Gradio UI with SHARP inference
- Integrate Three.js PLY viewer for interactive 3D preview
- Add ZeroGPU support for dynamic GPU allocation
- Create Dockerfile for Python 3.13 environment
- Add GitHub Actions workflow for auto-sync to HF Spaces
- Include comprehensive Japanese README with HF metadata
Features:
- Single image to 3D Gaussian Splats conversion
- Real-time 3D preview using Three.js + PLYLoader
- PLY file download support
- Optimized for ZeroGPU (Nvidia H200)
Technical stack:
- Apple SHARP model
- Gradio 5.9
- Three.js for 3D rendering
- Python 3.13 (via Docker)
- .github/workflows/sync-to-hub.yml +55 -0
- .gitignore +11 -0
- Dockerfile +44 -0
- README.md +197 -2
- app.py +404 -0
- requirements.txt +23 -0
.github/workflows/sync-to-hub.yml
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
name: Sync to Hugging Face Spaces
|
| 2 |
+
|
| 3 |
+
on:
|
| 4 |
+
push:
|
| 5 |
+
branches:
|
| 6 |
+
- main
|
| 7 |
+
- claude/**
|
| 8 |
+
workflow_dispatch:
|
| 9 |
+
|
| 10 |
+
jobs:
|
| 11 |
+
sync-to-hub:
|
| 12 |
+
runs-on: ubuntu-latest
|
| 13 |
+
|
| 14 |
+
steps:
|
| 15 |
+
- name: Checkout repository
|
| 16 |
+
uses: actions/checkout@v4
|
| 17 |
+
with:
|
| 18 |
+
fetch-depth: 0
|
| 19 |
+
lfs: true
|
| 20 |
+
|
| 21 |
+
- name: Set up Python
|
| 22 |
+
uses: actions/setup-python@v5
|
| 23 |
+
with:
|
| 24 |
+
python-version: '3.11'
|
| 25 |
+
|
| 26 |
+
- name: Install Hugging Face CLI
|
| 27 |
+
run: |
|
| 28 |
+
pip install --upgrade huggingface_hub
|
| 29 |
+
|
| 30 |
+
- name: Push to Hugging Face Spaces
|
| 31 |
+
env:
|
| 32 |
+
HF_TOKEN: ${{ secrets.HF_TOKEN }}
|
| 33 |
+
run: |
|
| 34 |
+
# Hugging Face にログイン
|
| 35 |
+
huggingface-cli login --token $HF_TOKEN --add-to-git-credential
|
| 36 |
+
|
| 37 |
+
# Spaces リポジトリのURL
|
| 38 |
+
SPACE_URL="https://huggingface.co/spaces/YUGOROU/ml-sharp_ZeroGPU"
|
| 39 |
+
|
| 40 |
+
# Git設定
|
| 41 |
+
git config --global user.email "github-actions[bot]@users.noreply.github.com"
|
| 42 |
+
git config --global user.name "github-actions[bot]"
|
| 43 |
+
|
| 44 |
+
# Hugging Face Spacesにpush
|
| 45 |
+
git remote add hf https://huggingface.co/spaces/YUGOROU/ml-sharp_ZeroGPU || true
|
| 46 |
+
git push hf main --force
|
| 47 |
+
|
| 48 |
+
echo "✅ Successfully synced to Hugging Face Spaces!"
|
| 49 |
+
echo "🚀 Space URL: $SPACE_URL"
|
| 50 |
+
|
| 51 |
+
- name: Comment on commit
|
| 52 |
+
if: success()
|
| 53 |
+
run: |
|
| 54 |
+
echo "🎉 Deployment successful!"
|
| 55 |
+
echo "View your Space at: https://huggingface.co/spaces/YUGOROU/ml-sharp_ZeroGPU"
|
.gitignore
CHANGED
|
@@ -205,3 +205,14 @@ cython_debug/
|
|
| 205 |
marimo/_static/
|
| 206 |
marimo/_lsp/
|
| 207 |
__marimo__/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 205 |
marimo/_static/
|
| 206 |
marimo/_lsp/
|
| 207 |
__marimo__/
|
| 208 |
+
|
| 209 |
+
# SHARP / Gradio specific
|
| 210 |
+
*.ply
|
| 211 |
+
*.splat
|
| 212 |
+
*.mp4
|
| 213 |
+
*.avi
|
| 214 |
+
*.mov
|
| 215 |
+
gradio_cached_examples/
|
| 216 |
+
flagged/
|
| 217 |
+
tmp/
|
| 218 |
+
temp/
|
Dockerfile
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
FROM nvidia/cuda:12.4.0-cudnn-devel-ubuntu22.04
|
| 2 |
+
|
| 3 |
+
# 環境変数
|
| 4 |
+
ENV DEBIAN_FRONTEND=noninteractive \
|
| 5 |
+
PYTHONUNBUFFERED=1 \
|
| 6 |
+
GRADIO_SERVER_NAME=0.0.0.0 \
|
| 7 |
+
GRADIO_SERVER_PORT=7860
|
| 8 |
+
|
| 9 |
+
# システムパッケージの更新とPython 3.13のインストール
|
| 10 |
+
RUN apt-get update && apt-get install -y \
|
| 11 |
+
software-properties-common \
|
| 12 |
+
wget \
|
| 13 |
+
git \
|
| 14 |
+
&& add-apt-repository ppa:deadsnakes/ppa \
|
| 15 |
+
&& apt-get update \
|
| 16 |
+
&& apt-get install -y \
|
| 17 |
+
python3.13 \
|
| 18 |
+
python3.13-dev \
|
| 19 |
+
python3.13-venv \
|
| 20 |
+
python3-pip \
|
| 21 |
+
&& rm -rf /var/lib/apt/lists/*
|
| 22 |
+
|
| 23 |
+
# Python 3.13をデフォルトに設定
|
| 24 |
+
RUN update-alternatives --install /usr/bin/python3 python3 /usr/bin/python3.13 1 \
|
| 25 |
+
&& update-alternatives --install /usr/bin/python python /usr/bin/python3.13 1
|
| 26 |
+
|
| 27 |
+
# pipのアップグレード
|
| 28 |
+
RUN python3 -m pip install --upgrade pip setuptools wheel
|
| 29 |
+
|
| 30 |
+
# 作業ディレクトリ
|
| 31 |
+
WORKDIR /app
|
| 32 |
+
|
| 33 |
+
# 依存関係をコピーしてインストール
|
| 34 |
+
COPY requirements.txt .
|
| 35 |
+
RUN python3 -m pip install --no-cache-dir -r requirements.txt
|
| 36 |
+
|
| 37 |
+
# アプリケーションファイルをコピー
|
| 38 |
+
COPY . .
|
| 39 |
+
|
| 40 |
+
# ポート公開
|
| 41 |
+
EXPOSE 7860
|
| 42 |
+
|
| 43 |
+
# 起動コマンド
|
| 44 |
+
CMD ["python3", "app.py"]
|
README.md
CHANGED
|
@@ -1,2 +1,197 @@
|
|
| 1 |
-
|
| 2 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
---
|
| 2 |
+
title: SHARP 3D Gaussian Splats Generator
|
| 3 |
+
emoji: 🎨
|
| 4 |
+
colorFrom: blue
|
| 5 |
+
colorTo: purple
|
| 6 |
+
sdk: docker
|
| 7 |
+
pinned: false
|
| 8 |
+
license: mit
|
| 9 |
+
tags:
|
| 10 |
+
- 3d
|
| 11 |
+
- gaussian-splatting
|
| 12 |
+
- computer-vision
|
| 13 |
+
- apple
|
| 14 |
+
- sharp
|
| 15 |
+
- three.js
|
| 16 |
+
- zerogpu
|
| 17 |
+
---
|
| 18 |
+
|
| 19 |
+
# 🎨 SHARP: 3D Gaussian Splats Generator
|
| 20 |
+
|
| 21 |
+
<div align="center">
|
| 22 |
+
|
| 23 |
+
[](https://github.com/apple/ml-sharp)
|
| 24 |
+
[](https://arxiv.org/abs/2512.10685)
|
| 25 |
+
[](https://huggingface.co/apple/Sharp)
|
| 26 |
+
[](LICENSE)
|
| 27 |
+
|
| 28 |
+
**単一の画像から高品質な3D Gaussian Splatsを1秒以下で生成**
|
| 29 |
+
|
| 30 |
+
</div>
|
| 31 |
+
|
| 32 |
+
---
|
| 33 |
+
|
| 34 |
+
## 📋 概要
|
| 35 |
+
|
| 36 |
+
このSpaceは、Appleが開発した最新の単一画像3D再構成技術「**SHARP (Sharp Monocular View Synthesis)**」を使用して、1枚の写真から3D Gaussian Splatsを生成します。
|
| 37 |
+
|
| 38 |
+
生成された3DモデルはThree.jsを使用してブラウザ上でインタラクティブにプレビューでき、PLY形式でダウンロードも可能です。
|
| 39 |
+
|
| 40 |
+
### ✨ 主な特徴
|
| 41 |
+
|
| 42 |
+
- 🚀 **超高速処理**: 1秒以下で3D再構成(従来手法の300倍以上高速)
|
| 43 |
+
- 🎯 **高品質**: SOTA品質(LPIPS 25-34%改善、DISTS 21-43%改善)
|
| 44 |
+
- 🖼️ **簡単操作**: 画像をアップロードするだけで3D化
|
| 45 |
+
- 🎬 **リアルタイムプレビュー**: Three.jsによるインタラクティブな3D表示
|
| 46 |
+
- 📦 **PLYエクスポート**: 標準的なPLY形式でダウンロード可能
|
| 47 |
+
- ⚡ **ZeroGPU対応**: Nvidia H200による動的GPU割り当て
|
| 48 |
+
|
| 49 |
+
---
|
| 50 |
+
|
| 51 |
+
## 🎮 使い方
|
| 52 |
+
|
| 53 |
+
### 1. 画像のアップロード
|
| 54 |
+
左側のエリアに画像をアップロードまたはドラッグ&ドロップします。
|
| 55 |
+
|
| 56 |
+
### 2. 生成開始
|
| 57 |
+
「🚀 生成開始」ボタンをクリックします。ZeroGPU (Nvidia H200)で処理されます。
|
| 58 |
+
|
| 59 |
+
### 3. 3Dプレビュー
|
| 60 |
+
右側のビューアで生成された3D Gaussian Splatsをインタラクティブに確認できます。
|
| 61 |
+
|
| 62 |
+
**操作方法:**
|
| 63 |
+
- 🖱️ **ドラッグ**: 3Dモデルを回転
|
| 64 |
+
- 🔍 **スクロール**: ズームイン/アウト
|
| 65 |
+
- ⌨️ **右クリック+ドラッグ**: パン移動
|
| 66 |
+
|
| 67 |
+
### 4. ダウンロード
|
| 68 |
+
PLYファイルをダウンロードして、Blender、CloudCompare、MeshLabなどの3Dソフトウェアで使用できます。
|
| 69 |
+
|
| 70 |
+
---
|
| 71 |
+
|
| 72 |
+
## 🔧 技術スタック
|
| 73 |
+
|
| 74 |
+
### フレームワーク
|
| 75 |
+
- **モデル**: Apple SHARP
|
| 76 |
+
- **UI**: Gradio 5.9
|
| 77 |
+
- **3Dレンダリング**: Three.js + PLYLoader
|
| 78 |
+
- **GPU**: ZeroGPU (Nvidia H200)
|
| 79 |
+
- **言語**: Python 3.13
|
| 80 |
+
|
| 81 |
+
### 主要ライブラリ
|
| 82 |
+
```
|
| 83 |
+
torch==2.5.1
|
| 84 |
+
gsplat==1.5.3
|
| 85 |
+
gradio==5.9.1
|
| 86 |
+
timm==1.0.12
|
| 87 |
+
```
|
| 88 |
+
|
| 89 |
+
---
|
| 90 |
+
|
| 91 |
+
## 📊 技術詳細
|
| 92 |
+
|
| 93 |
+
### 入力仕様
|
| 94 |
+
- **対応形式**: JPEG, PNG, TIFF, HEIC
|
| 95 |
+
- **解像度**: 任意(内部で1536×1536にリサイズ)
|
| 96 |
+
- **推奨**: 明瞭な被写体、適切な照明
|
| 97 |
+
|
| 98 |
+
### 出力仕様
|
| 99 |
+
- **形式**: PLY (Polygon File Format)
|
| 100 |
+
- **内容**: 3D Gaussian Splats
|
| 101 |
+
- 位置 (x, y, z)
|
| 102 |
+
- スケール (3軸)
|
| 103 |
+
- 回転 (クォータニオン)
|
| 104 |
+
- 不透明度
|
| 105 |
+
- 球面調和係数 (色情報)
|
| 106 |
+
|
| 107 |
+
### パフォーマンス
|
| 108 |
+
- **推論時間**: 通常1秒以下
|
| 109 |
+
- **メモリ使用量**: ~4-8GB (GPU)
|
| 110 |
+
- **出力サイズ**: 数MB〜数十MB (画像により変動)
|
| 111 |
+
|
| 112 |
+
---
|
| 113 |
+
|
| 114 |
+
## 🌐 ローカル実行
|
| 115 |
+
|
| 116 |
+
### 前提条件
|
| 117 |
+
- Python 3.13
|
| 118 |
+
- CUDA 12.4+ (GPU使用の場合)
|
| 119 |
+
- 8GB以上のVRAM推奨
|
| 120 |
+
|
| 121 |
+
### インストール
|
| 122 |
+
```bash
|
| 123 |
+
# リポジトリをクローン
|
| 124 |
+
git clone https://github.com/YUGOROU/ml-sharp_ZeroGPU.git
|
| 125 |
+
cd ml-sharp_ZeroGPU
|
| 126 |
+
|
| 127 |
+
# 依存関係をインストール
|
| 128 |
+
pip install -r requirements.txt
|
| 129 |
+
|
| 130 |
+
# アプリケーションを起動
|
| 131 |
+
python app.py
|
| 132 |
+
```
|
| 133 |
+
|
| 134 |
+
### Dockerで実行
|
| 135 |
+
```bash
|
| 136 |
+
# Dockerイメージをビルド
|
| 137 |
+
docker build -t sharp-app .
|
| 138 |
+
|
| 139 |
+
# コンテナを起動
|
| 140 |
+
docker run -p 7860:7860 --gpus all sharp-app
|
| 141 |
+
```
|
| 142 |
+
|
| 143 |
+
ブラウザで `http://localhost:7860` にアクセスします。
|
| 144 |
+
|
| 145 |
+
---
|
| 146 |
+
|
| 147 |
+
## 📚 リソース
|
| 148 |
+
|
| 149 |
+
### 公式リンク
|
| 150 |
+
- **GitHub**: [apple/ml-sharp](https://github.com/apple/ml-sharp)
|
| 151 |
+
- **公式サイト**: [apple.github.io/ml-sharp](https://apple.github.io/ml-sharp/)
|
| 152 |
+
- **論文**: [arXiv:2512.10685](https://arxiv.org/abs/2512.10685)
|
| 153 |
+
- **モデル**: [Hugging Face](https://huggingface.co/apple/Sharp)
|
| 154 |
+
|
| 155 |
+
### 関連プロジェクト
|
| 156 |
+
- [GaussianSplats3D](https://github.com/mkkellogg/GaussianSplats3D) - Three.js用3DGSレンダラー
|
| 157 |
+
- [gsplat.js](https://github.com/huggingface/gsplat.js) - Hugging Face公式ライブラリ
|
| 158 |
+
- [antimatter15/splat](https://antimatter15.com/splat/) - WebGL PLYビューア
|
| 159 |
+
|
| 160 |
+
---
|
| 161 |
+
|
| 162 |
+
## ⚠️ 制限事項
|
| 163 |
+
|
| 164 |
+
- **ZeroGPUタイムアウト**: 関数実行は最大60秒
|
| 165 |
+
- **同時処理**: 複数ユーザーが同時にアクセスすると待機時間が発生
|
| 166 |
+
- **メモリ制限**: 非常に大きな画像は処理���きない場合があります
|
| 167 |
+
- **3D品質**: 単一画像からの推測のため、見えない部分の精度は限定的
|
| 168 |
+
|
| 169 |
+
---
|
| 170 |
+
|
| 171 |
+
## 📄 ライセンス
|
| 172 |
+
|
| 173 |
+
このプロジェクトはMITライセンスの下で公開されています。
|
| 174 |
+
|
| 175 |
+
ただし、SHARPモデル自体はApple独自のライセンス(apple-amlr)に従います。詳細は[公式リポジトリ](https://github.com/apple/ml-sharp)を参照してください。
|
| 176 |
+
|
| 177 |
+
---
|
| 178 |
+
|
| 179 |
+
## 🙏 謝辞
|
| 180 |
+
|
| 181 |
+
- **Apple**: SHARPモデルの開発と公開
|
| 182 |
+
- **Hugging Face**: ZeroGPU Spacesの提供
|
| 183 |
+
- **Three.js Community**: 3Dレンダリングライブラリ
|
| 184 |
+
|
| 185 |
+
---
|
| 186 |
+
|
| 187 |
+
## 📧 お問い合わせ
|
| 188 |
+
|
| 189 |
+
質問や問題がある場合は、[GitHub Issues](https://github.com/YUGOROU/ml-sharp_ZeroGPU/issues)でお知らせください。
|
| 190 |
+
|
| 191 |
+
---
|
| 192 |
+
|
| 193 |
+
<div align="center">
|
| 194 |
+
|
| 195 |
+
**Made with ❤️ using Apple SHARP and Hugging Face Spaces**
|
| 196 |
+
|
| 197 |
+
</div>
|
app.py
ADDED
|
@@ -0,0 +1,404 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import gradio as gr
|
| 2 |
+
import spaces
|
| 3 |
+
import torch
|
| 4 |
+
from pathlib import Path
|
| 5 |
+
import tempfile
|
| 6 |
+
import os
|
| 7 |
+
import base64
|
| 8 |
+
from typing import Optional
|
| 9 |
+
import json
|
| 10 |
+
|
| 11 |
+
# SHARP モデルのインポート (遅延読み込み)
|
| 12 |
+
try:
|
| 13 |
+
from sharp import Sharp
|
| 14 |
+
SHARP_AVAILABLE = True
|
| 15 |
+
except ImportError:
|
| 16 |
+
SHARP_AVAILABLE = False
|
| 17 |
+
print("Warning: SHARP not available. Using mock mode for development.")
|
| 18 |
+
|
| 19 |
+
# グローバルモデルインスタンス (メモリ効率のため)
|
| 20 |
+
_model = None
|
| 21 |
+
|
| 22 |
+
def get_model():
|
| 23 |
+
"""モデルインスタンスを取得(キャッシング)"""
|
| 24 |
+
global _model
|
| 25 |
+
if _model is None and SHARP_AVAILABLE:
|
| 26 |
+
_model = Sharp()
|
| 27 |
+
return _model
|
| 28 |
+
|
| 29 |
+
@spaces.GPU(duration=60)
|
| 30 |
+
def process_image(image) -> tuple[Optional[str], str, str]:
|
| 31 |
+
"""
|
| 32 |
+
画像から3D Gaussian Splatsを生成
|
| 33 |
+
|
| 34 |
+
Args:
|
| 35 |
+
image: PIL Image or numpy array
|
| 36 |
+
|
| 37 |
+
Returns:
|
| 38 |
+
tuple: (PLYファイルパス, ステータスメッセージ, PLYデータ(base64))
|
| 39 |
+
"""
|
| 40 |
+
if not SHARP_AVAILABLE:
|
| 41 |
+
return None, "❌ SHARPモデルが利用できません", ""
|
| 42 |
+
|
| 43 |
+
if image is None:
|
| 44 |
+
return None, "❌ 画像をアップロードしてください", ""
|
| 45 |
+
|
| 46 |
+
try:
|
| 47 |
+
# 一時ファイルとして保存
|
| 48 |
+
with tempfile.NamedTemporaryFile(suffix=".jpg", delete=False) as tmp_input:
|
| 49 |
+
input_path = Path(tmp_input.name)
|
| 50 |
+
|
| 51 |
+
# PIL Imageとして保存
|
| 52 |
+
if hasattr(image, 'save'):
|
| 53 |
+
image.save(input_path, format='JPEG')
|
| 54 |
+
else:
|
| 55 |
+
from PIL import Image
|
| 56 |
+
Image.fromarray(image).save(input_path, format='JPEG')
|
| 57 |
+
|
| 58 |
+
# モデルで推論
|
| 59 |
+
model = get_model()
|
| 60 |
+
print(f"🔄 Processing image: {input_path}")
|
| 61 |
+
gaussians = model.predict(input_path)
|
| 62 |
+
|
| 63 |
+
# PLYファイルとして保存
|
| 64 |
+
with tempfile.NamedTemporaryFile(suffix=".ply", delete=False) as tmp_output:
|
| 65 |
+
output_path = Path(tmp_output.name)
|
| 66 |
+
|
| 67 |
+
gaussians.save(str(output_path))
|
| 68 |
+
|
| 69 |
+
# PLYファイルをBase64エンコード (Three.jsで使用)
|
| 70 |
+
with open(output_path, 'rb') as f:
|
| 71 |
+
ply_data = f.read()
|
| 72 |
+
ply_base64 = base64.b64encode(ply_data).decode('utf-8')
|
| 73 |
+
|
| 74 |
+
# 統計情報を取得
|
| 75 |
+
file_size = output_path.stat().st_size / (1024 * 1024) # MB
|
| 76 |
+
|
| 77 |
+
# 入力ファイルを削除
|
| 78 |
+
if input_path.exists():
|
| 79 |
+
input_path.unlink()
|
| 80 |
+
|
| 81 |
+
status_msg = f"✅ 生成完了!\n📦 ファイルサイズ: {file_size:.2f} MB"
|
| 82 |
+
|
| 83 |
+
return str(output_path), status_msg, ply_base64
|
| 84 |
+
|
| 85 |
+
except Exception as e:
|
| 86 |
+
import traceback
|
| 87 |
+
error_msg = f"❌ エラーが発生しました:\n{str(e)}\n\n{traceback.format_exc()}"
|
| 88 |
+
print(error_msg)
|
| 89 |
+
return None, error_msg, ""
|
| 90 |
+
|
| 91 |
+
# Three.js ビューアのHTMLテンプレート
|
| 92 |
+
def create_viewer_html(ply_base64: str) -> str:
|
| 93 |
+
"""Three.js + GaussianSplats3D ビューアのHTMLを生成"""
|
| 94 |
+
|
| 95 |
+
if not ply_base64:
|
| 96 |
+
return """
|
| 97 |
+
<div style="width: 100%; height: 600px; display: flex; align-items: center; justify-content: center; background: #1a1a1a; color: white; border-radius: 8px;">
|
| 98 |
+
<div style="text-align: center;">
|
| 99 |
+
<h2>🎨 3D Gaussian Splats ビューア</h2>
|
| 100 |
+
<p>左側で画像を処理すると、ここに3Dプレビューが表示されます</p>
|
| 101 |
+
</div>
|
| 102 |
+
</div>
|
| 103 |
+
"""
|
| 104 |
+
|
| 105 |
+
html = f"""
|
| 106 |
+
<!DOCTYPE html>
|
| 107 |
+
<html lang="ja">
|
| 108 |
+
<head>
|
| 109 |
+
<meta charset="UTF-8">
|
| 110 |
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
| 111 |
+
<title>3D Gaussian Splats Viewer</title>
|
| 112 |
+
<style>
|
| 113 |
+
body {{
|
| 114 |
+
margin: 0;
|
| 115 |
+
padding: 0;
|
| 116 |
+
overflow: hidden;
|
| 117 |
+
background: #000;
|
| 118 |
+
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
| 119 |
+
}}
|
| 120 |
+
#container {{
|
| 121 |
+
width: 100%;
|
| 122 |
+
height: 600px;
|
| 123 |
+
position: relative;
|
| 124 |
+
}}
|
| 125 |
+
#loading {{
|
| 126 |
+
position: absolute;
|
| 127 |
+
top: 50%;
|
| 128 |
+
left: 50%;
|
| 129 |
+
transform: translate(-50%, -50%);
|
| 130 |
+
color: white;
|
| 131 |
+
font-size: 18px;
|
| 132 |
+
z-index: 1000;
|
| 133 |
+
}}
|
| 134 |
+
#controls {{
|
| 135 |
+
position: absolute;
|
| 136 |
+
top: 10px;
|
| 137 |
+
left: 10px;
|
| 138 |
+
background: rgba(0, 0, 0, 0.7);
|
| 139 |
+
color: white;
|
| 140 |
+
padding: 10px;
|
| 141 |
+
border-radius: 5px;
|
| 142 |
+
font-size: 12px;
|
| 143 |
+
z-index: 1000;
|
| 144 |
+
}}
|
| 145 |
+
</style>
|
| 146 |
+
</head>
|
| 147 |
+
<body>
|
| 148 |
+
<div id="container">
|
| 149 |
+
<div id="loading">🔄 3Dモデルを読み込み中...</div>
|
| 150 |
+
<div id="controls">
|
| 151 |
+
<div>🖱️ ドラッグ: 回転</div>
|
| 152 |
+
<div>🔍 スクロール: ズーム</div>
|
| 153 |
+
<div>⌨️ 右クリック: パン</div>
|
| 154 |
+
</div>
|
| 155 |
+
</div>
|
| 156 |
+
|
| 157 |
+
<script type="importmap">
|
| 158 |
+
{{
|
| 159 |
+
"imports": {{
|
| 160 |
+
"three": "https://cdn.jsdelivr.net/npm/three@0.168.0/build/three.module.js",
|
| 161 |
+
"three/addons/": "https://cdn.jsdelivr.net/npm/three@0.168.0/examples/jsm/"
|
| 162 |
+
}}
|
| 163 |
+
}}
|
| 164 |
+
</script>
|
| 165 |
+
|
| 166 |
+
<script type="module">
|
| 167 |
+
import * as THREE from 'three';
|
| 168 |
+
import {{ OrbitControls }} from 'three/addons/controls/OrbitControls.js';
|
| 169 |
+
|
| 170 |
+
// シーンの初期化
|
| 171 |
+
const container = document.getElementById('container');
|
| 172 |
+
const loading = document.getElementById('loading');
|
| 173 |
+
|
| 174 |
+
const scene = new THREE.Scene();
|
| 175 |
+
scene.background = new THREE.Color(0x1a1a1a);
|
| 176 |
+
|
| 177 |
+
const camera = new THREE.PerspectiveCamera(
|
| 178 |
+
75,
|
| 179 |
+
container.clientWidth / container.clientHeight,
|
| 180 |
+
0.1,
|
| 181 |
+
1000
|
| 182 |
+
);
|
| 183 |
+
camera.position.set(0, 0, 5);
|
| 184 |
+
|
| 185 |
+
const renderer = new THREE.WebGLRenderer({{ antialias: true }});
|
| 186 |
+
renderer.setSize(container.clientWidth, container.clientHeight);
|
| 187 |
+
renderer.setPixelRatio(window.devicePixelRatio);
|
| 188 |
+
container.appendChild(renderer.domElement);
|
| 189 |
+
|
| 190 |
+
// OrbitControls
|
| 191 |
+
const controls = new OrbitControls(camera, renderer.domElement);
|
| 192 |
+
controls.enableDamping = true;
|
| 193 |
+
controls.dampingFactor = 0.05;
|
| 194 |
+
|
| 195 |
+
// ライト
|
| 196 |
+
const ambientLight = new THREE.AmbientLight(0xffffff, 0.5);
|
| 197 |
+
scene.add(ambientLight);
|
| 198 |
+
|
| 199 |
+
const directionalLight = new THREE.DirectionalLight(0xffffff, 1);
|
| 200 |
+
directionalLight.position.set(5, 10, 7.5);
|
| 201 |
+
scene.add(directionalLight);
|
| 202 |
+
|
| 203 |
+
// グリッドヘルパー
|
| 204 |
+
const gridHelper = new THREE.GridHelper(10, 10);
|
| 205 |
+
scene.add(gridHelper);
|
| 206 |
+
|
| 207 |
+
// PLYローダー
|
| 208 |
+
async function loadPLY() {{
|
| 209 |
+
try {{
|
| 210 |
+
// Base64からArrayBufferに変換
|
| 211 |
+
const plyBase64 = '{ply_base64}';
|
| 212 |
+
const binaryString = atob(plyBase64);
|
| 213 |
+
const bytes = new Uint8Array(binaryString.length);
|
| 214 |
+
for (let i = 0; i < binaryString.length; i++) {{
|
| 215 |
+
bytes[i] = binaryString.charCodeAt(i);
|
| 216 |
+
}}
|
| 217 |
+
|
| 218 |
+
// PLYLoaderを動的にインポート
|
| 219 |
+
const {{ PLYLoader }} = await import('three/addons/loaders/PLYLoader.js');
|
| 220 |
+
const loader = new PLYLoader();
|
| 221 |
+
|
| 222 |
+
// ArrayBufferをBlob経由でロード
|
| 223 |
+
const blob = new Blob([bytes], {{ type: 'application/octet-stream' }});
|
| 224 |
+
const url = URL.createObjectURL(blob);
|
| 225 |
+
|
| 226 |
+
loader.load(
|
| 227 |
+
url,
|
| 228 |
+
function (geometry) {{
|
| 229 |
+
loading.style.display = 'none';
|
| 230 |
+
|
| 231 |
+
// ポイントクラウドとしてレンダリング
|
| 232 |
+
geometry.computeVertexNormals();
|
| 233 |
+
|
| 234 |
+
// カラー情報があるか確認
|
| 235 |
+
const hasColors = geometry.attributes.color !== undefined;
|
| 236 |
+
|
| 237 |
+
const material = new THREE.PointsMaterial({{
|
| 238 |
+
size: 0.01,
|
| 239 |
+
vertexColors: hasColors,
|
| 240 |
+
color: hasColors ? undefined : 0x00ff00,
|
| 241 |
+
sizeAttenuation: true
|
| 242 |
+
}});
|
| 243 |
+
|
| 244 |
+
const points = new THREE.Points(geometry, material);
|
| 245 |
+
scene.add(points);
|
| 246 |
+
|
| 247 |
+
// カメラ位置を調整
|
| 248 |
+
geometry.computeBoundingBox();
|
| 249 |
+
const bbox = geometry.boundingBox;
|
| 250 |
+
const center = new THREE.Vector3();
|
| 251 |
+
bbox.getCenter(center);
|
| 252 |
+
|
| 253 |
+
const size = new THREE.Vector3();
|
| 254 |
+
bbox.getSize(size);
|
| 255 |
+
const maxDim = Math.max(size.x, size.y, size.z);
|
| 256 |
+
const fov = camera.fov * (Math.PI / 180);
|
| 257 |
+
let cameraZ = Math.abs(maxDim / Math.tan(fov / 2));
|
| 258 |
+
cameraZ *= 1.5;
|
| 259 |
+
|
| 260 |
+
camera.position.set(center.x, center.y, center.z + cameraZ);
|
| 261 |
+
camera.lookAt(center);
|
| 262 |
+
controls.target.copy(center);
|
| 263 |
+
controls.update();
|
| 264 |
+
|
| 265 |
+
URL.revokeObjectURL(url);
|
| 266 |
+
|
| 267 |
+
console.log('✅ PLYファイルの読み込み完了');
|
| 268 |
+
}},
|
| 269 |
+
function (xhr) {{
|
| 270 |
+
const percent = (xhr.loaded / xhr.total * 100).toFixed(0);
|
| 271 |
+
loading.textContent = `🔄 読み込み中... ${{percent}}%`;
|
| 272 |
+
}},
|
| 273 |
+
function (error) {{
|
| 274 |
+
console.error('❌ PLY読み込みエラー:', error);
|
| 275 |
+
loading.textContent = '❌ 読み込みエラー';
|
| 276 |
+
loading.style.color = 'red';
|
| 277 |
+
}}
|
| 278 |
+
);
|
| 279 |
+
}} catch (error) {{
|
| 280 |
+
console.error('❌ エラー:', error);
|
| 281 |
+
loading.textContent = '❌ エラーが発生しました';
|
| 282 |
+
loading.style.color = 'red';
|
| 283 |
+
}}
|
| 284 |
+
}}
|
| 285 |
+
|
| 286 |
+
// アニメーションループ
|
| 287 |
+
function animate() {{
|
| 288 |
+
requestAnimationFrame(animate);
|
| 289 |
+
controls.update();
|
| 290 |
+
renderer.render(scene, camera);
|
| 291 |
+
}}
|
| 292 |
+
|
| 293 |
+
// リサイズ対応
|
| 294 |
+
window.addEventListener('resize', () => {{
|
| 295 |
+
camera.aspect = container.clientWidth / container.clientHeight;
|
| 296 |
+
camera.updateProjectionMatrix();
|
| 297 |
+
renderer.setSize(container.clientWidth, container.clientHeight);
|
| 298 |
+
}});
|
| 299 |
+
|
| 300 |
+
// PLYを読み込んで開始
|
| 301 |
+
loadPLY();
|
| 302 |
+
animate();
|
| 303 |
+
</script>
|
| 304 |
+
</body>
|
| 305 |
+
</html>
|
| 306 |
+
"""
|
| 307 |
+
return html
|
| 308 |
+
|
| 309 |
+
def update_viewer(ply_base64: str) -> str:
|
| 310 |
+
"""ビューアを更新"""
|
| 311 |
+
return create_viewer_html(ply_base64)
|
| 312 |
+
|
| 313 |
+
# Gradio UI
|
| 314 |
+
with gr.Blocks(
|
| 315 |
+
theme=gr.themes.Soft(primary_hue="blue", secondary_hue="purple"),
|
| 316 |
+
title="SHARP: 3D Gaussian Splats Generator"
|
| 317 |
+
) as demo:
|
| 318 |
+
gr.Markdown("""
|
| 319 |
+
# 🎨 SHARP: 単一画像から3D Gaussian Splatsを生成
|
| 320 |
+
|
| 321 |
+
Appleの最新技術「SHARP」を使用して、1枚の画像から高品質な3D Gaussian Splatsを生成します。
|
| 322 |
+
生成された3DモデルはThree.jsで右側にリアルタイムプレビューされます。
|
| 323 |
+
|
| 324 |
+
### 使い方
|
| 325 |
+
1. 左側のエリアに画像をアップロード
|
| 326 |
+
2. 「生成開始」ボタンをクリック
|
| 327 |
+
3. 右側で3Dモデルをインタラクティブに確認
|
| 328 |
+
4. PLYファイルをダウンロード可能
|
| 329 |
+
|
| 330 |
+
**ZeroGPU (Nvidia H200)** で高速に処理されます 🚀
|
| 331 |
+
""")
|
| 332 |
+
|
| 333 |
+
with gr.Row():
|
| 334 |
+
with gr.Column(scale=1):
|
| 335 |
+
gr.Markdown("### 📸 入力画像")
|
| 336 |
+
input_image = gr.Image(
|
| 337 |
+
label="画像をアップロード",
|
| 338 |
+
type="pil",
|
| 339 |
+
sources=["upload", "clipboard"],
|
| 340 |
+
height=400
|
| 341 |
+
)
|
| 342 |
+
|
| 343 |
+
generate_btn = gr.Button(
|
| 344 |
+
"🚀 生成開始",
|
| 345 |
+
variant="primary",
|
| 346 |
+
size="lg"
|
| 347 |
+
)
|
| 348 |
+
|
| 349 |
+
status_box = gr.Textbox(
|
| 350 |
+
label="ステータス",
|
| 351 |
+
lines=3,
|
| 352 |
+
interactive=False
|
| 353 |
+
)
|
| 354 |
+
|
| 355 |
+
output_file = gr.File(
|
| 356 |
+
label="📦 PLYファイルをダウンロード",
|
| 357 |
+
interactive=False
|
| 358 |
+
)
|
| 359 |
+
|
| 360 |
+
with gr.Column(scale=1):
|
| 361 |
+
gr.Markdown("### 🎬 3Dプレビュー (Three.js)")
|
| 362 |
+
viewer_html = gr.HTML(
|
| 363 |
+
create_viewer_html(""),
|
| 364 |
+
label="3D Viewer"
|
| 365 |
+
)
|
| 366 |
+
|
| 367 |
+
# 非表示のステート (PLY Base64データ)
|
| 368 |
+
ply_data_state = gr.State("")
|
| 369 |
+
|
| 370 |
+
# イベントハンドラ
|
| 371 |
+
def on_generate(image):
|
| 372 |
+
ply_path, status, ply_base64 = process_image(image)
|
| 373 |
+
viewer = create_viewer_html(ply_base64)
|
| 374 |
+
return ply_path, status, ply_base64, viewer
|
| 375 |
+
|
| 376 |
+
generate_btn.click(
|
| 377 |
+
fn=on_generate,
|
| 378 |
+
inputs=[input_image],
|
| 379 |
+
outputs=[output_file, status_box, ply_data_state, viewer_html]
|
| 380 |
+
)
|
| 381 |
+
|
| 382 |
+
gr.Markdown("""
|
| 383 |
+
---
|
| 384 |
+
### ℹ️ 技術情報
|
| 385 |
+
|
| 386 |
+
- **モデル**: Apple SHARP (Sharp Monocular View Synthesis)
|
| 387 |
+
- **出力形式**: PLY (Polygon File Format)
|
| 388 |
+
- **レンダリング**: Three.js + PLYLoader
|
| 389 |
+
- **GPU**: ZeroGPU (Nvidia H200, 動的割り当て)
|
| 390 |
+
- **処理時間**: 通常1秒以下
|
| 391 |
+
|
| 392 |
+
### 📚 リソース
|
| 393 |
+
- [SHARP GitHub](https://github.com/apple/ml-sharp)
|
| 394 |
+
- [論文 (arXiv)](https://arxiv.org/abs/2512.10685)
|
| 395 |
+
- [Hugging Face Model](https://huggingface.co/apple/Sharp)
|
| 396 |
+
|
| 397 |
+
### ⚠️ 注意事項
|
| 398 |
+
- 処理にはGPUを使用するため、待機時間が発生する場合があります
|
| 399 |
+
- ZeroGPUは60秒のタイムアウトがあります
|
| 400 |
+
- 大きな画像は自動的にリサイズされます
|
| 401 |
+
""")
|
| 402 |
+
|
| 403 |
+
if __name__ == "__main__":
|
| 404 |
+
demo.launch()
|
requirements.txt
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Core dependencies for SHARP
|
| 2 |
+
torch==2.5.1
|
| 3 |
+
torchvision==0.20.1
|
| 4 |
+
timm==1.0.12
|
| 5 |
+
gsplat==1.5.3
|
| 6 |
+
scipy==1.14.1
|
| 7 |
+
numpy==2.1.3
|
| 8 |
+
pillow==11.0.0
|
| 9 |
+
pillow-heif==0.20.0
|
| 10 |
+
imageio==2.37.0
|
| 11 |
+
imageio-ffmpeg==0.6.0
|
| 12 |
+
click==8.1.8
|
| 13 |
+
plyfile==1.1.2
|
| 14 |
+
huggingface-hub==0.27.0
|
| 15 |
+
|
| 16 |
+
# Gradio for UI
|
| 17 |
+
gradio==5.9.1
|
| 18 |
+
|
| 19 |
+
# Spaces GPU support
|
| 20 |
+
spaces
|
| 21 |
+
|
| 22 |
+
# SHARP package from GitHub
|
| 23 |
+
git+https://github.com/apple/ml-sharp.git
|