Update app.py
Browse files
app.py
CHANGED
|
@@ -4,6 +4,7 @@
|
|
| 4 |
- Fixed output path parameter (now uses proper .mp4 extension)
|
| 5 |
- Fixed parameter order for TwoStageProcessor.process_video()
|
| 6 |
- Fixed background handling (pass background, not preset to processor)
|
|
|
|
| 7 |
- All other functionality maintained from working version
|
| 8 |
"""
|
| 9 |
|
|
@@ -1686,16 +1687,28 @@ def _ensure_file_exists(path_str: str) -> bool:
|
|
| 1686 |
except Exception:
|
| 1687 |
return False
|
| 1688 |
|
| 1689 |
-
def
|
| 1690 |
-
"""
|
| 1691 |
-
|
| 1692 |
-
|
| 1693 |
-
|
| 1694 |
-
|
| 1695 |
-
|
| 1696 |
-
|
| 1697 |
-
|
| 1698 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1699 |
|
| 1700 |
def resolve_background(
|
| 1701 |
video_path: str,
|
|
@@ -1725,7 +1738,7 @@ def resolve_background(
|
|
| 1725 |
img = cv2.imread(upload_img_path)
|
| 1726 |
if img is None:
|
| 1727 |
raise RuntimeError("Failed to read uploaded background image.")
|
| 1728 |
-
img =
|
| 1729 |
cv2.imwrite(out_path, img)
|
| 1730 |
return out_path
|
| 1731 |
|
|
@@ -1743,7 +1756,7 @@ def resolve_background(
|
|
| 1743 |
img = cv2.imread(path)
|
| 1744 |
if img is None:
|
| 1745 |
raise RuntimeError(f"Failed to load preset image: {preset_name}")
|
| 1746 |
-
img =
|
| 1747 |
cv2.imwrite(out_path, img)
|
| 1748 |
return out_path
|
| 1749 |
|
|
@@ -1752,6 +1765,7 @@ def resolve_background(
|
|
| 1752 |
raise RuntimeError("Please select a gradient preset.")
|
| 1753 |
c1, c2 = GRADIENT_PRESETS[gradient_name]
|
| 1754 |
grad = _make_vertical_gradient(w, h, c1, c2)
|
|
|
|
| 1755 |
cv2.imwrite(out_path, grad)
|
| 1756 |
return out_path
|
| 1757 |
|
|
@@ -1760,6 +1774,7 @@ def resolve_background(
|
|
| 1760 |
# If you wire up a diffusion pipeline later, render to (w,h) here and save to out_path.
|
| 1761 |
logger.info("AI Background requested: %s (using placeholder gradient for now)", ai_prompt or "(no prompt)")
|
| 1762 |
grad = _make_vertical_gradient(w, h, (80, 72, 96), (180, 180, 210))
|
|
|
|
| 1763 |
cv2.imwrite(out_path, grad)
|
| 1764 |
return out_path
|
| 1765 |
|
|
@@ -1917,6 +1932,10 @@ def _toggle_bg_fields(src):
|
|
| 1917 |
gr.update(visible=(src == "AI Background")), # ai_prompt
|
| 1918 |
)
|
| 1919 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1920 |
background_source.change(
|
| 1921 |
_toggle_bg_fields,
|
| 1922 |
inputs=[background_source],
|
|
@@ -1944,7 +1963,7 @@ def _toggle_bg_fields(src):
|
|
| 1944 |
gr.Markdown("""
|
| 1945 |
**Background Notes**
|
| 1946 |
- *Professional Presets* expect files under `assets/backgrounds/professional/`.
|
| 1947 |
-
- *Gradients* render on-the-fly (fastest).
|
| 1948 |
- *AI Background* is currently a placeholder gradient — wire a diffusion
|
| 1949 |
pipeline here later to render images from prompts, then save and return the path.
|
| 1950 |
""")
|
|
@@ -1957,7 +1976,6 @@ def _toggle_bg_fields(src):
|
|
| 1957 |
|
| 1958 |
def main():
|
| 1959 |
logger.info("Starting Video Background Replacement - SAM2 LARGE (REVERTED TO WORKING VERSION)")
|
| 1960 |
-
|
| 1961 |
interface = create_interface()
|
| 1962 |
interface.launch(
|
| 1963 |
server_name="0.0.0.0",
|
|
@@ -1968,4 +1986,4 @@ def main():
|
|
| 1968 |
)
|
| 1969 |
|
| 1970 |
if __name__ == "__main__":
|
| 1971 |
-
main()
|
|
|
|
| 4 |
- Fixed output path parameter (now uses proper .mp4 extension)
|
| 5 |
- Fixed parameter order for TwoStageProcessor.process_video()
|
| 6 |
- Fixed background handling (pass background, not preset to processor)
|
| 7 |
+
- Added robust vertical gradient + background size guard to prevent broadcasting errors
|
| 8 |
- All other functionality maintained from working version
|
| 9 |
"""
|
| 10 |
|
|
|
|
| 1687 |
except Exception:
|
| 1688 |
return False
|
| 1689 |
|
| 1690 |
+
def _ensure_size_bgr(img: np.ndarray, width: int, height: int) -> np.ndarray:
|
| 1691 |
+
"""Guarantee image is (height,width,3) BGR uint8."""
|
| 1692 |
+
if img is None or getattr(img, "size", 0) == 0:
|
| 1693 |
+
raise ValueError("Background image is empty")
|
| 1694 |
+
if img.ndim == 2:
|
| 1695 |
+
img = cv2.cvtColor(img, cv2.COLOR_GRAY2BGR)
|
| 1696 |
+
if img.shape[2] != 3:
|
| 1697 |
+
img = img[:, :, :3]
|
| 1698 |
+
if (img.shape[1], img.shape[0]) != (width, height):
|
| 1699 |
+
img = cv2.resize(img, (width, height), interpolation=cv2.INTER_AREA)
|
| 1700 |
+
return img.astype(np.uint8)
|
| 1701 |
+
|
| 1702 |
+
def _make_vertical_gradient(width: int, height: int, c1, c2) -> np.ndarray:
|
| 1703 |
+
"""
|
| 1704 |
+
Make a vertical BGR gradient image (uint8).
|
| 1705 |
+
Returns shape = (height, width, 3). Broadcast-safe via explicit repeat.
|
| 1706 |
+
"""
|
| 1707 |
+
top = np.array(c1, dtype=np.float32) # (3,)
|
| 1708 |
+
bot = np.array(c2, dtype=np.float32) # (3,)
|
| 1709 |
+
rows = np.linspace(top, bot, num=max(1, height), dtype=np.float32) # (height, 3)
|
| 1710 |
+
grad = np.repeat(rows[:, None, :], repeats=max(1, width), axis=1) # (height, width, 3)
|
| 1711 |
+
return np.clip(grad, 0, 255).astype(np.uint8)
|
| 1712 |
|
| 1713 |
def resolve_background(
|
| 1714 |
video_path: str,
|
|
|
|
| 1738 |
img = cv2.imread(upload_img_path)
|
| 1739 |
if img is None:
|
| 1740 |
raise RuntimeError("Failed to read uploaded background image.")
|
| 1741 |
+
img = _ensure_size_bgr(img, w, h)
|
| 1742 |
cv2.imwrite(out_path, img)
|
| 1743 |
return out_path
|
| 1744 |
|
|
|
|
| 1756 |
img = cv2.imread(path)
|
| 1757 |
if img is None:
|
| 1758 |
raise RuntimeError(f"Failed to load preset image: {preset_name}")
|
| 1759 |
+
img = _ensure_size_bgr(img, w, h)
|
| 1760 |
cv2.imwrite(out_path, img)
|
| 1761 |
return out_path
|
| 1762 |
|
|
|
|
| 1765 |
raise RuntimeError("Please select a gradient preset.")
|
| 1766 |
c1, c2 = GRADIENT_PRESETS[gradient_name]
|
| 1767 |
grad = _make_vertical_gradient(w, h, c1, c2)
|
| 1768 |
+
grad = _ensure_size_bgr(grad, w, h)
|
| 1769 |
cv2.imwrite(out_path, grad)
|
| 1770 |
return out_path
|
| 1771 |
|
|
|
|
| 1774 |
# If you wire up a diffusion pipeline later, render to (w,h) here and save to out_path.
|
| 1775 |
logger.info("AI Background requested: %s (using placeholder gradient for now)", ai_prompt or "(no prompt)")
|
| 1776 |
grad = _make_vertical_gradient(w, h, (80, 72, 96), (180, 180, 210))
|
| 1777 |
+
grad = _ensure_size_bgr(grad, w, h)
|
| 1778 |
cv2.imwrite(out_path, grad)
|
| 1779 |
return out_path
|
| 1780 |
|
|
|
|
| 1932 |
gr.update(visible=(src == "AI Background")), # ai_prompt
|
| 1933 |
)
|
| 1934 |
|
| 1935 |
+
background_source.change(
|
| 1936 |
+
_toggle_bg_fields,
|
| 1937 |
+
inputs=[background_source],
|
| 1938 |
+
|
| 1939 |
background_source.change(
|
| 1940 |
_toggle_bg_fields,
|
| 1941 |
inputs=[background_source],
|
|
|
|
| 1963 |
gr.Markdown("""
|
| 1964 |
**Background Notes**
|
| 1965 |
- *Professional Presets* expect files under `assets/backgrounds/professional/`.
|
| 1966 |
+
- *Gradients* render on-the-fly (fastest) and are auto-sized to your video to avoid broadcasting issues.
|
| 1967 |
- *AI Background* is currently a placeholder gradient — wire a diffusion
|
| 1968 |
pipeline here later to render images from prompts, then save and return the path.
|
| 1969 |
""")
|
|
|
|
| 1976 |
|
| 1977 |
def main():
|
| 1978 |
logger.info("Starting Video Background Replacement - SAM2 LARGE (REVERTED TO WORKING VERSION)")
|
|
|
|
| 1979 |
interface = create_interface()
|
| 1980 |
interface.launch(
|
| 1981 |
server_name="0.0.0.0",
|
|
|
|
| 1986 |
)
|
| 1987 |
|
| 1988 |
if __name__ == "__main__":
|
| 1989 |
+
main()
|