
    9i&4                        S r SSKrSSKrSSKrSSKJr  SSKJr  SSK	J
r
  SSKJr  SSKJr  SSKJrJr  SSKJr  S	S
KJr  S rS rS rS1S\R0                  S\4S jjr    S2S\R0                  S\S\S\S\4
S jjr  S3S\R0                  S\R0                  S\4S jjr S4S\R0                  S\R0                  S\R0                  S\R0                  S\R0                  S\R0                  S\4S jjr  S5S\R0                  S\R0                  S\R@                  S \R@                  S!\R0                  S"\S#\!S$\"S%\"S&\4S' jjr#S(\$S)\"S*\"S+\"4S, jr%S(\$S-\R@                  S.\&S/\"S%\"S&\S)\"S*\"S+\"4S0 jr'g)6zx
Part of the implementation is borrowed and modified from LaMa, publicly available at
https://github.com/saic-mdal/lama
    N)gaussian_blur2d)resizeerosion)
functional)SGDAdam)tqdm   )FFCResnetBlockc           	         [        U [        R                  5      (       a  U R                  U5      $ [        R
                  " U 5      (       a  U R                  U5      $ [        U [        [        45      (       a  U  Vs/ s H  n[        X!5      PM     sn$ [        U [        5      (       a/  U R                  5        VVs0 s H  u  p4U[        XA5      _M     snn$ [        S[        U 5       35      es  snf s  snnf )NzUnexpected type )
isinstancennModuletotorch	is_tensortuplelistmove_to_devicedictitems
ValueErrortype)objdeviceelnamevals        p/var/www/html/land-doc-ocr/venv/lib/python3.13/site-packages/modelscope/models/cv/image_inpainting/refinement.pyr   r      s    #ryy!!vvf~svvf~#t}%%589Srr*S99#tCF99;O;idnS11;OO
'S	{3
44 :Os   <C/<C4c                 *    X-  S:X  a  U $ X-  S-   U-  $ )Nr   r    )xmods     r    ceil_modulor%      s!    w!|HqLC    c                     U R                   u  p#pE[        XA5      n[        XQ5      n[        R                  " U SXu-
  SXd-
  4SS9$ )Nr   reflect)padmode)shaper%   Fr)   )imgr$   
batch_sizechannelsheightwidth
out_height	out_widths           r    pad_tensor_to_modulor4   %   sM    *-))'J&V)JE'I55	!1j&9: r&   imdownsizec                     Uc$  U R                   S   S-  U R                   S   S-  4nU R                   S   S:X  d   S5       e[        U SSS9n [        R                  " XSS	S
9n U $ )zdownscale the image      r   z5Expected shape for the input to be (n,3,height,width)   r;         ?r=   kernel_sizesigmabilinearFsizer*   align_cornersr+   r   r,   interpolate)r5   r6   s     r    _pyrdownrG   /   s|    HHQK1$bhhqkQ&6788	 IHI 	z	BB	
rz	OBIr&   maskeps	blur_maskround_upc                 X   Uc$  U R                   S   S-  U R                   S   S-  4nU R                   S   S:X  d   S5       eUSL a"  [        U SSS9n [        R                  " XS	S
S9n O[        R                  " XS	S
S9n U(       a  SX U:  '   SX U:  '   U $ SX SU-
  :  '   SX SU-
  :  '   U $ )a2  downscale the mask tensor

Parameters
----------
mask : torch.Tensor
    mask of size (B, 1, H, W)
downsize : tuple, optional
    size to downscale to. If None, image is downscaled to half, by default None
eps : float, optional
    threshold value for binarizing the mask, by default 1e-8
blur_mask : bool, optional
    if True, apply gaussian filter before downscaling, by default True
round_up : bool, optional
    if True, values above eps are marked 1, else, values below 1-eps are marked 0, by default True

Returns
-------
torch.Tensor
    downscaled mask
r8   r9   r   z5Expected shape for the input to be (n,1,height,width)Tr:   r<   r>   rA   FrB   r   r=   rE   )rH   r6   rI   rJ   rK   s        r    _pyrdown_maskrM   :   s    4 JJqMQ&

1(:;::	 IHI DtzJ}}jG }}jGS[CZ K #$S3Y!"C#IKr&   ekernelc                 J    Ub  [        X5      n SX SU-
  :  '   SX SU-
  :  '   U $ )z(erode the mask, and set gray pixels to 0r   r=   r   r   )rH   rN   rI   s      r    _erode_maskrP   h   s;     t%"#S3Y!"C#IKr&   predpred_downscaledrefmask_downscaledimageon_predc           	          [         R                  " [         R                  " XS:     XSS:     -
  5      5      nU(       a:  U[         R                  " [         R                  " XS:     X$S:     -
  5      5      -  nU$ )zAl1 loss on src pixels, and downscaled predictions if on_pred=True:0yE>)r   meanabs)rQ   rR   rS   rH   rT   rU   rV   losss           r    _l1_lossr\   s   ss     ::eiiD[ 1E+4F FGHD

IIo&=>t345 67 	7 Kr&   forward_frontforward_rearsref_lower_res
orig_shapedevices	scale_indn_iterslrc
                 \   U SU-
  -  n
[         R                  " X/SS9n
UR                  SSSS5      nUb  UR                  5       n[         R                  " 5          U" U
5      u  pSSS5        UR                  US   5      n[         R                  " [        R                  " [        R                  S5      R                  [        5      5      R                  5       nUR                  US   5      nU R                  US   5      n WR                  5       R                  US   5      WR                  5       R                  US   5      pSu  Ul        Ul        [        X/U	S	9n[        [!        U5      S
S9nU GHs  nUR#                  5         X4n[%        U5       H[  u  nnU" U5      nU['        U5      S-
  :  a9  Uu  nnUR                  UUS-      5      UR                  UUS-      5      nnUU4nMY  UnM]     Uc    O0 n[)        WSS2SS2SUS   2SUS   24   5      n[+        USS2SS2SUS   2SUS   24   S
S
S9n[-        UUS9nUR                  SSSS5      n[/        UUUUUU SS9US'   [1        UR3                  5       5      nUR5                  SR7                  US-   UUR9                  5       5      5        UUS-
  :  d  GMP  UR;                  5         UR=                  5         AAAGMv     UW-  SU-
  U -  -   nUR                  5       R?                  5       nU$ ! , (       d  f       GN= f)a  Performs inference with refinement at a given scale.

Parameters
----------
image : torch.Tensor
    input image to be inpainted, of size (1,3,H,W)
mask : torch.Tensor
    input inpainting mask, of size (1,1,H,W)
forward_front : nn.Module
    the front part of the inpainting network
forward_rears : nn.Module
    the rear part of the inpainting network
ref_lower_res : torch.Tensor
    the inpainting at previous scale, used as reference image
orig_shape : tuple
    shape of the original input image before padding
devices : list
    list of available devices
scale_ind : int
    the scale index
n_iters : int, optional
    number of iterations of refinement, by default 15
lr : float, optional
    learning rate, by default 0.002

Returns
-------
torch.Tensor
    inpainted image
r   )dimr9   N)   rh   r   )TT)rd   F)leave)rJ   rK   )rN   T)rV   ms_l1z8Refining scale {} using scale {} ...current loss: {:.4f}) r   catrepeatdetachno_gradr   
from_numpycv2getStructuringElementMORPH_ELLIPSEastypeboolfloatrequires_gradr	   r
   range	zero_grad	enumeratelenrG   rM   rP   r\   sumvaluesset_descriptionformatitembackwardstepcpu)rU   rH   r]   r^   r_   r`   ra   rb   rc   rd   masked_imagez1z2rN   	optimizerpbaridi
input_featiddforward_rearoutput_featmidz1midz2rQ   lossesrR   rT   r[   	inpainteds                                r    _inferr      s*   P AH%L99l1q9L;;q!Q"D %,,.	|, 
 7772;D!!#"3"3"*	,,2F4L::?%'  jj%GHHWR[!EYY[^^GAJ'
)C)3&Bb&bX"%Ige,DX
!*=!9C&z2KS\A%%*u$xxa(89588C!G$<&u#U^
" ":  "41nz!}nnz!}n(L#MN'BQBAA67 &owG)00Aq!<"w 6==?#FMMAy$))+7	8 1MMONNU X tq4x500I  "&&(I{ 
s   L
L+batchmin_side
max_scales	px_budgetc                 r   U S   R                   S   S:X  d   S5       eU S   u  pEUS   R                  5       US   R                  5       pTU S   SSU2SU24   nU S   SSU2SU24   nXE-  U:  at  [        R                  " U[	        XE-  5      -  5      nXEp[        XH-  5      [        XX-  5      pT[        S	X4 S
XE4 S35        [        XdU4SSS9n[        XtU4SSS9nSXwS:  '   [        XE5      n[        S[        [        [        S[        R                  " X-  5      5      5      5      -   U5      n/ n/ nUR                  U5        UR                  U5        [        US-
  5       HA  n[        US   5      n[        US   5      nUR                  U5        UR                  U5        MC     USSS2   USSS2   4$ )a  Build the image mask pyramid

Parameters
----------
batch : dict
    batch containing image, mask, etc
min_side : int
    minimum side length to limit the number of scales of the pyramid
max_scales : int
    maximum number of scales allowed
px_budget : int
    the product H*W cannot exceed this budget, because of resource constraints

Returns
-------
tuple
    image-mask pyramid in the form of list of images and list of masks
rU   r   r   z(refiner works on only batches of size 1!unpad_to_size.NrH   z2Original image too large for refinement! Resizing z to z...rA   F)interpolationrD   rX   rg   )r+   r   npsqrtru   intprintr   minroundmaxlog2appendrw   rG   rM   )r   r   r   r   hwrU   rH   ratioh_origw_origbreadthn_scales	ls_imagesls_masks_image_pmask_ps                     r    _get_image_mask_pyramidr      s   * >	 <;<  !DAQ499;!		q'N3BQB;'E=bqb"1"%Duy	E!%L0119~s19~1@&@QQUWXV[U\\_`	
 q65Ja&
%ID[!iG1s5Q0B(C!DEFFHIHUOOD8a< 9R=)x|,!	 ! TrT?HTrTN**r&   	inpaintergpu_idsmoduloc	                 F   UR                   nUR                  (       a   eUR                  (       a   eUR                  (       d   eUR	                  SS5      R                  S5       V	s/ s H  n	U	R                  5       (       d  M  SU	 3PM!     nn	Sn
SnSn[        [        UR                  R                   5      5       HF  n[        UR                  R                   U   [        5      (       a	  U
S-  n
SnM8  U(       a  MA  US-  nMH     U
[        U5      -  nU Vs/ s H  n[        R                  " U5      PM     nnUR                  R                   SU nUR                  US   5        / n[        [        U5      5       H  nU[        U5      S-
  :  a8  UR                  UR                  R                   UUU-  -   UUUS-   -  -    5        O.UR                  UR                  R                   UUU-  -   S	 5        UU   R                  UU   5        M     [!        XUU5      u  nnS	n[#        [%        UU5      5       H  u  nu  nnUR&                  S
S	 n[)        UU5      n[)        UU5      nSUUS:  '   SUUS:  '   [+        UUS   5      [+        UUS   5      nnUb  [+        UUS   5      n[-        UUUUUUUUXE5
      nUS	S	2S	S	2S	US   2S	US   24   nUR/                  5       R1                  5       nUR/                  5       R1                  5       nM     U$ s  sn	f s  snf )a  Refines the inpainting of the network

Parameters
----------
batch : dict
    image-mask batch, currently we assume the batchsize to be 1
inpainter : nn.Module
    the inpainting neural network
gpu_ids : str
    the GPU ids of the machine to use. If only single GPU, use: "0,"
modulo : int
    pad the image to ensure dimension % modulo == 0
n_iters : int
    number of iterations of refinement for each scale
lr : float
    learning rate
min_side : int
    all sides of image on all scales should be >= min_side / sqrt(2)
max_scales : int
    max number of downscaling scales for the image-mask pyramid
px_budget : int
    pixels budget. Any image will be resized to satisfy height*width <= px_budget

Returns
-------
torch.Tensor
    inpainted image of size (1,3,H,W)
  ,zcuda:r   Fr   TNr8   r=   rX   g        rg   )modeltrainingadd_noise_kwargsconcat_maskreplacesplitisdigitrw   rz   	generatorr   r   r   r   r   r   r   ry   zipr+   r4   r   r   rm   r   )r   r   r   r   rc   rd   r   r   r   gpuidn_resnet_blocksfirst_resblock_indfound_first_resblockidlresblocks_per_gpugpu_idra   r]   r^   r   r   r   image_inpaintedidsrU   rH   r`   s                              r    refine_predictr   -  sQ   > I!!!!))))     &-__S"%=%C%CC%H%HE==? 	%w%H   O S,,2234i))//4nEEq O#' %%!# 5 (3w<729:'u||F#'G: ''--a0BCMWQZ MS\"W!!  ##))*<,=-0-2+22D,=q,I3JKL   ##))*<,=,E+F +G HI 	cgcl+ # 2%:2;=IxO'Ix(@A]eT[[_
$UF3#D&1 TT\TD[$UGAJ7'!*:t&,_gbkJO m]!0*gs!(. *!QAA*NO""${{}  "! B$ q ;s   )L	L L)N)NrX   TT)NrX   )T)rh   gMb`?)(__doc__rp   numpyr   r   torch.nnr   kornia.filtersr   kornia.geometry.transformr   kornia.morphologyr   r   r,   torch.optimr   r	   r
   modules.ffcr   r   r%   r4   Tensorr   rG   ru   rt   rM   rP   r\   r   r   r   r   r   r   strr   r"   r&   r    <module>r      s(       * , % $ !  '	5    %)#$(#'	+ +!++ "+ !	+^ )-!ell " "5<< #ll,, << $ll	
 LL 0 k%,, kk))k ))k  ,,	k
 k k k k k\9+4 9+3 9+C 9+'*9+x\$ \299 \s \\),\27\CF\"\/2\r&   