libcom 0.1.8__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (310) hide show
  1. libcom/__init__.py +23 -0
  2. libcom/color_transfer/__init__.py +3 -0
  3. libcom/color_transfer/reinhard.py +57 -0
  4. libcom/fopa_heat_map/__init__.py +4 -0
  5. libcom/fopa_heat_map/fopa_heat_map.py +212 -0
  6. libcom/fopa_heat_map/source/__init__.py +0 -0
  7. libcom/fopa_heat_map/source/backbone/ResNet.py +229 -0
  8. libcom/fopa_heat_map/source/backbone/__init__.py +0 -0
  9. libcom/fopa_heat_map/source/data/OBdataset.py +292 -0
  10. libcom/fopa_heat_map/source/data/__init__.py +0 -0
  11. libcom/fopa_heat_map/source/data/all_transforms.py +25 -0
  12. libcom/fopa_heat_map/source/network/BaseBlocks.py +26 -0
  13. libcom/fopa_heat_map/source/network/DynamicModules.py +43 -0
  14. libcom/fopa_heat_map/source/network/ObPlaNet_simple.py +112 -0
  15. libcom/fopa_heat_map/source/network/__init__.py +1 -0
  16. libcom/fopa_heat_map/source/network/tensor_ops.py +37 -0
  17. libcom/fopa_heat_map/source/prepare_multi_fg_scales.py +85 -0
  18. libcom/fos_score/__init__.py +4 -0
  19. libcom/fos_score/fos_score_prediction.py +218 -0
  20. libcom/fos_score/source/__init__.py +0 -0
  21. libcom/fos_score/source/config/__init__.py +1 -0
  22. libcom/fos_score/source/config/config.py +68 -0
  23. libcom/fos_score/source/config/config.sfosd.yaml +43 -0
  24. libcom/fos_score/source/config/config_rfosd.yaml +43 -0
  25. libcom/fos_score/source/loss_function.py +118 -0
  26. libcom/fos_score/source/networks.py +355 -0
  27. libcom/harmony_score/__init__.py +3 -0
  28. libcom/harmony_score/harmony_score_prediction.py +119 -0
  29. libcom/harmony_score/source/__init__.py +0 -0
  30. libcom/harmony_score/source/bargainnet.py +226 -0
  31. libcom/image_harmonization/__init__.py +4 -0
  32. libcom/image_harmonization/image_harmonization.py +193 -0
  33. libcom/image_harmonization/source/__init__.py +0 -0
  34. libcom/image_harmonization/source/functions.py +747 -0
  35. libcom/image_harmonization/source/pct_net.py +85 -0
  36. libcom/image_harmonization/source/src/__init__.py +0 -0
  37. libcom/image_harmonization/source/src/lbm/__init__.py +0 -0
  38. libcom/image_harmonization/source/src/lbm/config.py +141 -0
  39. libcom/image_harmonization/source/src/lbm/data/__init__.py +62 -0
  40. libcom/image_harmonization/source/src/lbm/data/datasets/__init__.py +9 -0
  41. libcom/image_harmonization/source/src/lbm/data/datasets/collation_fn.py +41 -0
  42. libcom/image_harmonization/source/src/lbm/data/datasets/dataset.py +243 -0
  43. libcom/image_harmonization/source/src/lbm/data/datasets/datasets_config.py +42 -0
  44. libcom/image_harmonization/source/src/lbm/data/filters/__init__.py +12 -0
  45. libcom/image_harmonization/source/src/lbm/data/filters/base.py +21 -0
  46. libcom/image_harmonization/source/src/lbm/data/filters/filter_wrapper.py +36 -0
  47. libcom/image_harmonization/source/src/lbm/data/filters/filters.py +33 -0
  48. libcom/image_harmonization/source/src/lbm/data/filters/filters_config.py +32 -0
  49. libcom/image_harmonization/source/src/lbm/data/mappers/__init__.py +19 -0
  50. libcom/image_harmonization/source/src/lbm/data/mappers/base.py +26 -0
  51. libcom/image_harmonization/source/src/lbm/data/mappers/mappers.py +135 -0
  52. libcom/image_harmonization/source/src/lbm/data/mappers/mappers_config.py +109 -0
  53. libcom/image_harmonization/source/src/lbm/data/mappers/mappers_wrapper.py +31 -0
  54. libcom/image_harmonization/source/src/lbm/inference/__init__.py +4 -0
  55. libcom/image_harmonization/source/src/lbm/inference/inference.py +70 -0
  56. libcom/image_harmonization/source/src/lbm/inference/utils.py +222 -0
  57. libcom/image_harmonization/source/src/lbm/models/__init__.py +0 -0
  58. libcom/image_harmonization/source/src/lbm/models/base/__init__.py +4 -0
  59. libcom/image_harmonization/source/src/lbm/models/base/base_model.py +66 -0
  60. libcom/image_harmonization/source/src/lbm/models/base/model_config.py +8 -0
  61. libcom/image_harmonization/source/src/lbm/models/embedders/__init__.py +4 -0
  62. libcom/image_harmonization/source/src/lbm/models/embedders/base/__init__.py +4 -0
  63. libcom/image_harmonization/source/src/lbm/models/embedders/base/base_conditioner.py +60 -0
  64. libcom/image_harmonization/source/src/lbm/models/embedders/base/base_conditioner_config.py +27 -0
  65. libcom/image_harmonization/source/src/lbm/models/embedders/conditioners_wrapper.py +114 -0
  66. libcom/image_harmonization/source/src/lbm/models/embedders/latents_concat/__init__.py +4 -0
  67. libcom/image_harmonization/source/src/lbm/models/embedders/latents_concat/latents_concat_embedder_config.py +31 -0
  68. libcom/image_harmonization/source/src/lbm/models/embedders/latents_concat/latents_concat_embedder_model.py +80 -0
  69. libcom/image_harmonization/source/src/lbm/models/lbm/__init__.py +4 -0
  70. libcom/image_harmonization/source/src/lbm/models/lbm/lbm_config.py +101 -0
  71. libcom/image_harmonization/source/src/lbm/models/lbm/lbm_model.py +359 -0
  72. libcom/image_harmonization/source/src/lbm/models/unets/__init__.py +14 -0
  73. libcom/image_harmonization/source/src/lbm/models/unets/unet.py +148 -0
  74. libcom/image_harmonization/source/src/lbm/models/utils.py +377 -0
  75. libcom/image_harmonization/source/src/lbm/models/vae/__init__.py +4 -0
  76. libcom/image_harmonization/source/src/lbm/models/vae/autoencoderKL.py +136 -0
  77. libcom/image_harmonization/source/src/lbm/models/vae/autoencoderKL_config.py +27 -0
  78. libcom/image_harmonization/source/src/lbm/trainer/__init__.py +85 -0
  79. libcom/image_harmonization/source/src/lbm/trainer/loggers.py +324 -0
  80. libcom/image_harmonization/source/src/lbm/trainer/trainer.py +199 -0
  81. libcom/image_harmonization/source/src/lbm/trainer/training_config.py +82 -0
  82. libcom/image_harmonization/source/src/lbm/trainer/utils.py +193 -0
  83. libcom/inharmonious_region_localization/__init__.py +4 -0
  84. libcom/inharmonious_region_localization/inharmonious_region_localization.py +97 -0
  85. libcom/inharmonious_region_localization/source/__init__.py +0 -0
  86. libcom/inharmonious_region_localization/source/blocks.py +368 -0
  87. libcom/inharmonious_region_localization/source/functions.py +679 -0
  88. libcom/inharmonious_region_localization/source/madis_net.py +79 -0
  89. libcom/kontext_blending_harmonization/__init__.py +3 -0
  90. libcom/kontext_blending_harmonization/kontext_blending_harmonization.py +148 -0
  91. libcom/kontext_blending_harmonization/source/__init__.py +0 -0
  92. libcom/kontext_blending_harmonization/source/pipeline.py +1135 -0
  93. libcom/naive_composition/__init__.py +3 -0
  94. libcom/naive_composition/generate_composite_image.py +116 -0
  95. libcom/opa_score/__init__.py +3 -0
  96. libcom/opa_score/opa_score_prediction.py +101 -0
  97. libcom/opa_score/source/__init__.py +3 -0
  98. libcom/opa_score/source/object_place_net.py +55 -0
  99. libcom/opa_score/source/oblect_place_config.py +66 -0
  100. libcom/opa_score/source/resnet_4ch.py +213 -0
  101. libcom/os_insert/__init__.py +3 -0
  102. libcom/os_insert/diffusers_osinsert/__init__.py +78 -0
  103. libcom/os_insert/diffusers_osinsert/_patched_pipeline_flux_fill.py +878 -0
  104. libcom/os_insert/os_insert.py +534 -0
  105. libcom/os_insert/source/__init__.py +1 -0
  106. libcom/os_insert/source/ia_utils.py +183 -0
  107. libcom/os_insert/source/insertanything_infer.py +529 -0
  108. libcom/os_insert/source/ldm/__init__.py +0 -0
  109. libcom/os_insert/source/ldm/data/__init__.py +0 -0
  110. libcom/os_insert/source/ldm/data/base.py +23 -0
  111. libcom/os_insert/source/ldm/data/datamodule.py +128 -0
  112. libcom/os_insert/source/ldm/data/imagenet.py +394 -0
  113. libcom/os_insert/source/ldm/data/lsun.py +92 -0
  114. libcom/os_insert/source/ldm/data/open_images.py +728 -0
  115. libcom/os_insert/source/ldm/lr_scheduler.py +98 -0
  116. libcom/os_insert/source/ldm/models/__init__.py +0 -0
  117. libcom/os_insert/source/ldm/models/autoencoder.py +443 -0
  118. libcom/os_insert/source/ldm/models/diffusion/__init__.py +0 -0
  119. libcom/os_insert/source/ldm/models/diffusion/classifier.py +267 -0
  120. libcom/os_insert/source/ldm/models/diffusion/ddim.py +263 -0
  121. libcom/os_insert/source/ldm/models/diffusion/ddpm.py +1417 -0
  122. libcom/os_insert/source/ldm/models/diffusion/plms.py +252 -0
  123. libcom/os_insert/source/ldm/modules/__init__.py +0 -0
  124. libcom/os_insert/source/ldm/modules/attention.py +261 -0
  125. libcom/os_insert/source/ldm/modules/diffusionmodules/__init__.py +0 -0
  126. libcom/os_insert/source/ldm/modules/diffusionmodules/model.py +835 -0
  127. libcom/os_insert/source/ldm/modules/diffusionmodules/openaimodel.py +1108 -0
  128. libcom/os_insert/source/ldm/modules/diffusionmodules/util.py +267 -0
  129. libcom/os_insert/source/ldm/modules/distributions/__init__.py +0 -0
  130. libcom/os_insert/source/ldm/modules/distributions/distributions.py +92 -0
  131. libcom/os_insert/source/ldm/modules/ema.py +76 -0
  132. libcom/os_insert/source/ldm/modules/encoders/__init__.py +0 -0
  133. libcom/os_insert/source/ldm/modules/encoders/modules.py +190 -0
  134. libcom/os_insert/source/ldm/modules/encoders/xf.py +130 -0
  135. libcom/os_insert/source/ldm/modules/losses/__init__.py +1 -0
  136. libcom/os_insert/source/ldm/modules/losses/contperceptual.py +111 -0
  137. libcom/os_insert/source/ldm/modules/losses/vqperceptual.py +167 -0
  138. libcom/os_insert/source/ldm/modules/x_transformer.py +641 -0
  139. libcom/os_insert/source/ldm/util.py +203 -0
  140. libcom/os_insert/source/objectstitch_data.py +66 -0
  141. libcom/os_insert/source/objectstitch_infer.py +618 -0
  142. libcom/os_insert/source/sam_on_objectstitch.py +253 -0
  143. libcom/os_insert/source/utils.py +41 -0
  144. libcom/os_insert/source/v1.yaml +108 -0
  145. libcom/painterly_image_harmonization/__init__.py +4 -0
  146. libcom/painterly_image_harmonization/painterly_image_harmonization.py +215 -0
  147. libcom/painterly_image_harmonization/source/PHDNet/__init__.py +0 -0
  148. libcom/painterly_image_harmonization/source/PHDNet/networks.py +202 -0
  149. libcom/painterly_image_harmonization/source/PHDNet/phdnet.py +47 -0
  150. libcom/painterly_image_harmonization/source/PHDNet/phdnet_config.py +18 -0
  151. libcom/painterly_image_harmonization/source/PHDiffusion/__init__.py +0 -0
  152. libcom/painterly_image_harmonization/source/PHDiffusion/ldm/__init__.py +0 -0
  153. libcom/painterly_image_harmonization/source/PHDiffusion/ldm/inference_base.py +300 -0
  154. libcom/painterly_image_harmonization/source/PHDiffusion/ldm/lr_scheduler.py +98 -0
  155. libcom/painterly_image_harmonization/source/PHDiffusion/ldm/models/__init__.py +0 -0
  156. libcom/painterly_image_harmonization/source/PHDiffusion/ldm/models/autoencoder.py +211 -0
  157. libcom/painterly_image_harmonization/source/PHDiffusion/ldm/models/diffusion/__init__.py +3 -0
  158. libcom/painterly_image_harmonization/source/PHDiffusion/ldm/models/diffusion/ddim.py +336 -0
  159. libcom/painterly_image_harmonization/source/PHDiffusion/ldm/models/diffusion/ddpm.py +1400 -0
  160. libcom/painterly_image_harmonization/source/PHDiffusion/ldm/models/diffusion/dpm_solver/__init__.py +1 -0
  161. libcom/painterly_image_harmonization/source/PHDiffusion/ldm/models/diffusion/dpm_solver/dpm_solver.py +1217 -0
  162. libcom/painterly_image_harmonization/source/PHDiffusion/ldm/models/diffusion/dpm_solver/sampler.py +87 -0
  163. libcom/painterly_image_harmonization/source/PHDiffusion/ldm/models/diffusion/plms.py +243 -0
  164. libcom/painterly_image_harmonization/source/PHDiffusion/ldm/models/diffusion/scheduling_pndm.py +518 -0
  165. libcom/painterly_image_harmonization/source/PHDiffusion/ldm/modules/__init__.py +0 -0
  166. libcom/painterly_image_harmonization/source/PHDiffusion/ldm/modules/attention.py +378 -0
  167. libcom/painterly_image_harmonization/source/PHDiffusion/ldm/modules/diffusionmodules/__init__.py +0 -0
  168. libcom/painterly_image_harmonization/source/PHDiffusion/ldm/modules/diffusionmodules/model.py +857 -0
  169. libcom/painterly_image_harmonization/source/PHDiffusion/ldm/modules/diffusionmodules/openaimodel.py +823 -0
  170. libcom/painterly_image_harmonization/source/PHDiffusion/ldm/modules/diffusionmodules/util.py +270 -0
  171. libcom/painterly_image_harmonization/source/PHDiffusion/ldm/modules/distributions/__init__.py +0 -0
  172. libcom/painterly_image_harmonization/source/PHDiffusion/ldm/modules/distributions/distributions.py +92 -0
  173. libcom/painterly_image_harmonization/source/PHDiffusion/ldm/modules/ema.py +80 -0
  174. libcom/painterly_image_harmonization/source/PHDiffusion/ldm/modules/encoders/__init__.py +0 -0
  175. libcom/painterly_image_harmonization/source/PHDiffusion/ldm/modules/encoders/adapter.py +213 -0
  176. libcom/painterly_image_harmonization/source/PHDiffusion/ldm/modules/encoders/modules.py +82 -0
  177. libcom/painterly_image_harmonization/source/PHDiffusion/ldm/modules/extra_condition/__init__.py +1 -0
  178. libcom/painterly_image_harmonization/source/PHDiffusion/ldm/modules/extra_condition/api.py +269 -0
  179. libcom/painterly_image_harmonization/source/PHDiffusion/ldm/modules/extra_condition/midas/__init__.py +0 -0
  180. libcom/painterly_image_harmonization/source/PHDiffusion/ldm/modules/extra_condition/midas/api.py +175 -0
  181. libcom/painterly_image_harmonization/source/PHDiffusion/ldm/modules/extra_condition/midas/midas/__init__.py +0 -0
  182. libcom/painterly_image_harmonization/source/PHDiffusion/ldm/modules/extra_condition/midas/midas/base_model.py +16 -0
  183. libcom/painterly_image_harmonization/source/PHDiffusion/ldm/modules/extra_condition/midas/midas/blocks.py +342 -0
  184. libcom/painterly_image_harmonization/source/PHDiffusion/ldm/modules/extra_condition/midas/midas/dpt_depth.py +109 -0
  185. libcom/painterly_image_harmonization/source/PHDiffusion/ldm/modules/extra_condition/midas/midas/midas_net.py +76 -0
  186. libcom/painterly_image_harmonization/source/PHDiffusion/ldm/modules/extra_condition/midas/midas/midas_net_custom.py +128 -0
  187. libcom/painterly_image_harmonization/source/PHDiffusion/ldm/modules/extra_condition/midas/midas/transforms.py +234 -0
  188. libcom/painterly_image_harmonization/source/PHDiffusion/ldm/modules/extra_condition/midas/midas/vit.py +491 -0
  189. libcom/painterly_image_harmonization/source/PHDiffusion/ldm/modules/extra_condition/midas/utils.py +189 -0
  190. libcom/painterly_image_harmonization/source/PHDiffusion/ldm/modules/extra_condition/model_edge.py +653 -0
  191. libcom/painterly_image_harmonization/source/PHDiffusion/ldm/modules/extra_condition/openpose/__init__.py +0 -0
  192. libcom/painterly_image_harmonization/source/PHDiffusion/ldm/modules/extra_condition/openpose/api.py +35 -0
  193. libcom/painterly_image_harmonization/source/PHDiffusion/ldm/modules/extra_condition/openpose/body.py +209 -0
  194. libcom/painterly_image_harmonization/source/PHDiffusion/ldm/modules/extra_condition/openpose/hand.py +75 -0
  195. libcom/painterly_image_harmonization/source/PHDiffusion/ldm/modules/extra_condition/openpose/model.py +178 -0
  196. libcom/painterly_image_harmonization/source/PHDiffusion/ldm/modules/extra_condition/openpose/util.py +203 -0
  197. libcom/painterly_image_harmonization/source/PHDiffusion/ldm/modules/extra_condition/utils.py +72 -0
  198. libcom/painterly_image_harmonization/source/PHDiffusion/ldm/modules/fusion/__init__.py +0 -0
  199. libcom/painterly_image_harmonization/source/PHDiffusion/ldm/modules/fusion/dual_encoder_fusion.py +93 -0
  200. libcom/painterly_image_harmonization/source/PHDiffusion/ldm/modules/image_degradation/__init__.py +2 -0
  201. libcom/painterly_image_harmonization/source/PHDiffusion/ldm/modules/image_degradation/bsrgan.py +730 -0
  202. libcom/painterly_image_harmonization/source/PHDiffusion/ldm/modules/image_degradation/bsrgan_light.py +651 -0
  203. libcom/painterly_image_harmonization/source/PHDiffusion/ldm/modules/image_degradation/utils_image.py +916 -0
  204. libcom/painterly_image_harmonization/source/PHDiffusion/ldm/util.py +200 -0
  205. libcom/painterly_image_harmonization/source/PHDiffusion/stable_diffusion.yaml +75 -0
  206. libcom/painterly_image_harmonization/source/__init__.py +0 -0
  207. libcom/reflection_generation/__init__.py +3 -0
  208. libcom/reflection_generation/reflection_generation.py +174 -0
  209. libcom/reflection_generation/source/PostProcessModel.py +513 -0
  210. libcom/reflection_generation/source/__init__.py +0 -0
  211. libcom/reflection_generation/source/cldm/__init__.py +0 -0
  212. libcom/reflection_generation/source/cldm/base_network.py +166 -0
  213. libcom/reflection_generation/source/cldm/cldm.py +509 -0
  214. libcom/reflection_generation/source/cldm/ddim_hacked.py +317 -0
  215. libcom/reflection_generation/source/cldm/hack.py +111 -0
  216. libcom/reflection_generation/source/cldm/logger.py +127 -0
  217. libcom/reflection_generation/source/cldm/model.py +26 -0
  218. libcom/reflection_generation/source/cldm_v15.yaml +81 -0
  219. libcom/reflection_generation/source/cluster_feature.py +109 -0
  220. libcom/reflection_generation/source/ldm/__init__.py +0 -0
  221. libcom/reflection_generation/source/ldm/models/__init__.py +0 -0
  222. libcom/reflection_generation/source/ldm/models/autoencoder.py +219 -0
  223. libcom/reflection_generation/source/ldm/models/diffusion/__init__.py +0 -0
  224. libcom/reflection_generation/source/ldm/models/diffusion/attention_processor.py +188 -0
  225. libcom/reflection_generation/source/ldm/models/diffusion/ddim.py +340 -0
  226. libcom/reflection_generation/source/ldm/models/diffusion/ddpm.py +1892 -0
  227. libcom/reflection_generation/source/ldm/models/diffusion/dpm_solver/__init__.py +1 -0
  228. libcom/reflection_generation/source/ldm/models/diffusion/dpm_solver/dpm_solver.py +1154 -0
  229. libcom/reflection_generation/source/ldm/models/diffusion/dpm_solver/sampler.py +87 -0
  230. libcom/reflection_generation/source/ldm/models/diffusion/ip_adapter.py +57 -0
  231. libcom/reflection_generation/source/ldm/models/diffusion/plms.py +244 -0
  232. libcom/reflection_generation/source/ldm/models/diffusion/sampling_util.py +22 -0
  233. libcom/reflection_generation/source/ldm/modules/__init__.py +0 -0
  234. libcom/reflection_generation/source/ldm/modules/attention.py +341 -0
  235. libcom/reflection_generation/source/ldm/modules/diffusionmodules/__init__.py +0 -0
  236. libcom/reflection_generation/source/ldm/modules/diffusionmodules/model.py +852 -0
  237. libcom/reflection_generation/source/ldm/modules/diffusionmodules/openaimodel.py +786 -0
  238. libcom/reflection_generation/source/ldm/modules/diffusionmodules/upscaling.py +81 -0
  239. libcom/reflection_generation/source/ldm/modules/diffusionmodules/util.py +280 -0
  240. libcom/reflection_generation/source/ldm/modules/distributions/__init__.py +0 -0
  241. libcom/reflection_generation/source/ldm/modules/distributions/distributions.py +92 -0
  242. libcom/reflection_generation/source/ldm/modules/ema.py +80 -0
  243. libcom/reflection_generation/source/ldm/modules/encoders/__init__.py +0 -0
  244. libcom/reflection_generation/source/ldm/modules/encoders/modules.py +214 -0
  245. libcom/reflection_generation/source/ldm/modules/image_degradation/__init__.py +0 -0
  246. libcom/reflection_generation/source/ldm/modules/image_degradation/bsrgan.py +730 -0
  247. libcom/reflection_generation/source/ldm/modules/image_degradation/bsrgan_light.py +651 -0
  248. libcom/reflection_generation/source/ldm/modules/image_degradation/utils_image.py +916 -0
  249. libcom/reflection_generation/source/ldm/util.py +198 -0
  250. libcom/reflection_generation/source/local_clip.py +749 -0
  251. libcom/reflection_generation/source/tool_add_control.py +49 -0
  252. libcom/shadow_generation/__init__.py +3 -0
  253. libcom/shadow_generation/shadow_generation.py +754 -0
  254. libcom/shadow_generation/source/PostProcessModel.py +511 -0
  255. libcom/shadow_generation/source/__init__.py +0 -0
  256. libcom/shadow_generation/source/attention_processor.py +234 -0
  257. libcom/shadow_generation/source/cldm/__init__.py +0 -0
  258. libcom/shadow_generation/source/cldm/base_network.py +166 -0
  259. libcom/shadow_generation/source/cldm/cldm.py +524 -0
  260. libcom/shadow_generation/source/cldm/model.py +28 -0
  261. libcom/shadow_generation/source/ldm/__init__.py +0 -0
  262. libcom/shadow_generation/source/ldm/models/__init__.py +0 -0
  263. libcom/shadow_generation/source/ldm/models/autoencoder.py +219 -0
  264. libcom/shadow_generation/source/ldm/models/diffusion/__init__.py +0 -0
  265. libcom/shadow_generation/source/ldm/models/diffusion/attention_processor.py +188 -0
  266. libcom/shadow_generation/source/ldm/models/diffusion/ddim.py +340 -0
  267. libcom/shadow_generation/source/ldm/models/diffusion/ddpm.py +1893 -0
  268. libcom/shadow_generation/source/ldm/models/diffusion/dpm_solver/__init__.py +1 -0
  269. libcom/shadow_generation/source/ldm/models/diffusion/dpm_solver/dpm_solver.py +1154 -0
  270. libcom/shadow_generation/source/ldm/models/diffusion/dpm_solver/sampler.py +87 -0
  271. libcom/shadow_generation/source/ldm/models/diffusion/ip_adapter.py +57 -0
  272. libcom/shadow_generation/source/ldm/models/diffusion/plms.py +244 -0
  273. libcom/shadow_generation/source/ldm/models/diffusion/sampling_util.py +22 -0
  274. libcom/shadow_generation/source/ldm/modules/__init__.py +0 -0
  275. libcom/shadow_generation/source/ldm/modules/attention.py +341 -0
  276. libcom/shadow_generation/source/ldm/modules/diffusionmodules/__init__.py +0 -0
  277. libcom/shadow_generation/source/ldm/modules/diffusionmodules/model.py +852 -0
  278. libcom/shadow_generation/source/ldm/modules/diffusionmodules/openaimodel.py +786 -0
  279. libcom/shadow_generation/source/ldm/modules/diffusionmodules/upscaling.py +81 -0
  280. libcom/shadow_generation/source/ldm/modules/diffusionmodules/util.py +270 -0
  281. libcom/shadow_generation/source/ldm/modules/distributions/__init__.py +0 -0
  282. libcom/shadow_generation/source/ldm/modules/distributions/distributions.py +92 -0
  283. libcom/shadow_generation/source/ldm/modules/ema.py +80 -0
  284. libcom/shadow_generation/source/ldm/modules/encoders/__init__.py +0 -0
  285. libcom/shadow_generation/source/ldm/modules/encoders/modules.py +214 -0
  286. libcom/shadow_generation/source/ldm/modules/image_degradation/__init__.py +2 -0
  287. libcom/shadow_generation/source/ldm/modules/image_degradation/bsrgan.py +730 -0
  288. libcom/shadow_generation/source/ldm/modules/image_degradation/bsrgan_light.py +651 -0
  289. libcom/shadow_generation/source/ldm/modules/image_degradation/utils_image.py +916 -0
  290. libcom/shadow_generation/source/ldm/modules/midas/__init__.py +0 -0
  291. libcom/shadow_generation/source/ldm/modules/midas/api.py +170 -0
  292. libcom/shadow_generation/source/ldm/modules/midas/midas/__init__.py +0 -0
  293. libcom/shadow_generation/source/ldm/modules/midas/midas/base_model.py +16 -0
  294. libcom/shadow_generation/source/ldm/modules/midas/midas/blocks.py +342 -0
  295. libcom/shadow_generation/source/ldm/modules/midas/midas/dpt_depth.py +109 -0
  296. libcom/shadow_generation/source/ldm/modules/midas/midas/midas_net.py +76 -0
  297. libcom/shadow_generation/source/ldm/modules/midas/midas/midas_net_custom.py +128 -0
  298. libcom/shadow_generation/source/ldm/modules/midas/midas/transforms.py +234 -0
  299. libcom/shadow_generation/source/ldm/modules/midas/midas/vit.py +491 -0
  300. libcom/shadow_generation/source/ldm/modules/midas/utils.py +189 -0
  301. libcom/shadow_generation/source/ldm/util.py +199 -0
  302. libcom/utils/__init__.py +0 -0
  303. libcom/utils/environment.py +12 -0
  304. libcom/utils/model_download.py +67 -0
  305. libcom/utils/process_image.py +108 -0
  306. libcom-0.1.8.dist-info/METADATA +157 -0
  307. libcom-0.1.8.dist-info/RECORD +310 -0
  308. libcom-0.1.8.dist-info/WHEEL +5 -0
  309. libcom-0.1.8.dist-info/licenses/LICENSE +201 -0
  310. libcom-0.1.8.dist-info/top_level.txt +1 -0
@@ -0,0 +1,618 @@
1
+ """ObjectStitch inference wrapper for OSInsert (skeleton).
2
+
3
+ This module is the libcom-style home for ObjectStitch inference. It is
4
+ responsible for taking a single sample (background, foreground, masks, bbox)
5
+ and producing a coarse composite image that will later be refined by SAM and
6
+ InsertAnything.
7
+
8
+ The actual network definition and weight loading will be implemented in a
9
+ later phase. For now this file only defines the public API so that
10
+ `OSInsertModel` can depend on a stable interface.
11
+ """
12
+
13
+ from __future__ import annotations
14
+
15
+ from dataclasses import dataclass
16
+ from pathlib import Path
17
+ from typing import Tuple
18
+
19
+ import importlib
20
+ import sys
21
+
22
+ import numpy as np
23
+ import torch
24
+ import torch.nn.functional as F
25
+ from omegaconf import OmegaConf
26
+ from PIL import Image
27
+ from torchvision.transforms import Resize
28
+
29
+ from .objectstitch_data import bbox2mask, get_bbox_tensor, get_tensor, get_tensor_clip
30
+
31
+ REPO_ROOT = Path(__file__).resolve().parents[3]
32
+ PRETRAINED_ROOT = REPO_ROOT / "pretrained_models" / "objectstitch"
33
+
34
+ from libcom.os_insert.source.ldm.models.diffusion.ddim import DDIMSampler
35
+
36
+
37
+ @dataclass
38
+ class ObjectStitchConfig:
39
+ """Configuration for ObjectStitch inference.
40
+
41
+ Parameters are intentionally minimal; more options can be added when we
42
+ hook up the real model implementation.
43
+ """
44
+
45
+ ckpt_path: Path = PRETRAINED_ROOT / "v1" / "model.ckpt"
46
+ config_path: Path = PRETRAINED_ROOT / "v1" / "configs" / "v1.yaml"
47
+ clip_dir: Path | None = None
48
+ device: str = "cuda:0"
49
+
50
+
51
+ def instantiate_from_config(config):
52
+ """Instantiate a module from an OmegaConf-style config.
53
+
54
+ This is a local copy of the utility used in ObjectStitch's ldm.util.
55
+ """
56
+
57
+ if "target" not in config:
58
+ if config in {"__is_first_stage__", "__is_unconditional__"}:
59
+ return None
60
+ raise KeyError("Expected key `target` to instantiate.")
61
+
62
+ def get_obj_from_str(string, reload=False):
63
+ module, cls = string.rsplit(".", 1)
64
+ # 确保使用本地的 ldm 模块
65
+ if module.startswith("ldm"):
66
+ # 使用绝对导入路径
67
+ local_module = f"libcom.os_insert.source.{module}"
68
+ if reload:
69
+ module_imp = importlib.import_module(local_module)
70
+ importlib.reload(module_imp)
71
+ return getattr(importlib.import_module(local_module, package=None), cls)
72
+ else:
73
+ # 其他模块使用标准导入
74
+ if reload:
75
+ module_imp = importlib.import_module(module)
76
+ importlib.reload(module_imp)
77
+ return getattr(importlib.import_module(module, package=None), cls)
78
+
79
+ return get_obj_from_str(config["target"])(**config.get("params", {}))
80
+
81
+
82
+ def load_model_from_config(cfg_path: Path, ckpt_path: Path, verbose: bool = False) -> torch.nn.Module:
83
+ """Load ObjectStitch model from config and checkpoint.
84
+
85
+ This mirrors the `load_model_from_config` helper in ObjectStitch's
86
+ `scripts/inference.py`, but is rooted in this repository's
87
+ `pretrained_models/objectstitch` directory.
88
+ """
89
+
90
+ cfg_path = Path(cfg_path)
91
+ ckpt_path = Path(ckpt_path)
92
+
93
+ if not cfg_path.exists():
94
+ raise FileNotFoundError(f"ObjectStitch config not found: {cfg_path}")
95
+ if not ckpt_path.exists():
96
+ raise FileNotFoundError(f"ObjectStitch checkpoint not found: {ckpt_path}")
97
+
98
+ print(f"[ObjectStitch] load config {cfg_path}")
99
+ config = OmegaConf.load(str(cfg_path))
100
+
101
+ print(f"[ObjectStitch] load checkpoint {ckpt_path}")
102
+ pl_sd = torch.load(str(ckpt_path), map_location="cpu")
103
+ sd = pl_sd["state_dict"] if "state_dict" in pl_sd else pl_sd
104
+
105
+ model = instantiate_from_config(config["model"])
106
+ missing, unexpected = model.load_state_dict(sd, strict=False)
107
+
108
+ if verbose:
109
+ if missing:
110
+ print("[ObjectStitch] missing keys:")
111
+ print(missing)
112
+ if unexpected:
113
+ print("[ObjectStitch] unexpected keys:")
114
+ print(unexpected)
115
+
116
+ model.eval()
117
+ return model
118
+
119
+
120
+ # ---------------------------------------------------------------------------
121
+ # Data transforms & helpers (ported from scripts/inference.py and
122
+ # ldm.data.open_images).
123
+ # ---------------------------------------------------------------------------
124
+
125
+ clip_transform = get_tensor_clip(image_size=(224, 224))
126
+ sd_transform = get_tensor(image_size=(512, 512))
127
+ mask_transform = get_tensor(normalize=False, image_size=(512, 512))
128
+
129
+
130
+ def clip2sd(x: torch.Tensor) -> torch.Tensor:
131
+ """Convert CLIP-normalized tensor to Stable Diffusion space.
132
+
133
+ Copied from ObjectStitch's `scripts/inference.py`.
134
+ """
135
+
136
+ mean = torch.tensor([0.48145466, 0.4578275, 0.40821073], dtype=torch.float32, device=x.device).view(1, -1, 1, 1)
137
+ std = torch.tensor([0.26862954, 0.26130258, 0.27577711], dtype=torch.float32, device=x.device).view(1, -1, 1, 1)
138
+ denorm = x * std + mean
139
+ sd_x = denorm * 2 - 1
140
+ return sd_x
141
+
142
+
143
+ def generate_image_batch(
144
+ bg_path: Path,
145
+ fg_path: Path,
146
+ bbox_xyxy: Tuple[int, int, int, int],
147
+ fg_mask_path: Path,
148
+ ) -> dict:
149
+ """Prepare a single-sample batch for ObjectStitch.
150
+
151
+ This is a slightly simplified version of `generate_image_batch` from
152
+ ObjectStitch's `scripts/inference.py`, fixed to always use bbox and fg_mask
153
+ (which matches the OSInsert aggressive pipeline).
154
+ """
155
+
156
+ bg_img = Image.open(bg_path).convert("RGB")
157
+ bg_w, bg_h = bg_img.size
158
+ bg_t = sd_transform(bg_img)
159
+
160
+ fg_img = Image.open(fg_path).convert("RGB")
161
+ fg_mask = Image.open(fg_mask_path).convert("RGB")
162
+ fg_mask = fg_mask.resize((fg_img.width, fg_img.height))
163
+
164
+ black = np.zeros_like(np.asarray(fg_mask))
165
+ fg_mask_np = np.asarray(fg_mask)
166
+ fg_img_np = np.asarray(fg_img)
167
+ fg_img_np = np.where(fg_mask_np > 127, fg_img_np, black)
168
+ fg_img = Image.fromarray(fg_img_np)
169
+
170
+ fg_t = clip_transform(fg_img)
171
+
172
+ mask_np = bbox2mask(bbox_xyxy, bg_w, bg_h)
173
+ mask = Image.fromarray(mask_np)
174
+ mask_t = mask_transform(mask)
175
+ mask_t = torch.where(mask_t > 0.5, 1, 0).float()
176
+
177
+ inpaint_t = bg_t * (1 - mask_t)
178
+ bbox_t = get_bbox_tensor(bbox_xyxy, bg_w, bg_h)
179
+
180
+ return {
181
+ "bg_img": inpaint_t.unsqueeze(0),
182
+ "bg_mask": mask_t.unsqueeze(0),
183
+ "fg_img": fg_t.unsqueeze(0),
184
+ "bbox": bbox_t.unsqueeze(0),
185
+ }
186
+
187
+
188
+ def _ensure_pil_rgb(image: np.ndarray | Image.Image) -> Image.Image:
189
+ if isinstance(image, Image.Image):
190
+ return image.convert("RGB")
191
+ if not isinstance(image, np.ndarray):
192
+ raise TypeError("Expected numpy array or PIL.Image")
193
+ if image.ndim != 3 or image.shape[2] != 3:
194
+ raise ValueError("Expected HxWx3 image")
195
+ return Image.fromarray(image.astype(np.uint8), mode="RGB")
196
+
197
+
198
+ def _ensure_mask_uint8(mask: np.ndarray | Image.Image) -> np.ndarray:
199
+ if isinstance(mask, Image.Image):
200
+ mask_np = np.asarray(mask)
201
+ elif isinstance(mask, np.ndarray):
202
+ mask_np = mask
203
+ else:
204
+ raise TypeError("Expected numpy array or PIL.Image for mask")
205
+
206
+ if mask_np.ndim == 3:
207
+ mask_np = mask_np[:, :, 0]
208
+ if mask_np.ndim != 2:
209
+ raise ValueError("Expected HxW mask")
210
+ return mask_np.astype(np.uint8)
211
+
212
+
213
+ def generate_image_batch_from_images(
214
+ bg_image: np.ndarray | Image.Image,
215
+ fg_image: np.ndarray | Image.Image,
216
+ bbox_xyxy: Tuple[int, int, int, int],
217
+ fg_mask: np.ndarray | Image.Image,
218
+ ) -> dict:
219
+ """In-memory version of :func:`generate_image_batch`.
220
+
221
+ Parameters are identical in semantics, but accept already-loaded images.
222
+ """
223
+
224
+ bg_img = _ensure_pil_rgb(bg_image)
225
+ bg_w, bg_h = bg_img.size
226
+ bg_t = sd_transform(bg_img)
227
+
228
+ fg_img = _ensure_pil_rgb(fg_image)
229
+ fg_mask_np = _ensure_mask_uint8(fg_mask)
230
+
231
+ if fg_mask_np.shape[0] != fg_img.height or fg_mask_np.shape[1] != fg_img.width:
232
+ fg_mask_pil = Image.fromarray(fg_mask_np)
233
+ fg_mask_pil = fg_mask_pil.resize((fg_img.width, fg_img.height))
234
+ fg_mask_np = np.asarray(fg_mask_pil).astype(np.uint8)
235
+
236
+ black = np.zeros((fg_img.height, fg_img.width, 3), dtype=np.uint8)
237
+ fg_img_np = np.asarray(fg_img).astype(np.uint8)
238
+ fg_img_np = np.where(fg_mask_np[:, :, None] > 127, fg_img_np, black)
239
+ fg_img = Image.fromarray(fg_img_np)
240
+
241
+ fg_t = clip_transform(fg_img)
242
+
243
+ mask_np = bbox2mask(bbox_xyxy, bg_w, bg_h)
244
+ mask = Image.fromarray(mask_np)
245
+ mask_t = mask_transform(mask)
246
+ mask_t = torch.where(mask_t > 0.5, 1, 0).float()
247
+
248
+ inpaint_t = bg_t * (1 - mask_t)
249
+ bbox_t = get_bbox_tensor(bbox_xyxy, bg_w, bg_h)
250
+
251
+ return {
252
+ "bg_img": inpaint_t.unsqueeze(0),
253
+ "bg_mask": mask_t.unsqueeze(0),
254
+ "fg_img": fg_t.unsqueeze(0),
255
+ "bbox": bbox_t.unsqueeze(0),
256
+ }
257
+
258
+
259
+ def prepare_input(
260
+ batch: dict,
261
+ model: torch.nn.Module,
262
+ latent_shape: Tuple[int, int, int],
263
+ device: torch.device,
264
+ num_samples: int = 1,
265
+ ):
266
+ """Prepare model kwargs and conditioning vectors for sampling.
267
+
268
+ Port of ObjectStitch's `prepare_input` function, adapted to our config.
269
+ """
270
+
271
+ if num_samples > 1:
272
+ for k, v in batch.items():
273
+ if isinstance(v, torch.Tensor):
274
+ batch[k] = torch.cat([v] * num_samples, dim=0)
275
+
276
+ test_model_kwargs: dict = {}
277
+
278
+ bg_img = batch["bg_img"].to(device)
279
+ bg_latent = model.encode_first_stage(bg_img)
280
+ bg_latent = model.get_first_stage_encoding(bg_latent).detach()
281
+ test_model_kwargs["bg_latent"] = bg_latent
282
+
283
+ rs_mask = F.interpolate(batch["bg_mask"].to(device), latent_shape[-2:])
284
+ rs_mask = torch.where(rs_mask > 0.5, 1.0, 0.0)
285
+ test_model_kwargs["bg_mask"] = rs_mask
286
+
287
+ test_model_kwargs["bbox"] = batch["bbox"].to(device)
288
+
289
+ fg_tensor = batch["fg_img"].to(device)
290
+ c = model.get_learned_conditioning(fg_tensor)
291
+ c = model.proj_out(c)
292
+ uc = model.learnable_vector.repeat(c.shape[0], c.shape[1], 1)
293
+
294
+ return test_model_kwargs, c, uc
295
+
296
+
297
+ def tensor2numpy(image: torch.Tensor, normalized: bool = False, image_size: Tuple[int, int] = (512, 512)) -> np.ndarray:
298
+ """Convert a BCHW tensor in [-1,1] or [0,1] to uint8 numpy images.
299
+
300
+ Port of ObjectStitch's `tensor2numpy` utility.
301
+ """
302
+
303
+ image = Resize(image_size, antialias=True)(image)
304
+ if not normalized:
305
+ image = (image + 1.0) / 2.0
306
+ image = torch.clamp(image, 0.0, 1.0)
307
+ if image.dim() == 3:
308
+ image = image.unsqueeze(0)
309
+ image = image.permute(0, 2, 3, 1)
310
+ image = image.detach().cpu().numpy()
311
+ image = (image * 255).astype(np.uint8)
312
+ return image
313
+
314
+
315
+ def run_objectstitch_single(
316
+ bg_path: Path,
317
+ fg_path: Path,
318
+ fg_mask_path: Path,
319
+ bbox_xyxy: Tuple[int, int, int, int],
320
+ *,
321
+ config: ObjectStitchConfig,
322
+ out_dir: Path | None = None,
323
+ seed: int | None = None,
324
+ ) -> Path:
325
+ """Run ObjectStitch for a single sample and return the coarse composite path.
326
+
327
+ This wraps the original ObjectStitch `scripts/inference.py` logic into a
328
+ single-call API for OSInsert aggressive mode.
329
+ """
330
+
331
+ if out_dir is None:
332
+ out_dir = bg_path.parent
333
+ out_dir = Path(out_dir)
334
+ out_dir.mkdir(parents=True, exist_ok=True)
335
+
336
+ # Load OmegaConf config and patch CLIP path to local directory if present.
337
+ cfg = OmegaConf.load(str(config.config_path))
338
+ clip_dir = config.clip_dir
339
+ if clip_dir is None:
340
+ clip_dir = config.config_path.parent / "openai-clip-vit-large-patch14"
341
+ if not clip_dir.exists():
342
+ clip_dir = config.ckpt_path.parent / "openai-clip-vit-large-patch14"
343
+ if clip_dir is not None and Path(clip_dir).exists():
344
+ cfg.model.params.cond_stage_config.params.version = str(clip_dir)
345
+
346
+ # Instantiate model and sampler.
347
+ model = instantiate_from_config(cfg["model"])
348
+ pl_sd = torch.load(str(config.ckpt_path), map_location="cpu")
349
+ sd = pl_sd["state_dict"] if "state_dict" in pl_sd else pl_sd
350
+ missing, unexpected = model.load_state_dict(sd, strict=False)
351
+ if missing:
352
+ print("[ObjectStitch] missing keys:", missing)
353
+ if unexpected:
354
+ print("[ObjectStitch] unexpected keys:", unexpected)
355
+
356
+ device = torch.device(config.device)
357
+ model = model.to(device)
358
+
359
+ img_size = (512, 512)
360
+ latent_shape = (4, img_size[1] // 8, img_size[0] // 8)
361
+ sample_steps = 50
362
+ num_samples = 1
363
+ guidance_scale = 5.0
364
+
365
+ sampler = DDIMSampler(model)
366
+
367
+ if seed is not None:
368
+ torch.manual_seed(int(seed))
369
+ if device.type == "cuda":
370
+ torch.cuda.manual_seed_all(int(seed))
371
+
372
+ start_code = torch.randn((num_samples, *latent_shape), device=device)
373
+
374
+ batch = generate_image_batch(bg_path, fg_path, bbox_xyxy, fg_mask_path)
375
+ test_model_kwargs, c, uc = prepare_input(batch, model, latent_shape, device, num_samples)
376
+
377
+ samples_ddim, _ = sampler.sample(
378
+ S=sample_steps,
379
+ conditioning=c,
380
+ batch_size=num_samples,
381
+ shape=list(latent_shape),
382
+ verbose=False,
383
+ eta=0.0,
384
+ x_T=start_code,
385
+ unconditional_guidance_scale=guidance_scale,
386
+ unconditional_conditioning=uc,
387
+ test_model_kwargs=test_model_kwargs,
388
+ )
389
+
390
+ x_samples_ddim = model.decode_first_stage(samples_ddim[:, :4]).cpu().float()
391
+ comp_img = tensor2numpy(x_samples_ddim, image_size=img_size)
392
+ out_path = out_dir / "objectstitch_coarse.png"
393
+ Image.fromarray(comp_img[0]).save(out_path)
394
+
395
+ return out_path
396
+
397
+
398
+ def run_objectstitch_single_image(
399
+ bg_path: Path,
400
+ fg_path: Path,
401
+ fg_mask_path: Path,
402
+ bbox_xyxy: Tuple[int, int, int, int],
403
+ *,
404
+ config: ObjectStitchConfig,
405
+ seed: int | None = None,
406
+ ) -> np.ndarray:
407
+ """Run ObjectStitch for a single sample and return the coarse composite image (RGB uint8)."""
408
+
409
+ # Load OmegaConf config and patch CLIP path to local directory if present.
410
+ cfg = OmegaConf.load(str(config.config_path))
411
+ clip_dir = config.clip_dir
412
+ if clip_dir is None:
413
+ clip_dir = config.config_path.parent / "openai-clip-vit-large-patch14"
414
+ if not clip_dir.exists():
415
+ clip_dir = config.ckpt_path.parent / "openai-clip-vit-large-patch14"
416
+ if clip_dir is not None and Path(clip_dir).exists():
417
+ cfg.model.params.cond_stage_config.params.version = str(clip_dir)
418
+
419
+ model = instantiate_from_config(cfg["model"])
420
+ pl_sd = torch.load(str(config.ckpt_path), map_location="cpu")
421
+ sd = pl_sd["state_dict"] if "state_dict" in pl_sd else pl_sd
422
+ missing, unexpected = model.load_state_dict(sd, strict=False)
423
+ if missing:
424
+ print("[ObjectStitch] missing keys:", missing)
425
+ if unexpected:
426
+ print("[ObjectStitch] unexpected keys:", unexpected)
427
+
428
+ device = torch.device(config.device)
429
+ model = model.to(device)
430
+ model.eval()
431
+
432
+ img_size = (512, 512)
433
+ latent_shape = (4, img_size[1] // 8, img_size[0] // 8)
434
+ sample_steps = 50
435
+ num_samples = 1
436
+ guidance_scale = 5.0
437
+
438
+ sampler = DDIMSampler(model)
439
+
440
+ if seed is not None:
441
+ torch.manual_seed(int(seed))
442
+ if device.type == "cuda":
443
+ torch.cuda.manual_seed_all(int(seed))
444
+ start_code = torch.randn((num_samples, *latent_shape), device=device)
445
+
446
+ batch = generate_image_batch(bg_path, fg_path, bbox_xyxy, fg_mask_path)
447
+ test_model_kwargs, c, uc = prepare_input(batch, model, latent_shape, device, num_samples)
448
+
449
+ samples_ddim, _ = sampler.sample(
450
+ S=sample_steps,
451
+ conditioning=c,
452
+ batch_size=num_samples,
453
+ shape=list(latent_shape),
454
+ verbose=False,
455
+ eta=0.0,
456
+ x_T=start_code,
457
+ unconditional_guidance_scale=guidance_scale,
458
+ unconditional_conditioning=uc,
459
+ test_model_kwargs=test_model_kwargs,
460
+ )
461
+
462
+ x_samples_ddim = model.decode_first_stage(samples_ddim[:, :4]).cpu().float()
463
+ comp_img = tensor2numpy(x_samples_ddim, image_size=img_size)
464
+ return comp_img[0]
465
+
466
+
467
+ def load_objectstitch_model_and_sampler(*, config: ObjectStitchConfig) -> tuple[torch.nn.Module, DDIMSampler]:
468
+ """Load ObjectStitch model + sampler once.
469
+
470
+ The returned model is moved to ``config.device`` and set to ``eval()``.
471
+ """
472
+
473
+ cfg = OmegaConf.load(str(config.config_path))
474
+ clip_dir = config.clip_dir
475
+ if clip_dir is None:
476
+ clip_dir = config.config_path.parent / "openai-clip-vit-large-patch14"
477
+ if not clip_dir.exists():
478
+ clip_dir = config.ckpt_path.parent / "openai-clip-vit-large-patch14"
479
+ if clip_dir is not None and Path(clip_dir).exists():
480
+ cfg.model.params.cond_stage_config.params.version = str(clip_dir)
481
+
482
+ model = instantiate_from_config(cfg["model"])
483
+ pl_sd = torch.load(str(config.ckpt_path), map_location="cpu")
484
+ sd = pl_sd["state_dict"] if "state_dict" in pl_sd else pl_sd
485
+ missing, unexpected = model.load_state_dict(sd, strict=False)
486
+ if missing:
487
+ print("[ObjectStitch] missing keys:", missing)
488
+ if unexpected:
489
+ print("[ObjectStitch] unexpected keys:", unexpected)
490
+
491
+ device = torch.device(config.device)
492
+ model = model.to(device)
493
+ model.eval()
494
+
495
+ sampler = DDIMSampler(model)
496
+ return model, sampler
497
+
498
+
499
+ def run_objectstitch_single_image_from_images_cached(
500
+ *,
501
+ background: np.ndarray | Image.Image,
502
+ foreground: np.ndarray | Image.Image,
503
+ foreground_mask: np.ndarray | Image.Image,
504
+ bbox_xyxy: Tuple[int, int, int, int],
505
+ model: torch.nn.Module,
506
+ sampler: DDIMSampler,
507
+ device: str | torch.device,
508
+ seed: int | None = None,
509
+ split_steps: int = 50,
510
+ ) -> np.ndarray:
511
+ """Cached in-memory ObjectStitch inference.
512
+
513
+ This avoids re-loading weights for every call.
514
+ """
515
+
516
+ img_size = (512, 512)
517
+ latent_shape = (4, img_size[1] // 8, img_size[0] // 8)
518
+ num_samples = 1
519
+ guidance_scale = 5.0
520
+
521
+ device_t = torch.device(device)
522
+
523
+ if seed is not None:
524
+ torch.manual_seed(int(seed))
525
+ if device_t.type == "cuda":
526
+ torch.cuda.manual_seed_all(int(seed))
527
+ start_code = torch.randn((num_samples, *latent_shape), device=device_t)
528
+
529
+ batch = generate_image_batch_from_images(background, foreground, bbox_xyxy, foreground_mask)
530
+ test_model_kwargs, c, uc = prepare_input(batch, model, latent_shape, device_t, num_samples)
531
+
532
+ samples_ddim, _ = sampler.sample(
533
+ S=int(split_steps),
534
+ conditioning=c,
535
+ batch_size=num_samples,
536
+ shape=list(latent_shape),
537
+ verbose=False,
538
+ eta=0.0,
539
+ x_T=start_code,
540
+ unconditional_guidance_scale=guidance_scale,
541
+ unconditional_conditioning=uc,
542
+ test_model_kwargs=test_model_kwargs,
543
+ )
544
+
545
+ x_samples_ddim = model.decode_first_stage(samples_ddim[:, :4]).cpu().float()
546
+ comp_img = tensor2numpy(x_samples_ddim, image_size=img_size)
547
+ return comp_img[0]
548
+
549
+
550
+ def run_objectstitch_single_image_from_images(
551
+ *,
552
+ background: np.ndarray | Image.Image,
553
+ foreground: np.ndarray | Image.Image,
554
+ foreground_mask: np.ndarray | Image.Image,
555
+ bbox_xyxy: Tuple[int, int, int, int],
556
+ config: ObjectStitchConfig,
557
+ seed: int | None = None,
558
+ ) -> np.ndarray:
559
+ """Run ObjectStitch for a single sample and return the coarse composite image (RGB uint8).
560
+
561
+ This is the in-memory variant of :func:`run_objectstitch_single_image`.
562
+ """
563
+
564
+ cfg = OmegaConf.load(str(config.config_path))
565
+ clip_dir = config.clip_dir
566
+ if clip_dir is None:
567
+ clip_dir = config.config_path.parent / "openai-clip-vit-large-patch14"
568
+ if not clip_dir.exists():
569
+ clip_dir = config.ckpt_path.parent / "openai-clip-vit-large-patch14"
570
+ if clip_dir is not None and Path(clip_dir).exists():
571
+ cfg.model.params.cond_stage_config.params.version = str(clip_dir)
572
+
573
+ model = instantiate_from_config(cfg["model"])
574
+ pl_sd = torch.load(str(config.ckpt_path), map_location="cpu")
575
+ sd = pl_sd["state_dict"] if "state_dict" in pl_sd else pl_sd
576
+ missing, unexpected = model.load_state_dict(sd, strict=False)
577
+ if missing:
578
+ print("[ObjectStitch] missing keys:", missing)
579
+ if unexpected:
580
+ print("[ObjectStitch] unexpected keys:", unexpected)
581
+
582
+ device = torch.device(config.device)
583
+ model = model.to(device)
584
+ model.eval()
585
+
586
+ img_size = (512, 512)
587
+ latent_shape = (4, img_size[1] // 8, img_size[0] // 8)
588
+ sample_steps = 50
589
+ num_samples = 1
590
+ guidance_scale = 5.0
591
+
592
+ sampler = DDIMSampler(model)
593
+
594
+ if seed is not None:
595
+ torch.manual_seed(int(seed))
596
+ if device.type == "cuda":
597
+ torch.cuda.manual_seed_all(int(seed))
598
+ start_code = torch.randn((num_samples, *latent_shape), device=device)
599
+
600
+ batch = generate_image_batch_from_images(background, foreground, bbox_xyxy, foreground_mask)
601
+ test_model_kwargs, c, uc = prepare_input(batch, model, latent_shape, device, num_samples)
602
+
603
+ samples_ddim, _ = sampler.sample(
604
+ S=sample_steps,
605
+ conditioning=c,
606
+ batch_size=num_samples,
607
+ shape=list(latent_shape),
608
+ verbose=False,
609
+ eta=0.0,
610
+ x_T=start_code,
611
+ unconditional_guidance_scale=guidance_scale,
612
+ unconditional_conditioning=uc,
613
+ test_model_kwargs=test_model_kwargs,
614
+ )
615
+
616
+ x_samples_ddim = model.decode_first_stage(samples_ddim[:, :4]).cpu().float()
617
+ comp_img = tensor2numpy(x_samples_ddim, image_size=img_size)
618
+ return comp_img[0]