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,183 @@
1
+ """Local reimplementation of InsertAnything utility functions.
2
+
3
+ Moved from `osinsert/ia_utils.py` so that all OSInsert logic lives under
4
+ `libcom/os_insert` and does not depend on external repositories.
5
+ """
6
+
7
+ from __future__ import annotations
8
+
9
+ from typing import Tuple
10
+
11
+ import cv2
12
+ import numpy as np
13
+ import math
14
+
15
+
16
+ def get_bbox_from_mask(mask: np.ndarray) -> Tuple[int, int, int, int]:
17
+ """Get (y1, y2, x1, x2) bounding box from a binary mask.
18
+
19
+ This mirrors the original InsertAnything implementation: when the mask is
20
+ nearly empty, fall back to the full image.
21
+ """
22
+
23
+ h, w = mask.shape[:2]
24
+
25
+ if mask.sum() < 10:
26
+ return 0, h, 0, w
27
+
28
+ rows = np.any(mask, axis=1)
29
+ cols = np.any(mask, axis=0)
30
+ y1, y2 = np.where(rows)[0][[0, -1]]
31
+ x1, x2 = np.where(cols)[0][[0, -1]]
32
+ return int(y1), int(y2), int(x1), int(x2)
33
+
34
+
35
+ def expand_bbox(mask: np.ndarray, yyxx, ratio: float, min_crop: int = 0):
36
+ """Expand a bbox using the same heuristic as the original repo.
37
+
38
+ `mask` is only used for its shape; the expansion ratio is adapted based on
39
+ the relative area of the bbox.
40
+ """
41
+
42
+ y1, y2, x1, x2 = yyxx
43
+ H, W = mask.shape[0], mask.shape[1]
44
+
45
+ yyxx_area = (y2 - y1 + 1) * (x2 - x1 + 1)
46
+ r1 = yyxx_area / (H * W)
47
+
48
+ def _f(r, T=0.6, beta=0.1):
49
+ return np.where(r < T, beta + (1 - beta) / T * r, 1)
50
+
51
+ r2 = _f(r1)
52
+ ratio = math.sqrt(r2 / r1)
53
+
54
+ xc, yc = 0.5 * (x1 + x2), 0.5 * (y1 + y2)
55
+ h = ratio * (y2 - y1 + 1)
56
+ w = ratio * (x2 - x1 + 1)
57
+ h = max(h, min_crop)
58
+ w = max(w, min_crop)
59
+
60
+ x1 = int(xc - w * 0.5)
61
+ x2 = int(xc + w * 0.5)
62
+ y1 = int(yc - h * 0.5)
63
+ y2 = int(yc + h * 0.5)
64
+
65
+ x1 = max(0, x1)
66
+ x2 = min(W, x2)
67
+ y1 = max(0, y1)
68
+ y2 = min(H, y2)
69
+ return int(y1), int(y2), int(x1), int(x2)
70
+
71
+
72
+ def pad_to_square(image: np.ndarray, pad_value: int = 255, random: bool = False) -> np.ndarray:
73
+ """Pad to square using the original InsertAnything convention.
74
+
75
+ Only the shorter side is padded, and padding is applied with `np.pad`.
76
+ """
77
+
78
+ H, W = image.shape[0], image.shape[1]
79
+ if H == W:
80
+ return image
81
+
82
+ padd = abs(H - W)
83
+ if random:
84
+ padd_1 = int(np.random.randint(0, padd))
85
+ else:
86
+ padd_1 = int(padd / 2)
87
+ padd_2 = padd - padd_1
88
+
89
+ if image.ndim == 2:
90
+ if H > W:
91
+ pad_param = ((0, 0), (padd_1, padd_2))
92
+ else:
93
+ pad_param = ((padd_1, padd_2), (0, 0))
94
+ else:
95
+ if H > W:
96
+ pad_param = ((0, 0), (padd_1, padd_2), (0, 0))
97
+ else:
98
+ pad_param = ((padd_1, padd_2), (0, 0), (0, 0))
99
+
100
+ image = np.pad(image, pad_param, "constant", constant_values=pad_value)
101
+ return image
102
+
103
+
104
+ def box2squre(image: np.ndarray, box) -> Tuple[int, int, int, int]: # spelling kept for compatibility
105
+ """Convert a bbox to square, matching the original InsertAnything logic."""
106
+
107
+ H, W = image.shape[0], image.shape[1]
108
+ y1, y2, x1, x2 = box
109
+ cx = (x1 + x2) // 2
110
+ cy = (y1 + y2) // 2
111
+ h = y2 - y1
112
+ w = x2 - x1
113
+
114
+ if h >= w:
115
+ x1 = cx - h // 2
116
+ x2 = cx + h // 2
117
+ else:
118
+ y1 = cy - w // 2
119
+ y2 = cy + w // 2
120
+ x1 = max(0, x1)
121
+ x2 = min(W, x2)
122
+ y1 = max(0, y1)
123
+ y2 = min(H, y2)
124
+ return int(y1), int(y2), int(x1), int(x2)
125
+
126
+
127
+ def crop_back(edited: np.ndarray, old_tar: np.ndarray, hw_vec, box_crop) -> np.ndarray:
128
+ """Paste the edited crop back into the original target image.
129
+
130
+ This is a faithful port of the original InsertAnything geometry, including
131
+ margin and de-padding logic. It is used by both conservative and
132
+ aggressive modes so they share identical edge behavior.
133
+ """
134
+
135
+ H1, W1, H2, W2 = map(int, hw_vec)
136
+ y1, y2, x1, x2 = map(int, box_crop)
137
+
138
+ # Resize prediction back to the padded crop size.
139
+ pred = cv2.resize(edited, (W2, H2))
140
+ m = 2 # margin pixels
141
+
142
+ # Case 1: original crop was square, simple margin paste.
143
+ if W1 == H1:
144
+ if m != 0:
145
+ old_tar[y1 + m : y2 - m, x1 + m : x2 - m, :] = pred[m:-m, m:-m]
146
+ else:
147
+ old_tar[y1:y2, x1:x2, :] = pred[:, :]
148
+ return old_tar
149
+
150
+ # Case 2: handle padding introduced by pad_to_square along one dimension.
151
+ if W1 < W2:
152
+ pad1 = int((W2 - W1) / 2)
153
+ pad2 = W2 - W1 - pad1
154
+ pred = pred[:, pad1:-pad2, :]
155
+ else:
156
+ pad1 = int((H2 - H1) / 2)
157
+ pad2 = H2 - H1 - pad1
158
+ pred = pred[pad1:-pad2, :, :]
159
+
160
+ gen_image = old_tar.copy()
161
+ if m != 0:
162
+ gen_image[y1 + m : y2 - m, x1 + m : x2 - m, :] = pred[m:-m, m:-m]
163
+ else:
164
+ gen_image[y1:y2, x1:x2, :] = pred[:, :]
165
+
166
+ return gen_image
167
+
168
+
169
+ def expand_image_mask(image: np.ndarray, mask: np.ndarray, ratio: float = 1.4):
170
+ """Expand image and mask by symmetric padding (original behavior)."""
171
+
172
+ h, w = image.shape[0], image.shape[1]
173
+ H, W = int(h * ratio), int(w * ratio)
174
+ h1 = int((H - h) // 2)
175
+ h2 = H - h - h1
176
+ w1 = int((W - w) // 2)
177
+ w2 = W - w - w1
178
+
179
+ pad_param_image = ((h1, h2), (w1, w2), (0, 0))
180
+ pad_param_mask = ((h1, h2), (w1, w2))
181
+ image = np.pad(image, pad_param_image, "constant", constant_values=255)
182
+ mask = np.pad(mask, pad_param_mask, "constant", constant_values=0)
183
+ return image, mask
@@ -0,0 +1,529 @@
1
+ from __future__ import annotations
2
+
3
+ from pathlib import Path
4
+
5
+ import argparse
6
+ import os
7
+
8
+ import cv2
9
+ import numpy as np
10
+ import torch
11
+ from PIL import Image
12
+ from diffusers import FluxFillPipeline, FluxPriorReduxPipeline
13
+
14
+ from libcom.utils.model_download import download_pretrained_model
15
+ from .ia_utils import (
16
+ get_bbox_from_mask,
17
+ expand_bbox,
18
+ pad_to_square,
19
+ box2squre,
20
+ crop_back,
21
+ expand_image_mask,
22
+ )
23
+
24
+ dtype = torch.bfloat16
25
+ size = (768, 768)
26
+
27
+
28
+ # ---------------------------------------------------------------------------
29
+ # 模型路径:对齐 libcom 的 `pretrained_models/` 目录约定。
30
+ # ---------------------------------------------------------------------------
31
+
32
+ _PIPE: FluxFillPipeline | None = None
33
+ _REDUX: FluxPriorReduxPipeline | None = None
34
+ _PIPE_KEY: tuple[str, str, str, str] | None = None
35
+
36
+
37
+ def _resolve_ia_paths(
38
+ model_dir: str | Path | None,
39
+ *,
40
+ flux_fill_path: str | Path | None = None,
41
+ flux_redux_path: str | Path | None = None,
42
+ ia_lora_path: str | Path | None = None,
43
+ ):
44
+ if model_dir is None:
45
+ base = None
46
+ else:
47
+ base = Path(model_dir)
48
+
49
+ # Priority: explicit args > env vars > model_dir convention
50
+ flux_fill = str(flux_fill_path) if flux_fill_path is not None else os.getenv("FLUX_FILL_PATH")
51
+ flux_redux = str(flux_redux_path) if flux_redux_path is not None else os.getenv("FLUX_REDUX_PATH")
52
+ ia_lora = str(ia_lora_path) if ia_lora_path is not None else os.getenv("IA_LORA_PATH")
53
+
54
+ if flux_fill is None:
55
+ # 使用 HuggingFace 上的公有模型
56
+ flux_fill = "black-forest-labs/FLUX.1-Fill-dev"
57
+ if flux_redux is None:
58
+ # 使用 HuggingFace 上的公有模型
59
+ flux_redux = "black-forest-labs/FLUX.1-Redux-dev"
60
+ if ia_lora is None:
61
+ if base is None:
62
+ raise ValueError("model_dir must be provided when IA_LORA_PATH is not set")
63
+ ia_lora = str(base / "pretrained_models" / "insert_anything_lora.safetensors")
64
+ # 下载 LoRA 权重
65
+ download_pretrained_model(ia_lora)
66
+
67
+ return Path(flux_fill), Path(flux_redux), Path(ia_lora)
68
+
69
+
70
+ def _get_pipes(
71
+ model_dir: str | Path | None,
72
+ *,
73
+ flux_fill_path: str | Path | None = None,
74
+ flux_redux_path: str | Path | None = None,
75
+ ia_lora_path: str | Path | None = None,
76
+ device: str | torch.device | None = None,
77
+ ):
78
+ global _PIPE, _REDUX, _PIPE_KEY
79
+
80
+ if device is not None and not isinstance(device, torch.device):
81
+ device = torch.device(device)
82
+
83
+ flux_fill_path, flux_redux_path, ia_lora_path = _resolve_ia_paths(
84
+ model_dir,
85
+ flux_fill_path=flux_fill_path,
86
+ flux_redux_path=flux_redux_path,
87
+ ia_lora_path=ia_lora_path,
88
+ )
89
+ device_key = str(device) if device is not None else "<diffusers_default>"
90
+ key = (str(flux_fill_path), str(flux_redux_path), str(ia_lora_path), device_key)
91
+
92
+ if _PIPE is not None and _REDUX is not None and _PIPE_KEY == key:
93
+ return _PIPE, _REDUX
94
+
95
+ pipe = FluxFillPipeline.from_pretrained(
96
+ str(flux_fill_path),
97
+ torch_dtype=dtype,
98
+ )
99
+ pipe.load_lora_weights(str(ia_lora_path))
100
+ redux = FluxPriorReduxPipeline.from_pretrained(str(flux_redux_path)).to(dtype=dtype)
101
+
102
+ # Prefer explicit device. If device is None, fall back to diffusers defaults.
103
+ if device is None:
104
+ pipe.enable_model_cpu_offload()
105
+ redux.enable_model_cpu_offload()
106
+ pipe.enable_vae_slicing()
107
+ elif device.type == "cuda":
108
+ gpu_id = int(device.index or 0)
109
+ pipe.enable_model_cpu_offload(gpu_id=gpu_id)
110
+ redux.enable_model_cpu_offload(gpu_id=gpu_id)
111
+ pipe.enable_vae_slicing()
112
+ else:
113
+ # CPU mode: keep everything on CPU.
114
+ pipe.to(device)
115
+ redux.to(device)
116
+
117
+ _PIPE = pipe
118
+ _REDUX = redux
119
+ _PIPE_KEY = key
120
+ return pipe, redux
121
+
122
+
123
+
124
+ def _to_rgb_numpy(image: str | Path | np.ndarray | Image.Image) -> np.ndarray:
125
+ if isinstance(image, (str, Path)):
126
+ bgr = cv2.imread(str(image))
127
+ if bgr is None:
128
+ raise FileNotFoundError(str(image))
129
+ return cv2.cvtColor(bgr, cv2.COLOR_BGR2RGB)
130
+ if isinstance(image, Image.Image):
131
+ arr = np.array(image)
132
+ if arr.ndim != 3 or arr.shape[2] != 3:
133
+ raise ValueError("Expected RGB PIL image")
134
+ return arr
135
+ if isinstance(image, np.ndarray):
136
+ if image.ndim != 3 or image.shape[2] != 3:
137
+ raise ValueError("Expected HxWx3 numpy image")
138
+ return image
139
+ raise TypeError(f"Unsupported image type: {type(image)}")
140
+
141
+
142
+ def _to_mask_u8(mask: str | Path | np.ndarray | Image.Image) -> np.ndarray:
143
+ if isinstance(mask, (str, Path)):
144
+ m = cv2.imread(str(mask))
145
+ if m is None:
146
+ raise FileNotFoundError(str(mask))
147
+ m = (m > 128).astype(np.uint8)[:, :, 0]
148
+ return m
149
+ if isinstance(mask, Image.Image):
150
+ m = np.array(mask)
151
+ elif isinstance(mask, np.ndarray):
152
+ m = mask
153
+ else:
154
+ raise TypeError(f"Unsupported mask type: {type(mask)}")
155
+
156
+ if m.ndim == 3:
157
+ m = m[:, :, 0]
158
+ if m.ndim != 2:
159
+ raise ValueError("Expected HxW mask")
160
+ return (m > 128).astype(np.uint8)
161
+
162
+
163
+ def _basename_no_ext(x: str | Path | None, fallback: str) -> str:
164
+ if isinstance(x, (str, Path)):
165
+ base = os.path.basename(str(x))
166
+ return os.path.splitext(base)[0]
167
+ return fallback
168
+
169
+
170
+ def _normalize_suffix(s: str) -> str:
171
+ if not s:
172
+ return ""
173
+ return s[1:] if s.startswith("_") else s
174
+
175
+
176
+ class InsertAnythingModel:
177
+ def __init__(
178
+ self,
179
+ *,
180
+ model_dir: str | Path | None = None,
181
+ flux_fill_path: str | Path | None = None,
182
+ flux_redux_path: str | Path | None = None,
183
+ ia_lora_path: str | Path | None = None,
184
+ device: str | torch.device | None = None,
185
+ ) -> None:
186
+ if device is None:
187
+ device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
188
+ elif not isinstance(device, torch.device):
189
+ device = torch.device(device)
190
+
191
+ self.device = device
192
+ self.pipe, self.redux = _get_pipes(
193
+ model_dir,
194
+ flux_fill_path=flux_fill_path,
195
+ flux_redux_path=flux_redux_path,
196
+ ia_lora_path=ia_lora_path,
197
+ device=device,
198
+ )
199
+
200
+ def __call__(
201
+ self,
202
+ *,
203
+ source_image: str | Path | np.ndarray | Image.Image,
204
+ mask_image: str | Path | np.ndarray | Image.Image,
205
+ ref_image: str | Path | np.ndarray | Image.Image,
206
+ ref_mask: str | Path | np.ndarray | Image.Image,
207
+ sam_mask: str | Path | np.ndarray | Image.Image | None = None,
208
+ seeds=123,
209
+ strength: float | None = None,
210
+ split_ratio: float = 0.5,
211
+ save_path: str = "./result",
212
+ filename_suffix: str = "",
213
+ return_image: bool = False,
214
+ ):
215
+ return _run_insertanything_with_pipes(
216
+ source_image=source_image,
217
+ mask_image=mask_image,
218
+ ref_image=ref_image,
219
+ ref_mask=ref_mask,
220
+ sam_mask=sam_mask,
221
+ seeds=seeds,
222
+ strength=strength,
223
+ split_ratio=split_ratio,
224
+ save_path=save_path,
225
+ filename_suffix=filename_suffix,
226
+ return_image=return_image,
227
+ pipe=self.pipe,
228
+ redux=self.redux,
229
+ device=self.device,
230
+ )
231
+
232
+
233
+ def _run_insertanything_with_pipes(
234
+ *,
235
+ source_image: str | Path | np.ndarray | Image.Image,
236
+ mask_image: str | Path | np.ndarray | Image.Image,
237
+ ref_image: str | Path | np.ndarray | Image.Image,
238
+ ref_mask: str | Path | np.ndarray | Image.Image,
239
+ sam_mask: str | Path | np.ndarray | Image.Image | None = None,
240
+ seeds=123,
241
+ strength: float | None = None,
242
+ split_ratio: float = 0.5,
243
+ save_path: str = "./result",
244
+ filename_suffix: str = "",
245
+ return_image: bool = False,
246
+ pipe: FluxFillPipeline,
247
+ redux: FluxPriorReduxPipeline,
248
+ device: torch.device,
249
+ ):
250
+ if seeds is None:
251
+ seeds = [666]
252
+
253
+ ref_image_np = _to_rgb_numpy(ref_image)
254
+ tar_image = _to_rgb_numpy(source_image)
255
+
256
+ ref_mask_np = _to_mask_u8(ref_mask)
257
+ tar_mask = _to_mask_u8(mask_image)
258
+ tar_mask = cv2.resize(tar_mask, (tar_image.shape[1], tar_image.shape[0]))
259
+
260
+ sam_mask_np = None
261
+ if sam_mask is not None:
262
+ sam_mask_np = _to_mask_u8(sam_mask)
263
+ sam_mask_np = cv2.resize(sam_mask_np, (tar_image.shape[1], tar_image.shape[0]))
264
+
265
+ # Remove the background information of the reference picture
266
+ ref_box_yyxx = get_bbox_from_mask(ref_mask_np)
267
+ ref_mask_3 = np.stack([ref_mask_np, ref_mask_np, ref_mask_np], -1)
268
+ masked_ref_image = ref_image_np * ref_mask_3 + np.ones_like(ref_image_np) * 255 * (1 - ref_mask_3)
269
+
270
+ # Extract the box where the reference image is located, and place the reference
271
+ # object at the center of the image
272
+ y1, y2, x1, x2 = ref_box_yyxx
273
+ masked_ref_image = masked_ref_image[y1:y2, x1:x2, :]
274
+ ref_mask_crop = ref_mask_np[y1:y2, x1:x2]
275
+ ratio = 1.3
276
+ masked_ref_image, ref_mask_crop = expand_image_mask(masked_ref_image, ref_mask_crop, ratio=ratio)
277
+ masked_ref_image = pad_to_square(masked_ref_image, pad_value=255, random=False)
278
+
279
+ # Dilate the mask
280
+ kernel = np.ones((7, 7), np.uint8)
281
+ iterations = 2
282
+ tar_mask = cv2.dilate(tar_mask, kernel, iterations=iterations)
283
+
284
+ # zoom in
285
+ tar_box_yyxx = get_bbox_from_mask(tar_mask)
286
+ tar_box_yyxx = expand_bbox(tar_mask, tar_box_yyxx, ratio=1.2)
287
+
288
+ tar_box_yyxx_crop = expand_bbox(tar_image, tar_box_yyxx, ratio=2)
289
+ tar_box_yyxx_crop = box2squre(tar_image, tar_box_yyxx_crop)
290
+ y1, y2, x1, x2 = tar_box_yyxx_crop
291
+
292
+ old_tar_image = tar_image.copy()
293
+ tar_image = tar_image[y1:y2, x1:x2, :]
294
+ tar_mask = tar_mask[y1:y2, x1:x2]
295
+ if sam_mask_np is not None:
296
+ sam_mask_np = sam_mask_np[y1:y2, x1:x2]
297
+
298
+ H1, W1 = tar_image.shape[0], tar_image.shape[1]
299
+
300
+ tar_mask = pad_to_square(tar_mask, pad_value=0)
301
+ tar_mask = cv2.resize(tar_mask, size)
302
+
303
+ if sam_mask_np is not None:
304
+ sam_mask_np = pad_to_square(sam_mask_np, pad_value=0)
305
+ sam_mask_np = cv2.resize(sam_mask_np, size)
306
+
307
+ # Extract the features of the reference image
308
+ masked_ref_image = cv2.resize(masked_ref_image.astype(np.uint8), size).astype(np.uint8)
309
+ pipe_prior_output = redux(Image.fromarray(masked_ref_image))
310
+
311
+ tar_image = pad_to_square(tar_image, pad_value=255)
312
+ H2, W2 = tar_image.shape[0], tar_image.shape[1]
313
+
314
+ tar_image = cv2.resize(tar_image, size)
315
+ diptych_ref_tar = np.concatenate([masked_ref_image, tar_image], axis=1)
316
+
317
+ tar_mask = np.stack([tar_mask, tar_mask, tar_mask], -1)
318
+ mask_black = np.ones_like(tar_image) * 0
319
+ mask_diptych = np.concatenate([mask_black, tar_mask], axis=1)
320
+
321
+ # BBox-based mask for the second half of denoising (bbox_mask)
322
+ bbox_mask_diptych = mask_diptych.copy()
323
+
324
+ # SAM/ObjectStitch-based mask for the first half of denoising (sam_mask)
325
+ sam_mask_diptych = None
326
+ if sam_mask_np is not None:
327
+ sam_mask_rgb = np.stack([sam_mask_np, sam_mask_np, sam_mask_np], -1)
328
+ sam_mask_diptych = np.concatenate([mask_black, sam_mask_rgb], axis=1)
329
+
330
+ diptych_ref_tar = Image.fromarray(diptych_ref_tar)
331
+ mask_diptych[mask_diptych == 1] = 255
332
+ mask_diptych = Image.fromarray(mask_diptych)
333
+
334
+ if bbox_mask_diptych is not None:
335
+ bbox_mask_diptych[bbox_mask_diptych == 1] = 255
336
+ bbox_mask_diptych = Image.fromarray(bbox_mask_diptych)
337
+
338
+ if sam_mask_diptych is not None:
339
+ sam_mask_diptych[sam_mask_diptych == 1] = 255
340
+ sam_mask_diptych = Image.fromarray(sam_mask_diptych)
341
+
342
+ os.makedirs(save_path, exist_ok=True)
343
+
344
+ for seed in seeds:
345
+ generator = torch.Generator(device=device).manual_seed(seed)
346
+ from libcom.os_insert.diffusers_osinsert import patch_context
347
+
348
+ with patch_context():
349
+ edited_image = pipe(
350
+ image=diptych_ref_tar,
351
+ mask_image=mask_diptych,
352
+ height=mask_diptych.size[1],
353
+ width=mask_diptych.size[0],
354
+ max_sequence_length=512,
355
+ generator=generator,
356
+ strength=strength if strength is not None else 1.0,
357
+ sam_mask=sam_mask_diptych,
358
+ bbox_mask=bbox_mask_diptych,
359
+ split_ratio=split_ratio,
360
+ **pipe_prior_output,
361
+ ).images[0]
362
+
363
+ width, height = edited_image.size
364
+ left = width // 2
365
+ right = width
366
+ top = 0
367
+ bottom = height
368
+ edited_image = edited_image.crop((left, top, right, bottom))
369
+
370
+ edited_image = np.array(edited_image)
371
+ edited_image = crop_back(
372
+ edited_image,
373
+ old_tar_image,
374
+ np.array([H1, W1, H2, W2]),
375
+ np.array(tar_box_yyxx_crop),
376
+ )
377
+ edited_pil = Image.fromarray(edited_image)
378
+
379
+ ref_without_ext = _basename_no_ext(ref_mask if isinstance(ref_mask, (str, Path)) else None, "ref")
380
+ tar_without_ext = _basename_no_ext(mask_image if isinstance(mask_image, (str, Path)) else None, "tar")
381
+
382
+ suffix_norm = _normalize_suffix(filename_suffix)
383
+ if ref_without_ext == "ref" and tar_without_ext == "tar" and suffix_norm:
384
+ base_name = suffix_norm
385
+ seed_token = f"seed{seed}"
386
+ needs_seed_suffix = (len(seeds) > 1) and (seed_token not in base_name)
387
+ if needs_seed_suffix:
388
+ edited_image_save_path = os.path.join(save_path, f"{base_name}_seed{seed}.png")
389
+ else:
390
+ edited_image_save_path = os.path.join(save_path, f"{base_name}.png")
391
+ else:
392
+ suffix = f"_{suffix_norm}" if suffix_norm else ""
393
+ edited_image_save_path = os.path.join(
394
+ save_path,
395
+ f"{ref_without_ext}_to_{tar_without_ext}_seed{seed}{suffix}.png",
396
+ )
397
+ edited_pil.save(edited_image_save_path)
398
+
399
+ if return_image:
400
+ return np.array(edited_pil)
401
+
402
+ return None
403
+
404
+
405
+ def run_insertanything(
406
+ source_image_path: str | Path | np.ndarray | Image.Image,
407
+ mask_image_path: str | Path | np.ndarray | Image.Image,
408
+ ref_image_path: str | Path | np.ndarray | Image.Image,
409
+ ref_mask_path: str | Path | np.ndarray | Image.Image,
410
+ sam_mask_path: str | Path | np.ndarray | Image.Image | None = None,
411
+ seeds=123,
412
+ strength: float | None = None,
413
+ split_ratio: float = 0.5,
414
+ save_path: str = "./result",
415
+ filename_suffix: str = "",
416
+ model_dir: str | Path | None = None,
417
+ flux_fill_path: str | Path | None = None,
418
+ flux_redux_path: str | Path | None = None,
419
+ ia_lora_path: str | Path | None = None,
420
+ device: str | torch.device | None = None,
421
+ net: InsertAnythingModel | None = None,
422
+ *,
423
+ return_image: bool = False,
424
+ ):
425
+ """Single-image InsertAnything inference following the original diptych pipeline."""
426
+
427
+ if net is None:
428
+ if device is None:
429
+ device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
430
+ else:
431
+ device = torch.device(device)
432
+ pipe, redux = _get_pipes(
433
+ model_dir,
434
+ flux_fill_path=flux_fill_path,
435
+ flux_redux_path=flux_redux_path,
436
+ ia_lora_path=ia_lora_path,
437
+ device=device,
438
+ )
439
+ else:
440
+ pipe, redux, device = net.pipe, net.redux, net.device
441
+
442
+ return _run_insertanything_with_pipes(
443
+ source_image=source_image_path,
444
+ mask_image=mask_image_path,
445
+ ref_image=ref_image_path,
446
+ ref_mask=ref_mask_path,
447
+ sam_mask=sam_mask_path,
448
+ seeds=seeds,
449
+ strength=strength,
450
+ split_ratio=split_ratio,
451
+ save_path=save_path,
452
+ filename_suffix=filename_suffix,
453
+ return_image=return_image,
454
+ pipe=pipe,
455
+ redux=redux,
456
+ device=device,
457
+ )
458
+
459
+
460
+ def insertanything_infer(
461
+ *,
462
+ source_image: str | Path | np.ndarray | Image.Image,
463
+ mask_image: str | Path | np.ndarray | Image.Image,
464
+ ref_image: str | Path | np.ndarray | Image.Image,
465
+ ref_mask: str | Path | np.ndarray | Image.Image,
466
+ sam_mask: str | Path | np.ndarray | Image.Image | None = None,
467
+ seeds=123,
468
+ strength: float | None = None,
469
+ split_ratio: float = 0.5,
470
+ save_path: str = "./result",
471
+ filename_suffix: str = "",
472
+ net: InsertAnythingModel | None = None,
473
+ model_dir: str | Path | None = None,
474
+ flux_fill_path: str | Path | None = None,
475
+ flux_redux_path: str | Path | None = None,
476
+ ia_lora_path: str | Path | None = None,
477
+ device: str | torch.device | None = None,
478
+ return_image: bool = True,
479
+ ):
480
+ if net is None:
481
+ net = InsertAnythingModel(
482
+ model_dir=model_dir,
483
+ flux_fill_path=flux_fill_path,
484
+ flux_redux_path=flux_redux_path,
485
+ ia_lora_path=ia_lora_path,
486
+ device=device,
487
+ )
488
+
489
+ return net(
490
+ source_image=source_image,
491
+ mask_image=mask_image,
492
+ ref_image=ref_image,
493
+ ref_mask=ref_mask,
494
+ sam_mask=sam_mask,
495
+ seeds=seeds,
496
+ strength=strength,
497
+ split_ratio=split_ratio,
498
+ save_path=save_path,
499
+ filename_suffix=filename_suffix,
500
+ return_image=return_image,
501
+ )
502
+
503
+
504
+ def main():
505
+ parser = argparse.ArgumentParser(
506
+ description="Single-image InsertAnything inference using diptych pipeline",
507
+ )
508
+ parser.add_argument("--source_image", default="examples/source_image/1.png")
509
+ parser.add_argument("--source_mask", default="examples/source_mask/1.png")
510
+ parser.add_argument("--ref_image", default="examples/ref_image/1.png")
511
+ parser.add_argument("--ref_mask", default="examples/ref_mask/1.png")
512
+ parser.add_argument("--outdir", default="./result")
513
+ parser.add_argument("--seeds", nargs="+", type=int, default=[666])
514
+ parser.add_argument("--strength", type=float, default=1.0)
515
+ args = parser.parse_args()
516
+
517
+ run_insertanything(
518
+ source_image_path=args.source_image,
519
+ mask_image_path=args.source_mask,
520
+ ref_image_path=args.ref_image,
521
+ ref_mask_path=args.ref_mask,
522
+ seeds=args.seeds,
523
+ strength=args.strength,
524
+ save_path=args.outdir,
525
+ )
526
+
527
+
528
+ if __name__ == "__main__":
529
+ main()
File without changes