Update config/app_config.py
Browse files- config/app_config.py +100 -5
config/app_config.py
CHANGED
|
@@ -46,6 +46,34 @@ class ProcessingConfig:
|
|
| 46 |
matanyone_precision: str = os.getenv('MATANYONE_PRECISION', 'fp32') # fp16, fp32
|
| 47 |
model_device: str = os.getenv('MODEL_DEVICE', 'auto') # auto, cuda, cpu
|
| 48 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 49 |
# Processing settings
|
| 50 |
temporal_consistency: bool = os.getenv('TEMPORAL_CONSISTENCY', 'true').lower() == 'true'
|
| 51 |
edge_refinement: bool = os.getenv('EDGE_REFINEMENT', 'true').lower() == 'true'
|
|
@@ -145,6 +173,22 @@ def _validate_config(self):
|
|
| 145 |
logger.warning(f"Invalid precision: {self.matanyone_precision}. Setting to 'fp32'.")
|
| 146 |
self.matanyone_precision = 'fp32'
|
| 147 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 148 |
# Validate output settings
|
| 149 |
valid_formats = ['mp4', 'avi', 'mov', 'webm', 'mkv']
|
| 150 |
if self.output_format not in valid_formats:
|
|
@@ -183,6 +227,14 @@ def _create_directories(self):
|
|
| 183 |
Path(self.output_dir) / 'two_stage'
|
| 184 |
]
|
| 185 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 186 |
for directory in directories:
|
| 187 |
try:
|
| 188 |
Path(directory).mkdir(parents=True, exist_ok=True)
|
|
@@ -255,6 +307,35 @@ def from_yaml(cls, filepath: str) -> 'ProcessingConfig':
|
|
| 255 |
config_dict = yaml.safe_load(f)
|
| 256 |
return cls(**config_dict)
|
| 257 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 258 |
def get_quality_settings(self) -> Dict[str, Any]:
|
| 259 |
"""Get quality-specific settings based on preset"""
|
| 260 |
quality_maps = {
|
|
@@ -265,7 +346,8 @@ def get_quality_settings(self) -> Dict[str, Any]:
|
|
| 265 |
'temporal_consistency': False,
|
| 266 |
'model_precision': 'fp16',
|
| 267 |
'batch_size': min(self.batch_size * 2, 16),
|
| 268 |
-
'output_quality_params': '-preset ultrafast -crf 28'
|
|
|
|
| 269 |
},
|
| 270 |
'balanced': {
|
| 271 |
'keyframe_interval': self.keyframe_interval,
|
|
@@ -274,7 +356,8 @@ def get_quality_settings(self) -> Dict[str, Any]:
|
|
| 274 |
'temporal_consistency': True,
|
| 275 |
'model_precision': 'fp32',
|
| 276 |
'batch_size': self.batch_size,
|
| 277 |
-
'output_quality_params': '-preset medium -crf 23'
|
|
|
|
| 278 |
},
|
| 279 |
'high': {
|
| 280 |
'keyframe_interval': max(self.keyframe_interval // 2, 1),
|
|
@@ -283,7 +366,8 @@ def get_quality_settings(self) -> Dict[str, Any]:
|
|
| 283 |
'temporal_consistency': True,
|
| 284 |
'model_precision': 'fp32',
|
| 285 |
'batch_size': max(self.batch_size // 2, 1),
|
| 286 |
-
'output_quality_params': '-preset slow -crf 18'
|
|
|
|
| 287 |
},
|
| 288 |
'ultra': {
|
| 289 |
'keyframe_interval': 1,
|
|
@@ -292,7 +376,10 @@ def get_quality_settings(self) -> Dict[str, Any]:
|
|
| 292 |
'temporal_consistency': True,
|
| 293 |
'model_precision': 'fp32',
|
| 294 |
'batch_size': 1,
|
| 295 |
-
'output_quality_params': '-preset veryslow -crf 15'
|
|
|
|
|
|
|
|
|
|
| 296 |
}
|
| 297 |
}
|
| 298 |
|
|
@@ -330,7 +417,8 @@ def is_high_performance_mode(self) -> bool:
|
|
| 330 |
self.quality_preset in ['high', 'ultra'] and
|
| 331 |
self.edge_refinement and
|
| 332 |
self.temporal_consistency and
|
| 333 |
-
self.keyframe_interval <= 3
|
|
|
|
| 334 |
)
|
| 335 |
|
| 336 |
def get_memory_limits(self) -> Dict[str, Any]:
|
|
@@ -368,6 +456,13 @@ def validate_for_production(self) -> List[str]:
|
|
| 368 |
if self.max_concurrent_processes > 4:
|
| 369 |
warnings.append("High concurrent processes may cause instability")
|
| 370 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 371 |
return warnings
|
| 372 |
|
| 373 |
# Singleton instance for application-wide use
|
|
|
|
| 46 |
matanyone_precision: str = os.getenv('MATANYONE_PRECISION', 'fp32') # fp16, fp32
|
| 47 |
model_device: str = os.getenv('MODEL_DEVICE', 'auto') # auto, cuda, cpu
|
| 48 |
|
| 49 |
+
# MatAnyone specific settings
|
| 50 |
+
matanyone_enabled: bool = os.getenv('MATANYONE_ENABLED', 'false').lower() == 'true'
|
| 51 |
+
matanyone_model_path: str = os.getenv('MATANYONE_MODEL_PATH', 'models/matanyone/checkpoint.pth')
|
| 52 |
+
matanyone_threshold: float = float(os.getenv('MATANYONE_THRESHOLD', '0.5'))
|
| 53 |
+
matanyone_hair_refinement: bool = os.getenv('MATANYONE_HAIR_REFINEMENT', 'true').lower() == 'true'
|
| 54 |
+
matanyone_edge_enhancement: bool = os.getenv('MATANYONE_EDGE_ENHANCEMENT', 'true').lower() == 'true'
|
| 55 |
+
matanyone_detail_refinement: bool = os.getenv('MATANYONE_DETAIL_REFINEMENT', 'true').lower() == 'true'
|
| 56 |
+
matanyone_morphology_ops: bool = os.getenv('MATANYONE_MORPHOLOGY_OPS', 'true').lower() == 'true'
|
| 57 |
+
matanyone_morphology_kernel_size: int = int(os.getenv('MATANYONE_MORPHOLOGY_KERNEL_SIZE', '5'))
|
| 58 |
+
|
| 59 |
+
# Component paths for separate mask files
|
| 60 |
+
hair_masks_dir: str = os.getenv('HAIR_MASKS_DIR', 'assets/hair_masks')
|
| 61 |
+
edge_masks_dir: str = os.getenv('EDGE_MASKS_DIR', 'assets/edge_masks')
|
| 62 |
+
detail_masks_dir: str = os.getenv('DETAIL_MASKS_DIR', 'assets/detail_masks')
|
| 63 |
+
use_component_masks: bool = os.getenv('USE_COMPONENT_MASKS', 'false').lower() == 'true'
|
| 64 |
+
|
| 65 |
+
# MatAnyone component weights
|
| 66 |
+
matanyone_weight_base: float = float(os.getenv('MATANYONE_WEIGHT_BASE', '1.0'))
|
| 67 |
+
matanyone_weight_hair: float = float(os.getenv('MATANYONE_WEIGHT_HAIR', '1.2'))
|
| 68 |
+
matanyone_weight_edge: float = float(os.getenv('MATANYONE_WEIGHT_EDGE', '1.5'))
|
| 69 |
+
matanyone_weight_detail: float = float(os.getenv('MATANYONE_WEIGHT_DETAIL', '1.1'))
|
| 70 |
+
|
| 71 |
+
# MatAnyone processing modes
|
| 72 |
+
matanyone_processing_mode: str = os.getenv('MATANYONE_PROCESSING_MODE', 'refine') # refine, replace, blend
|
| 73 |
+
matanyone_blend_alpha: float = float(os.getenv('MATANYONE_BLEND_ALPHA', '0.7'))
|
| 74 |
+
matanyone_trimap_enabled: bool = os.getenv('MATANYONE_TRIMAP_ENABLED', 'false').lower() == 'true'
|
| 75 |
+
matanyone_trimap_dilation: int = int(os.getenv('MATANYONE_TRIMAP_DILATION', '10'))
|
| 76 |
+
|
| 77 |
# Processing settings
|
| 78 |
temporal_consistency: bool = os.getenv('TEMPORAL_CONSISTENCY', 'true').lower() == 'true'
|
| 79 |
edge_refinement: bool = os.getenv('EDGE_REFINEMENT', 'true').lower() == 'true'
|
|
|
|
| 173 |
logger.warning(f"Invalid precision: {self.matanyone_precision}. Setting to 'fp32'.")
|
| 174 |
self.matanyone_precision = 'fp32'
|
| 175 |
|
| 176 |
+
# Validate MatAnyone settings
|
| 177 |
+
self.matanyone_threshold = max(0.0, min(1.0, self.matanyone_threshold))
|
| 178 |
+
self.matanyone_weight_base = max(0.1, min(2.0, self.matanyone_weight_base))
|
| 179 |
+
self.matanyone_weight_hair = max(0.1, min(2.0, self.matanyone_weight_hair))
|
| 180 |
+
self.matanyone_weight_edge = max(0.1, min(2.0, self.matanyone_weight_edge))
|
| 181 |
+
self.matanyone_weight_detail = max(0.1, min(2.0, self.matanyone_weight_detail))
|
| 182 |
+
self.matanyone_blend_alpha = max(0.0, min(1.0, self.matanyone_blend_alpha))
|
| 183 |
+
self.matanyone_morphology_kernel_size = max(3, min(15, self.matanyone_morphology_kernel_size))
|
| 184 |
+
self.matanyone_trimap_dilation = max(1, min(50, self.matanyone_trimap_dilation))
|
| 185 |
+
|
| 186 |
+
# Validate MatAnyone processing mode
|
| 187 |
+
valid_modes = ['refine', 'replace', 'blend']
|
| 188 |
+
if self.matanyone_processing_mode not in valid_modes:
|
| 189 |
+
logger.warning(f"Invalid MatAnyone processing mode: {self.matanyone_processing_mode}. Setting to 'refine'.")
|
| 190 |
+
self.matanyone_processing_mode = 'refine'
|
| 191 |
+
|
| 192 |
# Validate output settings
|
| 193 |
valid_formats = ['mp4', 'avi', 'mov', 'webm', 'mkv']
|
| 194 |
if self.output_format not in valid_formats:
|
|
|
|
| 227 |
Path(self.output_dir) / 'two_stage'
|
| 228 |
]
|
| 229 |
|
| 230 |
+
# Add MatAnyone component directories if enabled
|
| 231 |
+
if self.use_component_masks:
|
| 232 |
+
directories.extend([
|
| 233 |
+
self.hair_masks_dir,
|
| 234 |
+
self.edge_masks_dir,
|
| 235 |
+
self.detail_masks_dir
|
| 236 |
+
])
|
| 237 |
+
|
| 238 |
for directory in directories:
|
| 239 |
try:
|
| 240 |
Path(directory).mkdir(parents=True, exist_ok=True)
|
|
|
|
| 307 |
config_dict = yaml.safe_load(f)
|
| 308 |
return cls(**config_dict)
|
| 309 |
|
| 310 |
+
def get_matanyone_config(self) -> Dict[str, Any]:
|
| 311 |
+
"""Get MatAnyone-specific configuration as a dictionary"""
|
| 312 |
+
return {
|
| 313 |
+
'enabled': self.matanyone_enabled,
|
| 314 |
+
'model_path': self.matanyone_model_path,
|
| 315 |
+
'threshold': self.matanyone_threshold,
|
| 316 |
+
'edge_refinement': self.matanyone_edge_enhancement,
|
| 317 |
+
'hair_refinement': self.matanyone_hair_refinement,
|
| 318 |
+
'detail_refinement': self.matanyone_detail_refinement,
|
| 319 |
+
'morphology_ops': self.matanyone_morphology_ops,
|
| 320 |
+
'morphology_kernel_size': self.matanyone_morphology_kernel_size,
|
| 321 |
+
'processing_mode': self.matanyone_processing_mode,
|
| 322 |
+
'blend_alpha': self.matanyone_blend_alpha,
|
| 323 |
+
'trimap_enabled': self.matanyone_trimap_enabled,
|
| 324 |
+
'trimap_dilation': self.matanyone_trimap_dilation,
|
| 325 |
+
'component_weights': {
|
| 326 |
+
'base': self.matanyone_weight_base,
|
| 327 |
+
'hair': self.matanyone_weight_hair,
|
| 328 |
+
'edge': self.matanyone_weight_edge,
|
| 329 |
+
'detail': self.matanyone_weight_detail
|
| 330 |
+
},
|
| 331 |
+
'component_paths': {
|
| 332 |
+
'hair': self.hair_masks_dir if self.use_component_masks else None,
|
| 333 |
+
'edge': self.edge_masks_dir if self.use_component_masks else None,
|
| 334 |
+
'detail': self.detail_masks_dir if self.use_component_masks else None
|
| 335 |
+
},
|
| 336 |
+
'precision': self.matanyone_precision
|
| 337 |
+
}
|
| 338 |
+
|
| 339 |
def get_quality_settings(self) -> Dict[str, Any]:
|
| 340 |
"""Get quality-specific settings based on preset"""
|
| 341 |
quality_maps = {
|
|
|
|
| 346 |
'temporal_consistency': False,
|
| 347 |
'model_precision': 'fp16',
|
| 348 |
'batch_size': min(self.batch_size * 2, 16),
|
| 349 |
+
'output_quality_params': '-preset ultrafast -crf 28',
|
| 350 |
+
'matanyone_enabled': False # Disable MatAnyone for fast mode
|
| 351 |
},
|
| 352 |
'balanced': {
|
| 353 |
'keyframe_interval': self.keyframe_interval,
|
|
|
|
| 356 |
'temporal_consistency': True,
|
| 357 |
'model_precision': 'fp32',
|
| 358 |
'batch_size': self.batch_size,
|
| 359 |
+
'output_quality_params': '-preset medium -crf 23',
|
| 360 |
+
'matanyone_enabled': self.matanyone_enabled
|
| 361 |
},
|
| 362 |
'high': {
|
| 363 |
'keyframe_interval': max(self.keyframe_interval // 2, 1),
|
|
|
|
| 366 |
'temporal_consistency': True,
|
| 367 |
'model_precision': 'fp32',
|
| 368 |
'batch_size': max(self.batch_size // 2, 1),
|
| 369 |
+
'output_quality_params': '-preset slow -crf 18',
|
| 370 |
+
'matanyone_enabled': True # Enable MatAnyone for high quality
|
| 371 |
},
|
| 372 |
'ultra': {
|
| 373 |
'keyframe_interval': 1,
|
|
|
|
| 376 |
'temporal_consistency': True,
|
| 377 |
'model_precision': 'fp32',
|
| 378 |
'batch_size': 1,
|
| 379 |
+
'output_quality_params': '-preset veryslow -crf 15',
|
| 380 |
+
'matanyone_enabled': True, # Always enable MatAnyone for ultra
|
| 381 |
+
'matanyone_morphology_ops': True,
|
| 382 |
+
'matanyone_trimap_enabled': True
|
| 383 |
}
|
| 384 |
}
|
| 385 |
|
|
|
|
| 417 |
self.quality_preset in ['high', 'ultra'] and
|
| 418 |
self.edge_refinement and
|
| 419 |
self.temporal_consistency and
|
| 420 |
+
self.keyframe_interval <= 3 and
|
| 421 |
+
self.matanyone_enabled # Include MatAnyone in high performance check
|
| 422 |
)
|
| 423 |
|
| 424 |
def get_memory_limits(self) -> Dict[str, Any]:
|
|
|
|
| 456 |
if self.max_concurrent_processes > 4:
|
| 457 |
warnings.append("High concurrent processes may cause instability")
|
| 458 |
|
| 459 |
+
# MatAnyone-specific warnings
|
| 460 |
+
if self.matanyone_enabled and self.quality_preset == 'fast':
|
| 461 |
+
warnings.append("MatAnyone is enabled with 'fast' quality preset (may impact performance)")
|
| 462 |
+
|
| 463 |
+
if self.use_component_masks and not Path(self.hair_masks_dir).exists():
|
| 464 |
+
warnings.append(f"Component masks enabled but directory not found: {self.hair_masks_dir}")
|
| 465 |
+
|
| 466 |
return warnings
|
| 467 |
|
| 468 |
# Singleton instance for application-wide use
|