|
1 |
| -# Non-public API. Don't host publicly - SECURITY RISKS! |
2 |
| -# (will only be on with --api starting option) |
3 |
| -# Currently no API stability guarantees are provided - API may break on any new commit. |
| 1 | +# DO NOT HOST PUBLICLY - SECURITY RISKS! |
| 2 | +# (the API will only be on with --api starting option) |
| 3 | +# Currently no API stability guarantees are provided - API may break on any new commit (but hopefully won't). |
4 | 4 |
|
| 5 | +import os |
5 | 6 | import numpy as np
|
6 | 7 | from fastapi import FastAPI, Body
|
7 | 8 | from fastapi.exceptions import HTTPException
|
|
12 | 13 | from typing import Dict, List
|
13 | 14 | from modules.api import api
|
14 | 15 |
|
15 |
| -from src.core import core_generation_funnel |
| 16 | +from src.core import core_generation_funnel, run_makevideo |
16 | 17 | from src.misc import SCRIPT_VERSION
|
17 | 18 | from src import backbone
|
18 | 19 | from src.common_constants import GenerationOptions as go
|
@@ -70,12 +71,110 @@ async def process(
|
70 | 71 | if not isinstance(result, Image.Image):
|
71 | 72 | continue
|
72 | 73 | results_based += [encode_to_base64(result)]
|
| 74 | + |
73 | 75 | return {"images": results_based, "info": "Success"}
|
74 | 76 |
|
| 77 | + @app.post("/depth/generate/video") |
| 78 | + async def process_video( |
| 79 | + depth_input_images: List[str] = Body([], title='Input Images'), |
| 80 | + options: Dict[str, object] = Body("options", title='Generation options'), |
| 81 | + ): |
| 82 | + if len(depth_input_images) == 0: |
| 83 | + raise HTTPException(status_code=422, detail="No images supplied") |
| 84 | + print(f"Processing {str(len(depth_input_images))} images trough the API") |
| 85 | + |
| 86 | + available_models = { |
| 87 | + 'res101': 0, |
| 88 | + 'dpt_beit_large_512': 1, #midas 3.1 |
| 89 | + 'dpt_beit_large_384': 2, #midas 3.1 |
| 90 | + 'dpt_large_384': 3, #midas 3.0 |
| 91 | + 'dpt_hybrid_384': 4, #midas 3.0 |
| 92 | + 'midas_v21': 5, |
| 93 | + 'midas_v21_small': 6, |
| 94 | + 'zoedepth_n': 7, #indoor |
| 95 | + 'zoedepth_k': 8, #outdoor |
| 96 | + 'zoedepth_nk': 9, |
| 97 | + } |
| 98 | + |
| 99 | + model_type = options["model_type"] |
| 100 | + |
| 101 | + model_id = None |
| 102 | + if isinstance(model_type, str): |
| 103 | + # Check if the string is in the available_models dictionary |
| 104 | + if model_type in available_models: |
| 105 | + model_id = available_models[model_type] |
| 106 | + else: |
| 107 | + available_strings = list(available_models.keys()) |
| 108 | + raise HTTPException(status_code=400, detail={'error': 'Invalid model string', 'available_models': available_strings}) |
| 109 | + elif isinstance(model_type, int): |
| 110 | + model_id = model_type |
| 111 | + else: |
| 112 | + raise HTTPException(status_code=400, detail={'error': 'Invalid model parameter type'}) |
| 113 | + |
| 114 | + options["model_type"] = model_id |
| 115 | + |
| 116 | + video_parameters = options["video_parameters"] |
| 117 | + |
| 118 | + required_params = ["vid_numframes", "vid_fps", "vid_traj", "vid_shift", "vid_border", "dolly", "vid_format", "vid_ssaa", "output_filename"] |
| 119 | + |
| 120 | + missing_params = [param for param in required_params if param not in video_parameters] |
| 121 | + |
| 122 | + if missing_params: |
| 123 | + raise HTTPException(status_code=400, detail={'error': f"Missing required parameter(s): {', '.join(missing_params)}"}) |
| 124 | + |
| 125 | + vid_numframes = video_parameters["vid_numframes"] |
| 126 | + vid_fps = video_parameters["vid_fps"] |
| 127 | + vid_traj = video_parameters["vid_traj"] |
| 128 | + vid_shift = video_parameters["vid_shift"] |
| 129 | + vid_border = video_parameters["vid_border"] |
| 130 | + dolly = video_parameters["dolly"] |
| 131 | + vid_format = video_parameters["vid_format"] |
| 132 | + vid_ssaa = int(video_parameters["vid_ssaa"]) |
| 133 | + |
| 134 | + output_filename = video_parameters["output_filename"] |
| 135 | + output_path = os.path.dirname(output_filename) |
| 136 | + basename, extension = os.path.splitext(os.path.basename(output_filename)) |
| 137 | + |
| 138 | + # Comparing video_format with the extension |
| 139 | + if vid_format != extension[1:]: |
| 140 | + raise HTTPException(status_code=400, detail={'error': f"Video format '{vid_format}' does not match with the extension '{extension}'."}) |
| 141 | + |
| 142 | + pil_images = [] |
| 143 | + for input_image in depth_input_images: |
| 144 | + pil_images.append(to_base64_PIL(input_image)) |
| 145 | + outpath = backbone.get_outpath() |
| 146 | + |
| 147 | + mesh_fi_filename = video_parameters.get('mesh_fi_filename', None) |
| 148 | + |
| 149 | + if mesh_fi_filename and os.path.exists(mesh_fi_filename): |
| 150 | + mesh_fi = mesh_fi_filename |
| 151 | + print("Loaded existing mesh from: ", mesh_fi) |
| 152 | + else: |
| 153 | + # If there is no mesh file generate it. |
| 154 | + options["GEN_INPAINTED_MESH"] = True |
| 155 | + |
| 156 | + gen_obj = core_generation_funnel(outpath, pil_images, None, None, options) |
| 157 | + |
| 158 | + mesh_fi = None |
| 159 | + for count, type, result in gen_obj: |
| 160 | + if type == 'inpainted_mesh': |
| 161 | + mesh_fi = result |
| 162 | + break |
| 163 | + |
| 164 | + if mesh_fi: |
| 165 | + print("Created mesh in: ", mesh_fi) |
| 166 | + else: |
| 167 | + raise HTTPException(status_code=400, detail={'error': "The mesh has not been created"}) |
| 168 | + |
| 169 | + run_makevideo(mesh_fi, vid_numframes, vid_fps, vid_traj, vid_shift, vid_border, dolly, vid_format, vid_ssaa, output_path, basename) |
| 170 | + |
| 171 | + return {"info": "Success"} |
| 172 | + |
75 | 173 |
|
76 | 174 | try:
|
77 | 175 | import modules.script_callbacks as script_callbacks
|
78 | 176 | if backbone.get_cmd_opt('api', False):
|
79 | 177 | script_callbacks.on_app_started(depth_api)
|
| 178 | + print("Started the depthmap API. DO NOT HOST PUBLICLY - SECURITY RISKS!") |
80 | 179 | except:
|
81 | 180 | print('DepthMap API could not start')
|
0 commit comments