@@ -118,6 +118,15 @@ def get_commit_hash():
118118 return commit_hash
119119
120120
121+ def convert_i16_to_rgb (image , like ):
122+ # three channel, 8 bits per channel image
123+ output = np .zeros_like (like )
124+ output [:, :, 0 ] = image / 256.0
125+ output [:, :, 1 ] = image / 256.0
126+ output [:, :, 2 ] = image / 256.0
127+ return output
128+
129+
121130def main_ui_panel (is_depth_tab ):
122131 inp = GradioComponentBundle ()
123132 # TODO: Greater visual separation
@@ -344,7 +353,7 @@ def run(self, p, *inputs):
344353 continue
345354 inputimages .append (processed .images [count ])
346355
347- generated_images , mesh_fi , meshsimple_fi = run_depthmap (processed , p .outpath_samples , inputimages , None , inputs )
356+ generated_images , mesh_fi , meshsimple_fi = run_depthmap (p .outpath_samples , inputimages , None , None , inputs )
348357
349358 for input_i , imgs in enumerate (generated_images ):
350359 # get generation parameters
@@ -355,10 +364,15 @@ def run(self, p, *inputs):
355364 for image_type , image in list (imgs .items ()):
356365 processed .images .append (image )
357366 if inputs ["save_outputs" ]:
358- images .save_image (image , path = p .outpath_samples , basename = "" , seed = processed .all_seeds [input_i ],
367+ try :
368+ images .save_image (image , path = p .outpath_samples , basename = "" , seed = processed .all_seeds [input_i ],
359369 prompt = processed .all_prompts [input_i ], extension = opts .samples_format , info = info ,
360370 p = processed ,
361371 suffix = f"_{ image_type } " )
372+ except Exception as e :
373+ if not ('image has wrong mode' in str (e ) or 'I;16' in str (e )): raise e
374+ print ('Catched exception: image has wrong mode!' )
375+ traceback .print_exc ()
362376 return processed
363377
364378
@@ -374,9 +388,12 @@ def reload_sd_model():
374388 shared .sd_model .first_stage_model .to (devices .device )
375389
376390
377- def run_depthmap (processed , outpath , inputimages , inputnames , inp ):
391+ def run_depthmap (outpath , inputimages , inputdepthmaps , inputnames , inp ):
378392 if len (inputimages ) == 0 or inputimages [0 ] is None :
379- return [], []
393+ return [], '' , ''
394+ if len (inputdepthmaps ) == 0 :
395+ inputdepthmaps = [None for _ in range (len (inputimages ))]
396+ inputdepthmaps_complete = all ([x is not None for x in inputdepthmaps ])
380397
381398 background_removal = inp ["background_removal" ]
382399 background_removal_model = inp ["background_removal_model" ]
@@ -409,10 +426,6 @@ def run_depthmap(processed, outpath, inputimages, inputnames, inp):
409426 stereo_modes = inp ["stereo_modes" ]
410427 stereo_separation = inp ["stereo_separation" ]
411428
412- custom_depthmap = inp ["custom_depthmap" ] if "custom_depthmap" in inp else False
413- custom_depthmap_img = inp ["custom_depthmap_img" ] if "custom_depthmap_img" in inp else None
414- depthmap_batch_reuse = inp ["depthmap_batch_reuse" ] if "depthmap_batch_reuse" in inp else True
415-
416429 # TODO: run_depthmap should not generate or save meshes, since these do not use generated depthmaps.
417430 # Rationale: allowing webui-independent (stand-alone) wrappers.
418431 print (f"\n { scriptname } { scriptversion } ({ get_commit_hash ()} )" )
@@ -429,9 +442,6 @@ def run_depthmap(processed, outpath, inputimages, inputnames, inp):
429442 else :
430443 background_removed_images = batched_background_removal (inputimages , background_removal_model )
431444
432- meshsimple_fi = None
433- mesh_fi = None
434-
435445 resize_mode = "minimal"
436446 normalization = NormalizeImage (mean = [0.5 , 0.5 , 0.5 ], std = [0.5 , 0.5 , 0.5 ])
437447
@@ -455,7 +465,7 @@ def run_depthmap(processed, outpath, inputimages, inputnames, inp):
455465 os .makedirs ('./models/pix2pix' , exist_ok = True )
456466
457467 global depthmap_model_depth , depthmap_model_pix2pix , depthmap_model_type , depthmap_device_idx
458- loadmodels = True
468+ loadmodels = True # TODO: loadmodels is not intuitive
459469 if hasattr (opts , 'depthmap_script_keepmodels' ) and opts .depthmap_script_keepmodels :
460470 loadmodels = False
461471 if depthmap_model_type != model_type or depthmap_model_depth == None or depthmap_device_idx != depthmap_compute_device :
@@ -464,7 +474,7 @@ def run_depthmap(processed, outpath, inputimages, inputnames, inp):
464474 loadmodels = True
465475
466476 try :
467- if loadmodels and not ( custom_depthmap and custom_depthmap_img != None ) :
477+ if loadmodels and not inputdepthmaps_complete :
468478 # TODO: loading model should be separated into a function that would return the model
469479 # and the parameters (or maybe even functions) needed.
470480 # The rest of the run_depthmap should not depend on what specific model
@@ -645,10 +655,12 @@ def run_depthmap(processed, outpath, inputimages, inputnames, inp):
645655 # Every array element corresponds to particular input image.
646656 # Dictionary keys are types of images that were derived from the input image.
647657 generated_images = [{} for _ in range (numimages )]
658+
648659 # TODO: ???
660+ meshsimple_fi = None
649661 inpaint_imgs = []
650- # TODO: ???
651662 inpaint_depths = []
663+
652664 # iterate over input (generated) images
653665 for count in trange (0 , numimages ):
654666
@@ -657,25 +669,8 @@ def run_depthmap(processed, outpath, inputimages, inputnames, inp):
657669 # filename
658670 basename = 'depthmap'
659671
660- # TODO: this should not use heuristics to figure out the mode, mode should ideally be abstracted away.
661- # By the way, this is probably broken
662- # figuring out the name of custom DepthMap
663- custom_depthmap_fn = None # None means that DepthMap should be computed
664- # find filename if in the single image mode
665- if custom_depthmap and custom_depthmap_img is not None :
666- custom_depthmap_fn = custom_depthmap_img .name
667- # find filename if in batch mode
668- if inputnames is not None and depthmap_batch_reuse :
669- if inputnames [count ] is not None :
670- p = Path (inputnames [count ])
671- basename = p .stem
672- if outpath != opts .outdir_extras_samples :
673- custom_depthmap_fn = os .path .join (outpath , basename + '-0000.' + opts .samples_format )
674- if not os .path .isfile (custom_depthmap_fn ):
675- custom_depthmap_fn = None
676-
677672 # override net size
678- if ( match_size ) :
673+ if match_size :
679674 net_width , net_height = inputimages [count ].width , inputimages [count ].height
680675
681676 # Convert single channel input (PIL) images to rgb
@@ -687,10 +682,9 @@ def run_depthmap(processed, outpath, inputimages, inputnames, inp):
687682 img = cv2 .cvtColor (np .asarray (inputimages [count ]), cv2 .COLOR_BGR2RGB ) / 255.0
688683
689684 skipInvertAndSave = False
690- # TODO: custom depthmaps should be supplied in the same way as "custom depthmap" in single image mode
691- if custom_depthmap_fn is not None :
685+ if inputdepthmaps is not None and inputdepthmaps [count ] is not None :
692686 # use custom depthmap
693- dimg = Image . open ( os . path . abspath ( custom_depthmap_fn ))
687+ dimg = inputdepthmaps [ count ]
694688 # resize if not same size as input
695689 if dimg .width != inputimages [count ].width or dimg .height != inputimages [count ].height :
696690 dimg = dimg .resize ((inputimages [count ].width , inputimages [count ].height ), Image .Resampling .LANCZOS )
@@ -736,12 +730,6 @@ def run_depthmap(processed, outpath, inputimages, inputnames, inp):
736730 img_output = clipdepthmap (img_output , clipthreshold_far , clipthreshold_near )
737731 # img_output = cv2.blur(img_output, (3, 3))
738732
739- # three channel, 8 bits per channel image
740- img_output2 = np .zeros_like (inputimages [count ])
741- img_output2 [:, :, 0 ] = img_output / 256.0
742- img_output2 [:, :, 1 ] = img_output / 256.0
743- img_output2 [:, :, 2 ] = img_output / 256.0
744-
745733 # if 3dinpainting, store maps for processing in second pass
746734 if inpaint :
747735 inpaint_imgs .append (inputimages [count ])
@@ -773,7 +761,8 @@ def run_depthmap(processed, outpath, inputimages, inputnames, inp):
773761 if not skipInvertAndSave : # TODO: skipInvertAndSave is not intuitive
774762 if output_depth :
775763 if combine_output :
776- img_concat = Image .fromarray (np .concatenate ((rgb_image , img_output2 ), axis = combine_output_axis ))
764+ img_concat = Image .fromarray (np .concatenate (
765+ (rgb_image , convert_i16_to_rgb (img_output , rgb_image )), axis = combine_output_axis ))
777766 generated_images [count ]['concat_depth' ] = img_concat
778767 else :
779768 generated_images [count ]['depth' ] = Image .fromarray (img_output )
@@ -819,9 +808,9 @@ def run_depthmap(processed, outpath, inputimages, inputnames, inp):
819808
820809 depthi = prediction
821810 # try to map output to sensible values for non zoedepth models, boost, or custom maps
822- if model_type < 7 or boost or ( custom_depthmap and custom_depthmap_img != None ) :
811+ if model_type < 7 or boost or inputdepthmaps_complete :
823812 # invert if midas
824- if model_type > 0 or (( custom_depthmap and custom_depthmap_img != None ) and not invert_depth ):
813+ if model_type > 0 or (inputdepthmaps_complete and not invert_depth ):
825814 depthi = depth_max - depthi + depth_min
826815 depth_max = depthi .max ()
827816 depth_min = depthi .min ()
@@ -860,13 +849,15 @@ def run_depthmap(processed, outpath, inputimages, inputnames, inp):
860849 gc .collect ()
861850 devices .torch_gc ()
862851 reload_sd_model ()
863- try :
864- if inpaint :
852+
853+ mesh_fi = None
854+ if inpaint :
855+ try :
865856 unload_sd_model ()
866857 mesh_fi = run_3dphoto (device , inpaint_imgs , inpaint_depths , inputnames , outpath , inpaint_vids , 1 , "mp4" )
867- finally :
868- reload_sd_model ()
869- print ("All done." )
858+ finally :
859+ reload_sd_model () # Do not reload twice
860+ print ("All done." )
870861
871862 return generated_images , mesh_fi , meshsimple_fi
872863
@@ -1196,15 +1187,27 @@ def run_generate(*inputs):
11961187 depthmap_input_image = inputs ['depthmap_input_image' ]
11971188 depthmap_batch_output_dir = inputs ['depthmap_batch_output_dir' ]
11981189 depthmap_batch_reuse = inputs ['depthmap_batch_reuse' ]
1190+ custom_depthmap = inputs ['custom_depthmap' ]
1191+ custom_depthmap_img = inputs ['custom_depthmap_img' ]
11991192
12001193 inputimages = []
1194+ # Allow supplying custom depthmaps
1195+ inputdepthmaps = []
12011196 # Also keep track of original file names
12021197 inputnames = []
1203- show_images = []
1198+
1199+ if depthmap_mode == '2' and depthmap_batch_output_dir != '' :
1200+ outpath = depthmap_batch_output_dir
1201+ else :
1202+ outpath = opts .outdir_samples or opts .outdir_extras_samples
12041203
12051204 if depthmap_mode == '0' : # Single image
12061205 inputimages .append (depthmap_input_image )
12071206 inputnames .append (None )
1207+ if custom_depthmap :
1208+ inputdepthmaps .append (custom_depthmap_img )
1209+ else :
1210+ inputdepthmaps .append (None )
12081211 if depthmap_mode == '1' : # Batch Process
12091212 # convert files to pillow images
12101213 for img in image_batch :
@@ -1214,39 +1217,58 @@ def run_generate(*inputs):
12141217 elif depthmap_mode == '2' : # Batch from Directory
12151218 assert not shared .cmd_opts .hide_ui_dir_config , '--hide-ui-dir-config option must be disabled'
12161219 if depthmap_batch_input_dir == '' :
1217- return show_images , "Please select an input directory." , ''
1220+ return [], "Please select an input directory." , ""
1221+ if depthmap_batch_input_dir == depthmap_batch_output_dir :
1222+ return [], "Please pick different directories for batch processing." , ""
12181223 image_list = shared .listfiles (depthmap_batch_input_dir )
1219- for img in image_list :
1224+ for path in image_list :
12201225 try :
1221- image = Image .open (img )
1222- inputimages .append (image )
1223- inputnames .append (img )
1224- except Exception :
1225- print (f'Failed to load { img } , ignoring.' )
1226+ inputimages .append (Image .open (path ))
1227+ inputnames .append (path )
12261228
1227- if depthmap_mode == '2' and depthmap_batch_output_dir != '' :
1228- outpath = depthmap_batch_output_dir
1229- else :
1230- outpath = opts .outdir_samples or opts .outdir_extras_samples
1229+ custom_depthmap = None
1230+ if depthmap_batch_reuse :
1231+ basename = Path (path ).stem
1232+ # Custom names are not used in samples directory
1233+ if outpath != opts .outdir_extras_samples :
1234+ # Possible filenames that the custom depthmaps may have
1235+ name_candidates = [f'{ basename } -0000_depth.{ opts .samples_format } ' , # current format
1236+ f'{ basename } -0000.{ opts .samples_format } ' , # old format
1237+ f'{ basename } .png' , # human-intuitive format
1238+ f'{ Path (path ).name } ' ] # human-intuitive format (worse)
1239+ for fn_cand in name_candidates :
1240+ path_cand = os .path .join (outpath , fn_cand )
1241+ if os .path .isfile (path_cand ):
1242+ custom_depthmap = Image .open (os .path .abspath (path_cand ))
1243+ break
1244+ inputdepthmaps .append (custom_depthmap )
1245+ except Exception :
1246+ print (f'Failed to load { path } , ignoring.' )
1247+ inputdepthmaps_n = len ([1 for x in inputdepthmaps if x is not None ])
1248+ print (f'{ len (inputimages )} images will be processed, { inputdepthmaps_n } existing depthmaps will be reused' )
12311249
1232- save_images , mesh_fi , meshsimple_fi = run_depthmap (None , outpath , inputimages , inputnames , inputs )
1250+ save_images , mesh_fi , meshsimple_fi = run_depthmap (outpath , inputimages , inputdepthmaps , inputnames , inputs )
12331251 show_images = []
12341252
12351253 # Saving images
12361254 for input_i , imgs in enumerate (save_images ):
12371255 basename = 'depthmap'
1238- if depthmap_batch_reuse and depthmap_mode == '2' :
1239- if inputnames [input_i ] is not None :
1240- basename = Path (inputnames [input_i ]).stem
1256+ if depthmap_mode == '2' and inputnames [input_i ] is not None and outpath != opts .outdir_extras_samples :
1257+ basename = Path (inputnames [input_i ]).stem
12411258 info = None
12421259
12431260 for image_type , image in list (imgs .items ()):
12441261 show_images += [image ]
12451262 if inputs ["save_outputs" ]:
1246- images .save_image (image , path = outpath , basename = basename , seed = None ,
1263+ try :
1264+ images .save_image (image , path = outpath , basename = basename , seed = None ,
12471265 prompt = None , extension = opts .samples_format , info = info , short_filename = True ,
12481266 no_prompt = True , grid = False , pnginfo_section_name = "extras" , existing_info = None ,
12491267 forced_filename = None , suffix = f"_{ image_type } " )
1268+ except Exception as e :
1269+ if not ('image has wrong mode' in str (e ) or 'I;16' in str (e )): raise e
1270+ print ('Catched exception: image has wrong mode!' )
1271+ traceback .print_exc ()
12501272
12511273 # use inpainted 3d mesh to show in 3d model output when enabled in settings
12521274 if hasattr (opts , 'depthmap_script_show_3d_inpaint' ) and opts .depthmap_script_show_3d_inpaint and mesh_fi != None and len (mesh_fi ) > 0 :
@@ -1320,8 +1342,9 @@ def on_ui_tabs():
13201342 inp += gr .Textbox (elem_id = "depthmap_batch_output_dir" , label = "Output directory" ,
13211343 ** shared .hide_dirs ,
13221344 placeholder = "Leave blank to save images to the default path." )
1345+ gr .HTML ("Files in the output directory may be overwritten" )
13231346 inp += gr .Checkbox (elem_id = "depthmap_batch_reuse" ,
1324- label = "Skip generation and use (edited/custom) depthmaps in output directory when a file exists." ,
1347+ label = "Skip generation and use (edited/custom) depthmaps in output directory when a file already exists." ,
13251348 value = True )
13261349 submit = gr .Button ('Generate' , elem_id = "depthmap_generate" , variant = 'primary' )
13271350 inp += main_ui_panel (True ) # Main panel is inserted here
0 commit comments