From 49a4b36032f86e91726d9090289133629f560e05 Mon Sep 17 00:00:00 2001 From: pq-yang Date: Mon, 16 Mar 2026 06:45:38 +0000 Subject: [PATCH] cleanup --- README.md | 67 +++++++++++++++-------------- matanyone2/utils/inference_utils.py | 15 ++----- pyproject.toml | 60 ++++++++++---------------- 3 files changed, 59 insertions(+), 83 deletions(-) diff --git a/README.md b/README.md index e8ddbb1..48b9ad2 100644 --- a/README.md +++ b/README.md @@ -67,33 +67,31 @@ ## 🔧 Installation -### From PyPI / Source -```bash -# install from repo -pip install git+https://github.com/pq-yang/MatAnyone2.git#egg=matanyone2 - -# or install optional extras -pip install git+https://github.com/pq-yang/MatAnyone2.git#egg=matanyone2[gui] # Gradio demo + PySide6 -pip install git+https://github.com/pq-yang/MatAnyone2.git#egg=matanyone2[dev] # development / evaluation tools -pip install git+https://github.com/pq-yang/MatAnyone2.git#egg=matanyone2[all] # everything -``` - ### Conda -```bash -conda create -n matanyone2 python=3.10 -y -conda activate matanyone2 -pip install git+https://github.com/pq-yang/MatAnyone2.git#egg=matanyone2[all] -``` +1. Clone Repo + ```bash + git clone https://github.com/pq-yang/MatAnyone2 + cd MatAnyone2 + ``` -### uv (recommended) +2. Create Conda Environment and Install Dependencies + ```bash + # create new conda env + conda create -n matanyone2 python=3.10 -y + conda activate matanyone2 + + # install python dependencies + pip install -e . + # [optional] install python dependencies for gradio demo + pip3 install -r hugging_face/requirements.txt + ``` + +### uv +You may also install via [uv](https://docs.astral.sh/uv/): ```bash # create a new project and add matanyone2 uv init my-matting-project && cd my-matting-project uv add matanyone2@git+https://github.com/pq-yang/MatAnyone2.git - -# or with optional extras -uv add matanyone2[gui]@git+https://github.com/pq-yang/MatAnyone2.git -uv add matanyone2[all]@git+https://github.com/pq-yang/MatAnyone2.git ``` ## 🔥 Inference @@ -122,23 +120,29 @@ Run the following command to try it out: ```shell # intput format: video folder -matanyone2 -i inputs/video/test-sample1 -m inputs/mask/test-sample1.png +python inference_matanyone2.py -i inputs/video/test-sample1 -m inputs/mask/test-sample1.png # intput format: mp4 -matanyone2 -i inputs/video/test-sample2.mp4 -m inputs/mask/test-sample2.png - -# or via python -python inference_matanyone2.py -i inputs/video/test-sample1 -m inputs/mask/test-sample1.png +python inference_matanyone2.py -i inputs/video/test-sample2.mp4 -m inputs/mask/test-sample2.png ``` -The results will be saved in the `results` folder, including the foreground output video and the alpha output video. +- The results will be saved in the `results` folder, including the foreground output video and the alpha output video. +- If you want to save the results as per-frame images, you can set `--save-image`. +- If you want to set a limit for the maximum input resolution, you can set `--max-size`, and the video will be downsampled if min(w, h) exceeds. By default, we don't set the limit. -### Python API (recommended 🔥) +### uv +If you install via uv, you may try the following command: +```shell +matanyone2 -i inputs/video/test-sample1 -m inputs/mask/test-sample1.png +``` +- Run `matanyone2 --help` for a full list of options. + +### Python API 🤗 You can load the model directly from Hugging Face using `from_pretrained` and run inference programmatically: ```python from matanyone2 import MatAnyone2, InferenceCore -model = MatAnyone2.from_pretrained("not-lain/matanyone2") +model = MatAnyone2.from_pretrained("PeiqingYang/MatAnyone2") processor = InferenceCore(model, device="cuda:0") processor.process_video( input_path="inputs/video/test-sample2.mp4", @@ -146,9 +150,6 @@ processor.process_video( output_path="results", ) ``` -- If you want to save the results as per-frame images, you can set `--save-image`. -- If you want to set a limit for the maximum input resolution, you can set `--max-size`, and the video will be downsampled if min(w, h) exceeds. By default, we don't set the limit. -- Run `matanyone2 --help` for a full list of options. ## 🎪 Interactive Demo To get rid of the preparation for first-frame segmentation mask, we prepare a gradio demo on [hugging face](https://huggingface.co/spaces/PeiqingYang/MatAnyone2) and could also **launch locally**. Just drop your video/image, assign the target masks with a few clicks, and get the the matting results! @@ -158,7 +159,7 @@ To get rid of the preparation for first-frame segmentation mask, we prepare a gr ```shell cd hugging_face -# install GUI dependencies (if not already installed via pip install -e ".[gui]") +# install GUI dependencies pip3 install -r requirements.txt # FFmpeg required # launch the demo diff --git a/matanyone2/utils/inference_utils.py b/matanyone2/utils/inference_utils.py index a356422..c5bb6a0 100644 --- a/matanyone2/utils/inference_utils.py +++ b/matanyone2/utils/inference_utils.py @@ -4,6 +4,7 @@ import random import numpy as np import torch +import torchvision IMAGE_EXTENSIONS = ('.jpg', '.jpeg', '.png', '.JPG', '.JPEG', '.PNG') VIDEO_EXTENSIONS = ('.mp4', '.mov', '.avi', '.MP4', '.MOV', '.AVI') @@ -11,18 +12,8 @@ VIDEO_EXTENSIONS = ('.mp4', '.mov', '.avi', '.MP4', '.MOV', '.AVI') def read_frame_from_videos(frame_root): if frame_root.endswith(VIDEO_EXTENSIONS): # Video file path video_name = os.path.basename(frame_root)[:-4] - cap = cv2.VideoCapture(frame_root) - fps = cap.get(cv2.CAP_PROP_FPS) - if fps <= 0: - fps = 24 - frames = [] - while True: - ret, frame = cap.read() - if not ret: - break - frames.append(frame[..., [2, 1, 0]]) # BGR to RGB, HWC - cap.release() - frames = torch.Tensor(np.array(frames)).permute(0, 3, 1, 2).contiguous() # TCHW + frames, _, info = torchvision.io.read_video(filename=frame_root, pts_unit='sec', output_format='TCHW') # RGB + fps = info['video_fps'] else: video_name = os.path.basename(frame_root) frames = [] diff --git a/pyproject.toml b/pyproject.toml index 7995afb..cbdaef5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -22,54 +22,35 @@ classifiers = [ "Operating System :: OS Independent", ] dependencies = [ + 'cython', + 'gitpython >= 3.1', + 'thinplate@git+https://github.com/cheind/py-thin-plate-spline', + 'hickle >= 5.0', + 'tensorboard >= 2.11', 'numpy >= 1.21', 'Pillow >= 9.5', 'opencv-python >= 4.8', 'scipy >= 1.7', + 'pycocotools >= 2.0.7', 'tqdm >= 4.66.1', + 'gradio >= 3.34', + 'gdown >= 4.7.1', 'einops >= 0.6', 'hydra-core >= 1.3.2', - 'requests', - 'imageio >= 2.25.0', - 'imageio[ffmpeg]', - 'huggingface_hub >= 0.25.0', - 'safetensors', - 'kornia', + 'PySide6 >= 6.2.0', + 'charset-normalizer >= 3.1.0', + 'netifaces >= 0.11.0', + 'cchardet >= 2.1.7', 'easydict', - 'torch', - 'torchvision', - 'typer >= 0.9.0', - "av>=16.1.0", -] - -[project.optional-dependencies] -dev = [ - 'cython', - 'gitpython >= 3.1', - 'thinplate@git+https://github.com/cheind/py-thin-plate-spline', - 'hickle >= 5.0', - 'tensorboard >= 2.11', - 'pycocotools >= 2.0.7', - 'gdown >= 4.7.1', - 'xlsxwriter', -] -gui = [ - 'gradio >= 6.9.0', - 'PySide6 >= 6.2.0', + 'av >= 0.5.2', + 'requests', 'pyqtdarktheme', -] -all = [ - 'cython', - 'gitpython >= 3.1', - 'thinplate@git+https://github.com/cheind/py-thin-plate-spline', - 'hickle >= 5.0', - 'tensorboard >= 2.11', - 'pycocotools >= 2.0.7', - 'gdown >= 4.7.1', + 'imageio == 2.25.0', + 'imageio[ffmpeg]', + 'huggingface_hub == 0.36.2', + 'safetensors', 'xlsxwriter', - 'gradio >= 6.9.0', - 'PySide6 >= 6.2.0', - 'pyqtdarktheme', + 'kornia', ] [project.scripts] @@ -104,3 +85,6 @@ torchvision = { index = "pytorch-cu128" } [project.urls] "Homepage" = "https://github.com/pq-yang/MatAnyone2" "Bug Tracker" = "https://github.com/pq-yang/MatAnyone2/issues" + +[tool.setuptools] +package-dir = {"" = "."}