Merge pull request #173 from akx/path-types
Fix up some path-related types
This commit is contained in:
commit
39f89026f0
@ -1,4 +1,5 @@
|
|||||||
import logging
|
import logging
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
import mlx.core as mx
|
import mlx.core as mx
|
||||||
import numpy as np
|
import numpy as np
|
||||||
@ -48,7 +49,7 @@ class RuntimeConfig:
|
|||||||
return self.model_config.num_train_steps
|
return self.model_config.num_train_steps
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def image_path(self) -> str:
|
def image_path(self) -> Path | None:
|
||||||
return self.config.image_path
|
return self.config.image_path
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@ -56,15 +57,15 @@ class RuntimeConfig:
|
|||||||
return self.config.image_strength
|
return self.config.image_strength
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def depth_image_path(self) -> str | None:
|
def depth_image_path(self) -> Path | None:
|
||||||
return self.config.depth_image_path
|
return self.config.depth_image_path
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def redux_image_paths(self) -> str | None:
|
def redux_image_paths(self) -> list[Path] | None:
|
||||||
return self.config.redux_image_paths
|
return self.config.redux_image_paths
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def masked_image_path(self) -> str | None:
|
def masked_image_path(self) -> Path | None:
|
||||||
return self.config.masked_image_path
|
return self.config.masked_image_path
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
|||||||
@ -6,7 +6,9 @@ from zipfile import ZipFile
|
|||||||
|
|
||||||
class ZipUtil:
|
class ZipUtil:
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def unzip(zip_path: str | Path, filename: str, loader: callable):
|
def unzip(zip_path: str | Path | None, filename: str, loader: callable):
|
||||||
|
if not zip_path: # Would be nicer to do this in typing, but that's more effort on the callers' side
|
||||||
|
raise ValueError("zip_path cannot be None")
|
||||||
zip_path = Path(zip_path)
|
zip_path = Path(zip_path)
|
||||||
if not zip_path.exists():
|
if not zip_path.exists():
|
||||||
raise FileNotFoundError(f"ZIP file not found at: {zip_path}")
|
raise FileNotFoundError(f"ZIP file not found at: {zip_path}")
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
import mlx.core as mx
|
import mlx.core as mx
|
||||||
import PIL.Image
|
import PIL.Image
|
||||||
@ -19,8 +20,8 @@ class DepthUtil:
|
|||||||
vae: VAE,
|
vae: VAE,
|
||||||
depth_pro: DepthPro,
|
depth_pro: DepthPro,
|
||||||
config: RuntimeConfig,
|
config: RuntimeConfig,
|
||||||
image_path: str | None = None,
|
image_path: str | Path | None = None,
|
||||||
depth_image_path: str | None = None,
|
depth_image_path: str | Path | None = None,
|
||||||
) -> (mx.array, PIL.Image.Image):
|
) -> (mx.array, PIL.Image.Image):
|
||||||
# 1. Create the depth map or use existing one
|
# 1. Create the depth map or use existing one
|
||||||
depth_image_path, depth_image = DepthUtil.get_or_create_depth_map(
|
depth_image_path, depth_image = DepthUtil.get_or_create_depth_map(
|
||||||
@ -44,9 +45,9 @@ class DepthUtil:
|
|||||||
@staticmethod
|
@staticmethod
|
||||||
def get_or_create_depth_map(
|
def get_or_create_depth_map(
|
||||||
depth_pro: DepthPro,
|
depth_pro: DepthPro,
|
||||||
image_path: str | None = None,
|
image_path: str | Path | None = None,
|
||||||
depth_map_path: str | None = None,
|
depth_map_path: str | Path | None = None,
|
||||||
) -> tuple[str, PIL.Image.Image | None]:
|
) -> tuple[str | Path, PIL.Image.Image | None]:
|
||||||
# 1. If a depth map path is provided, use it directly
|
# 1. If a depth map path is provided, use it directly
|
||||||
if depth_map_path:
|
if depth_map_path:
|
||||||
if not os.path.exists(depth_map_path):
|
if not os.path.exists(depth_map_path):
|
||||||
|
|||||||
@ -1,3 +1,5 @@
|
|||||||
|
from pathlib import Path
|
||||||
|
|
||||||
import mlx.core as mx
|
import mlx.core as mx
|
||||||
|
|
||||||
from mflux.config.runtime_config import RuntimeConfig
|
from mflux.config.runtime_config import RuntimeConfig
|
||||||
@ -12,8 +14,8 @@ class MaskUtil:
|
|||||||
vae: VAE,
|
vae: VAE,
|
||||||
config: RuntimeConfig,
|
config: RuntimeConfig,
|
||||||
latents: mx.array,
|
latents: mx.array,
|
||||||
img_path: str,
|
img_path: str | Path,
|
||||||
mask_path: str | None,
|
mask_path: str | Path | None,
|
||||||
) -> mx.array:
|
) -> mx.array:
|
||||||
if not img_path or not mask_path:
|
if not img_path or not mask_path:
|
||||||
# Return empty latents if no image or mask is provided
|
# Return empty latents if no image or mask is provided
|
||||||
|
|||||||
@ -1,3 +1,5 @@
|
|||||||
|
from pathlib import Path
|
||||||
|
|
||||||
import mlx.core as mx
|
import mlx.core as mx
|
||||||
from mlx import nn
|
from mlx import nn
|
||||||
from tqdm import tqdm
|
from tqdm import tqdm
|
||||||
@ -158,7 +160,7 @@ class Flux1Redux(nn.Module):
|
|||||||
clip_tokenizer: TokenizerCLIP,
|
clip_tokenizer: TokenizerCLIP,
|
||||||
t5_text_encoder: T5Encoder,
|
t5_text_encoder: T5Encoder,
|
||||||
clip_text_encoder: CLIPEncoder,
|
clip_text_encoder: CLIPEncoder,
|
||||||
image_paths: list[str],
|
image_paths: list[str] | list[Path],
|
||||||
image_encoder: SiglipVisionTransformer,
|
image_encoder: SiglipVisionTransformer,
|
||||||
image_embedder: ReduxEncoder,
|
image_embedder: ReduxEncoder,
|
||||||
) -> (mx.array, mx.array):
|
) -> (mx.array, mx.array):
|
||||||
|
|||||||
@ -1,3 +1,5 @@
|
|||||||
|
from pathlib import Path
|
||||||
|
|
||||||
import mlx.core as mx
|
import mlx.core as mx
|
||||||
|
|
||||||
from mflux import ImageUtil
|
from mflux import ImageUtil
|
||||||
@ -8,7 +10,7 @@ from mflux.models.siglip_vision_transformer.siglip_vision_transformer import Sig
|
|||||||
class ReduxUtil:
|
class ReduxUtil:
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def embed_images(
|
def embed_images(
|
||||||
image_paths: list[str],
|
image_paths: list[str] | list[Path],
|
||||||
image_encoder: SiglipVisionTransformer,
|
image_encoder: SiglipVisionTransformer,
|
||||||
image_embedder: ReduxEncoder,
|
image_embedder: ReduxEncoder,
|
||||||
) -> list[mx.array]: # fmt:off
|
) -> list[mx.array]: # fmt:off
|
||||||
@ -24,7 +26,7 @@ class ReduxUtil:
|
|||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _embed_single_image(
|
def _embed_single_image(
|
||||||
image_path: str,
|
image_path: str | Path,
|
||||||
image_encoder: SiglipVisionTransformer,
|
image_encoder: SiglipVisionTransformer,
|
||||||
image_embedder: ReduxEncoder,
|
image_embedder: ReduxEncoder,
|
||||||
) -> mx.array: # fmt:off
|
) -> mx.array: # fmt:off
|
||||||
|
|||||||
@ -1,3 +1,5 @@
|
|||||||
|
from pathlib import Path
|
||||||
|
|
||||||
import mlx.core as mx
|
import mlx.core as mx
|
||||||
|
|
||||||
from mflux.models.vae.vae import VAE
|
from mflux.models.vae.vae import VAE
|
||||||
@ -11,7 +13,7 @@ class Img2Img:
|
|||||||
vae: VAE,
|
vae: VAE,
|
||||||
sigmas: mx.array,
|
sigmas: mx.array,
|
||||||
init_time_step: int,
|
init_time_step: int,
|
||||||
image_path: int,
|
image_path: str | Path | None,
|
||||||
):
|
):
|
||||||
self.vae = vae
|
self.vae = vae
|
||||||
self.sigmas = sigmas
|
self.sigmas = sigmas
|
||||||
@ -39,9 +41,7 @@ class LatentCreator:
|
|||||||
img2img: Img2Img,
|
img2img: Img2Img,
|
||||||
) -> mx.array:
|
) -> mx.array:
|
||||||
# 0. Determine type of image generation
|
# 0. Determine type of image generation
|
||||||
is_text2img = img2img.image_path is None
|
if img2img.image_path is None:
|
||||||
|
|
||||||
if is_text2img:
|
|
||||||
# 1. Create the pure noise
|
# 1. Create the pure noise
|
||||||
return LatentCreator.create(
|
return LatentCreator.create(
|
||||||
seed=seed,
|
seed=seed,
|
||||||
@ -71,7 +71,7 @@ class LatentCreator:
|
|||||||
)
|
)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def encode_image(vae: VAE, image_path: str, height: int, width: int):
|
def encode_image(vae: VAE, image_path: str | Path, height: int, width: int):
|
||||||
scaled_user_image = ImageUtil.scale_to_dimensions(
|
scaled_user_image = ImageUtil.scale_to_dimensions(
|
||||||
image=ImageUtil.load_image(image_path).convert("RGB"),
|
image=ImageUtil.load_image(image_path).convert("RGB"),
|
||||||
target_width=width,
|
target_width=width,
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
import importlib
|
import importlib
|
||||||
import pathlib
|
|
||||||
import typing as t
|
import typing as t
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
import mlx.core as mx
|
import mlx.core as mx
|
||||||
import PIL.Image
|
import PIL.Image
|
||||||
@ -23,13 +23,13 @@ class GeneratedImage:
|
|||||||
generation_time: float,
|
generation_time: float,
|
||||||
lora_paths: list[str],
|
lora_paths: list[str],
|
||||||
lora_scales: list[float],
|
lora_scales: list[float],
|
||||||
controlnet_image_path: str | pathlib.Path | None = None,
|
controlnet_image_path: str | Path | None = None,
|
||||||
controlnet_strength: float | None = None,
|
controlnet_strength: float | None = None,
|
||||||
image_path: str | pathlib.Path | None = None,
|
image_path: str | Path | None = None,
|
||||||
image_strength: float | None = None,
|
image_strength: float | None = None,
|
||||||
masked_image_path: str | pathlib.Path | None = None,
|
masked_image_path: str | Path | None = None,
|
||||||
depth_image_path: str | pathlib.Path | None = None,
|
depth_image_path: str | Path | None = None,
|
||||||
redux_image_paths: list[str] | list[pathlib.Path] | None = None,
|
redux_image_paths: list[str] | list[Path] | None = None,
|
||||||
):
|
):
|
||||||
self.image = image
|
self.image = image
|
||||||
self.model_config = model_config
|
self.model_config = model_config
|
||||||
@ -78,7 +78,7 @@ class GeneratedImage:
|
|||||||
|
|
||||||
def save(
|
def save(
|
||||||
self,
|
self,
|
||||||
path: t.Union[str, pathlib.Path],
|
path: t.Union[str, Path],
|
||||||
export_json_metadata: bool = False,
|
export_json_metadata: bool = False,
|
||||||
overwrite: bool = False,
|
overwrite: bool = False,
|
||||||
) -> None:
|
) -> None:
|
||||||
@ -129,7 +129,7 @@ class GeneratedImage:
|
|||||||
@staticmethod
|
@staticmethod
|
||||||
def _get_version_from_toml() -> str | None:
|
def _get_version_from_toml() -> str | None:
|
||||||
# Search for pyproject.toml by traversing up from the current working directory
|
# Search for pyproject.toml by traversing up from the current working directory
|
||||||
current_dir = pathlib.Path(__file__).resolve().parent
|
current_dir = Path(__file__).resolve().parent
|
||||||
for parent in current_dir.parents:
|
for parent in current_dir.parents:
|
||||||
pyproject_path = parent / "pyproject.toml"
|
pyproject_path = parent / "pyproject.toml"
|
||||||
if pyproject_path.exists():
|
if pyproject_path.exists():
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
import json
|
import json
|
||||||
import logging
|
import logging
|
||||||
import pathlib
|
|
||||||
import typing as t
|
import typing as t
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
import mlx.core as mx
|
import mlx.core as mx
|
||||||
import numpy as np
|
import numpy as np
|
||||||
@ -27,12 +27,12 @@ class ImageUtil:
|
|||||||
generation_time: float,
|
generation_time: float,
|
||||||
lora_paths: list[str],
|
lora_paths: list[str],
|
||||||
lora_scales: list[float],
|
lora_scales: list[float],
|
||||||
controlnet_image_path: str | None = None,
|
controlnet_image_path: str | Path | None = None,
|
||||||
image_path: str | None = None,
|
image_path: str | Path | None = None,
|
||||||
redux_image_paths: list[str] | None = None,
|
redux_image_paths: list[str] | list[Path] | None = None,
|
||||||
image_strength: float | None = None,
|
image_strength: float | None = None,
|
||||||
masked_image_path: str | None = None,
|
masked_image_path: str | Path | None = None,
|
||||||
depth_image_path: str | None = None,
|
depth_image_path: str | Path | None = None,
|
||||||
) -> GeneratedImage:
|
) -> GeneratedImage:
|
||||||
normalized = ImageUtil._denormalize(decoded_latents)
|
normalized = ImageUtil._denormalize(decoded_latents)
|
||||||
normalized_numpy = ImageUtil._to_numpy(normalized)
|
normalized_numpy = ImageUtil._to_numpy(normalized)
|
||||||
@ -113,7 +113,7 @@ class ImageUtil:
|
|||||||
return array
|
return array
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def load_image(path: str | pathlib.Path) -> PIL.Image.Image:
|
def load_image(path: str | Path) -> PIL.Image.Image:
|
||||||
return PIL.Image.open(path)
|
return PIL.Image.open(path)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
@ -204,12 +204,12 @@ class ImageUtil:
|
|||||||
@staticmethod
|
@staticmethod
|
||||||
def save_image(
|
def save_image(
|
||||||
image: PIL.Image.Image,
|
image: PIL.Image.Image,
|
||||||
path: t.Union[str, pathlib.Path],
|
path: t.Union[str, Path],
|
||||||
metadata: dict | None = None,
|
metadata: dict | None = None,
|
||||||
export_json_metadata: bool = False,
|
export_json_metadata: bool = False,
|
||||||
overwrite: bool = False,
|
overwrite: bool = False,
|
||||||
) -> None:
|
) -> None:
|
||||||
file_path = pathlib.Path(path)
|
file_path = Path(path)
|
||||||
file_path.parent.mkdir(parents=True, exist_ok=True)
|
file_path.parent.mkdir(parents=True, exist_ok=True)
|
||||||
file_name = file_path.stem
|
file_name = file_path.stem
|
||||||
file_extension = file_path.suffix
|
file_extension = file_path.suffix
|
||||||
@ -240,7 +240,7 @@ class ImageUtil:
|
|||||||
log.error(f"Error saving image: {e}")
|
log.error(f"Error saving image: {e}")
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _embed_metadata(metadata: dict, path: str) -> None:
|
def _embed_metadata(metadata: dict, path: str | Path) -> None:
|
||||||
try:
|
try:
|
||||||
# Convert metadata dictionary to a string
|
# Convert metadata dictionary to a string
|
||||||
metadata_str = json.dumps(metadata)
|
metadata_str = json.dumps(metadata)
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import pathlib
|
|
||||||
import sys
|
import sys
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
from mflux.post_processing.image_util import ImageUtil
|
from mflux.post_processing.image_util import ImageUtil
|
||||||
from mflux.ui.box_values import AbsoluteBoxValues, BoxValues
|
from mflux.ui.box_values import AbsoluteBoxValues, BoxValues
|
||||||
@ -8,7 +8,7 @@ from mflux.ui.cli.parsers import CommandLineParser
|
|||||||
|
|
||||||
def main():
|
def main():
|
||||||
parser = CommandLineParser(description="Create expanded canvas and mask for outpainting")
|
parser = CommandLineParser(description="Create expanded canvas and mask for outpainting")
|
||||||
parser.add_argument("image_path", type=pathlib.Path, help="Path to the input image file")
|
parser.add_argument("image_path", type=Path, help="Path to the input image file")
|
||||||
parser.add_image_outpaint_arguments(required=True)
|
parser.add_image_outpaint_arguments(required=True)
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user