
    3jJ?                        S r SSKrSSKJr  SSKrSSKJs  Jr  SSK	J
r
  SSKJr  SSKJr   S S\R                  S	\\\4   S
\S\\R                  \R                  4   4S jjrS\R                  S\\\4   S\R                  4S jrS\R                  S\S\R                  4S jr S!S\R                  S\S\S\S\R                  4
S jjrS\R                  S\R                  S\R                  4S jrS\R                  S\R                  S\R                  4S jr\   S"S\R                  S\S	\\\4   S\S\R                  4
S jj5       rg)#zHIn this module several equalization methods are exposed: he, ahe, clahe.    N)Tuple_torch_histc_cast)perform_keep_shape_image   )	histogramimgs	grid_sizeeven_tile_sizereturnc                    U nUR                   SS u  pE[        R                  " XAS   -  5      n[        R                  " XQS   -  5      nU(       a   XfS-  (       a  SOS-  nXwS-  (       a  SOS-  nXaS   -  U-
  nXqS   -  U-
  n	XR                   S   :  d  XR                   S   :  a  [        S5      eUS:  d  U	S:  a  [        R
                  " USU	SU/SS	9nUR                   S
   n
UR                  SX5      R                  SXf5      R                  SXw5      R                  S5      R                  5       nUR                   S   US   :w  a  [        eUR                   S   US   :w  a  [        eX4$ )a\  Compute tiles on an image according to a grid size.

Note that padding can be added to the image in order to crop properly the image.
So, the grid_size (GH, GW) x tile_size (TH, TW) >= image_size (H, W)

Args:
    imgs: batch of 2D images with shape (B, C, H, W) or (C, H, W).
    grid_size: number of tiles to be cropped in each direction (GH, GW)
    even_tile_size: Determine if the width and height of the tiles must be even.

Returns:
    tensor with tiles (B, GH, GW, C, TH, TW). B = 1 in case of a single image is provided.
    tensor with the padded batch of 2D imageswith shape (B, C, H', W').

Nr   r      zBCannot compute tiles on the image according to the given grid sizereflect)mode   )
shapemathceil
ValueErrorFpadunfoldsqueeze
contiguousAssertionError)r	   r
   r   batchhwkernel_vertkernel_horzpad_vertpad_horzctiless               U/home/wildlama/miniconda3/lib/python3.13/site-packages/kornia/enhance/equalization.py_compute_tilesr+       sg   $ E ;;rsDAyyq\!12Kyyq\!12K!Oq2!Oq2 q\)A-Hq\)A-H ++b/!XB%?]^^!|x!|ea1h7iH [[_AQ	;	,	;	,	jl 
 {{2)A,&{{2)A,&<    padded_imgs	tile_sizec                 ^   U R                  5       S:w  a  [        S5      eU R                  S   US   -  S:w  a  [        S5      eU R                  S   US   -  S:w  a  [        S5      eUS   S-  nUS   S-  nU R                  S	   nU R                  SXD5      R                  SX"5      R                  S
X35      R	                  S5      R                  5       nUR                  S	   U:w  a  [        eUR                  S   US   S-  :w  a  [        eUR                  S   US   S-  :w  a  [        eU$ )a  Compute interpolation tiles on a properly padded set of images.

Note that images must be padded. So, the tile_size (TH, TW) * grid_size (GH, GW) = image_size (H, W)

Args:
    padded_imgs: batch of 2D images with shape (B, C, H, W) already padded to extract tiles
                                of size (TH, TW).
    tile_size: shape of the current tiles (TH, TW).

Returns:
    tensor with the interpolation tiles (B, 2GH, 2GW, C, TH/2, TW/2).

   zImages Tensor must be 4D.r   r   z Images are not correctly padded.r   r   r   r   r   )dimr    r   r   r   r   )r-   r.   interp_kernel_vertinterp_kernel_horzr(   interp_tiless         r*   _compute_interpolation_tilesr5   Z   sC    A899y|+q0?@@y|+q0?@@ (la/'la/r"A1a#	%	:	%	:	jl  """1!11"1!11r,   r)   binsc                     [        XSSS9$ )Nr   r   r6   minmaxr   )r)   r6   s     r*   	_my_histcr;      s    U1!<<r,   
tiles_x_imnum_binsclipdiffc                    U R                  5       S:w  a  [        S5      eU R                  u  pEpgpX-  n
U R                  SU
5      nU(       d  [        R
                  R                  5       (       a1  [        R                  " U Vs/ s H  n[        XSSS9PM     sn5      nO[        R                  " [        [        [        X/[        U5      -  5      5      5      nOR[        R                  " SSXR                  S9n[        X[        R                   " S5      5      R#                  5       nX-  nUS	:  a  [%        X*-  U-  S5      nUR'                  US
9  XR)                  S5      -
  n[        R*                  " UU5      nUU-
  R-                  U5      nUUS   R/                  SS5      -  n[        R0                  " XR                  S9nUR3                  UR                  S   S5      nUUUS   R/                  SS5      :  -  nUS-
  U
-  n[        R4                  " US5      U-  nUR7                  SUS-
  5      nU(       d  UR9                  5       nUR                  XEXgU45      nU$ s  snf )a  Compute luts for a batched set of tiles.

Same approach as in OpenCV (https://github.com/opencv/opencv/blob/master/modules/imgproc/src/clahe.cpp)

Args:
    tiles_x_im: set of tiles per image to apply the lut. (B, GH, GW, C, TH, TW)
    num_bins: number of bins. default: 256
    clip: threshold value for contrast limiting. If it is 0 then the clipping is disabled.
    diff: denote if the differentiable histagram will be used. Default: False

Returns:
    Lut for each tile (B, GH, GW, C, 256).

   zTensor must be 6D.r   r   r   r8   )devicegMbP?g        )r:   N)r1   r    r   viewtorchjitis_scriptingstackr   listmapr;   lenlinspacerB   r   tensorr   r:   clamp_sum	remainderdiv	transposearangerepeatcumsumclampfloor)r<   r=   r>   r?   bghgwr(   thtwpixelsr)   tilehistosr6   max_valclippedresidualredistv_range	mat_range	lut_scalelutss                          r*   _compute_lutsrg      s   " ~~1122%++A2"'F$//"f5E99!!##[[ch!ich[_"3DQTU"Vch!ijF[[c)UJU<S&T!UVF"^^Aq(<<P5U(;<DDFczT]h6:'" &A 6!&(!C '( 277A&,((A.. %Xmm L")..a!"D	)htn66q!<<< 1.Ifa09<D::aA&Dzz|99aRH-.DK5 "js   I&r4   rf   c           	      R   U R                  5       S:w  a  [        S5      eUR                  5       S:w  a  [        S5      eU R                  u  p#pE  n[        R                  " SS[        R
                  S9nUS:  ad  [        R                  " S	US	-
  5      R                  US-
  S	5      R                  SS
S9n[        R                  " / SQ/ SQ/US-
  S-  -  5      nXx-  n[        R                  " SS[        R
                  S9n	US:  ad  [        R                  " S	US	-
  5      R                  US-
  S	5      R                  SS
S9n
[        R                  " / SQ/ SQ/US-
  S-  -  5      n	X-  n	[        R                  " X#USXQR                  S   4SU R                  U R                  S9nUSS2SS[        US-  S	-
  S	5      2SS[        US-  S	-
  S	5      24   USS2SSUS	-
  2SSUS	-
  2S4'   USS2USS2S4   SS[        US-  S	-
  S	5      24   USS2S	S2SSUS	-
  2S4'   USS2USS2S4   SS[        US-  S	-
  S	5      24   USS2S	S2SSUS	-
  2S	4'   USS2SS[        US-  S	-
  S	5      2U	SS2S4   4   USS2SSUS	-
  2S	S2S4'   USS2SS[        US-  S	-
  S	5      2U	SS2S	4   4   USS2SSUS	-
  2S	S2S	4'   USS2UR                  [        US-
  S	5      S	S	5      R                  S	SS5      U	R                  [        US-
  S	5      S	S	5      4   USS2S	S2S	S2SS24'   U$ )zAssign the required luts to each tile.

Args:
    interp_tiles: set of interpolation tiles. (B, 2GH, 2GW, C, TH/2, TW/2)
    luts: luts for each one of the original tiles. (B, GH, GW, C, 256)

Returns:
     mapped luts (B, 2GH, 2GW, 4, C, 256)

rA   interp_tiles tensor must be 6D.   luts tensor must be 5D.r   r0   )dtyper   r   trunc)rounding_mode)r   r   r   r   )r   r   r   r   )r   r   r   r   )r   r   r   r   r   rl   rB   N)r1   r    r   rD   emptylongrR   rC   rP   rL   fullrl   rB   r:   rS   permute)r4   rf   num_imgsrX   rY   r(   _j_idxsj_floori_idxsi_floorluts_x_interp_tiless               r*   	_map_lutsr{      s    Q>??xxzQ677 !- 2 2H"A [[AUZZ0F	Av,,q"q&)..rAvq9==aw=W|^<aANO[[AUZZ0F	Av,,q"q&)..rAvq9==aw=W|^<aANO
 ).

	r1aB0"L<N<NWcWjWj) ;?q!BZs2QR7UV;XYGZBZ\]\tadegklelopeprsat\t?t:u1;Q;R!VQ67376!Q$<IacRTXYRY\]R]_`NaIa8a3b1R4b1fa/0376!Q$<IacRTXYRY\]R]_`NaIa8a3b1R4b1fa/0371;SB!GaKQR@S;SU[\]_`\`Ua8a3b1;Q;"a/0371;SB!GaKQR@S;SU[\]_`\`Ua8a3b1;Q;"a/0,0	6==R!VQA.66q!Q?sSUXYSY[\~_`bcAdd-1R42q() r,   c           	      	   U R                  5       S:w  a  [        S5      eUR                  5       S:w  a  [        S5      e[        X5      nU R                  u  p4pVpxU S-  R	                  5       R                  SS5      n	U	R                  S5      R                  X4US	XgU-  5      n	[        R                  " USU	5      R                  U 5      R                  X4US	XgU5      n
[        R                  " U 5      n[        R                  " S
U-  S-
  SSU R                  U R                  S9R!                  SU-  S-
  5      S   R#                  SS5      R                  S
U-  U5      nUR%                  SXw5      R%                  SX5      n[        R                  " S
U-  S-
  SSU R                  U R                  S9R!                  SU-  S-
  5      R                  US
U-  5      nUR%                  SXw5      R%                  SX5      nUR                  US
-
  S
-  S
Xx5      R                  US
-
  SXx5      R                  S5      nUR'                  US
-
  S
-  SSS5      R                  S5      nU
SS2SS2SS24   R)                  S5      u  nnnn[        R*                  " UU[        R,                  " UU5      5      n[        R*                  " UU[        R,                  " UU5      5      n[        R*                  " UU[        R,                  " UU5      5      USS2SS2SS24'   U
SS2SSUS-
  2SSUS-
  2S4   USS2SSUS-
  2SSUS-
  24'   U
SS2SS2S4   R)                  S
5      u  nn  n[        R*                  " UUR/                  S5      [        R,                  " UU5      5      USS2SS2S4'   U
SS2SS2US-
  4   R)                  S
5      u  nn  n[        R*                  " UUR/                  S5      [        R,                  " UU5      5      USS2SS2US-
  4'   U
SS2SSS24   R)                  S
5      u  nn  n[        R*                  " UU[        R,                  " UU5      5      USS2SSS24'   U
SS2US-
  SS24   R)                  S
5      u  nn  n[        R*                  " UU[        R,                  " UU5      5      USS2US-
  SS24'   UR!                  S5      $ )a  Equalize the tiles.

Args:
    interp_tiles: set of interpolation tiles, values must be in the range [0, 1].
      (B, 2GH, 2GW, C, TH/2, TW/2)
    luts: luts for each one of the original tiles. (B, GH, GW, C, 256)

Returns:
    equalized tiles (B, 2GH, 2GW, C, TH/2, TW/2)

rA   ri   rj   rk      r   r   r   r0   r   r   ro   g       @Nr   r   g     o@)r1   r    r{   r   rq   flatten	unsqueezeexpandrD   gathertoreshape
zeros_likerR   rl   rB   rP   rQ   r   rS   unbindaddcmulsubr   )r4   rf   mapped_lutsrt   rX   rY   r(   rZ   r[   flatten_interp_tilespreinterp_tiles_equalizedtiles_equalizedihiwtiwtihtltrblbrtrW   ru   leftrights                            r*   _compute_equalized_tilesr      s    Q>??xxzQ677 ), =K #/"4"4H" +7*<)B)B)D)L)LRQS)T/99"=DDXSUWXZ[bd]de[!%9:	L		r1aR	0  %*$4$4\$BO 	QVaZR|/A/A,J]J]^	S2X\	4	!	2r		B		  
1b		$	$Q	/BQVaZR|/A/A,J]J]^	S2X\		AF	 
 
1b		$	$Q	/B ))R!VM1b
-
5
5b1fa
H
R
RST
UC
))R!VM1a
+
5
5a
8C /q!B$"}=DDQGNBBb#uyyR01Ab#uyyR01A%*]]1c599Q?%KOAqtQrTM" 4MQPQP[UWZ[U[P[]^]hbdghbh]hjkMk3lOAq{BF{AKaK/0 +1adA:6==a@JAq!Q"'--3;;q>599QPQ?"SOAqtQJ*1adBF?;BB1EJAq!Q',}}QA		RSUV'XOAqtR!VO$ 2!Q"*=DDQGD%A"'--sEIIdE<R"SOAq!B$J1!R!VQrT/BII!LD%A',}}UC4QVAW'XOArAvqtO$ u%%r,   input
clip_limitslow_and_differentiablec                 >   [        U[        5      (       d  [        S[        U5       35      e[        U[        5      (       d  [        S[        U5       35      e[        U5      S:w  a  [        S[        U5       35      e[        US   [        5      (       d  [        US   [        5      (       a  [        S5      eUS   S::  d	  US   S::  a  [        SU 35      eU n[        XBS	5      u  pVUR                  S
   UR                  S   4n[        Xg5      n[        XQUS9n	[        X5      n
U
R                  SSSSSS5      R                  U5      nUR                  S
S u  pUSSU2SU24   nU R                  5       UR                  5       :w  a  UR                  S5      nU$ )a5  Apply clahe equalization on the input tensor.

.. image:: _static/img/equalize_clahe.png

NOTE: Lut computation uses the same approach as in OpenCV, in next versions this can change.

Args:
    input: images tensor to equalize with values in the range [0, 1] and shape :math:`(*, C, H, W)`.
    clip_limit: threshold value for contrast limiting. If 0 clipping is disabled.
    grid_size: number of tiles to be cropped in each direction (GH, GW).
    slow_and_differentiable: flag to select implementation

Returns:
    Equalized image or images with shape as the input.

Examples:
    >>> img = torch.rand(1, 10, 20)
    >>> res = equalize_clahe(img)
    >>> res.shape
    torch.Size([1, 10, 20])

    >>> img = torch.rand(2, 3, 10, 20)
    >>> res = equalize_clahe(img)
    >>> res.shape
    torch.Size([2, 3, 10, 20])

z(Input clip_limit type is not float. Got z'Input grid_size type is not Tuple. Got r   z4Input grid_size is not a Tuple with 2 elements. Got r   r   z=Input grid_size type is not valid, must be a Tuple[int, int].z/Input grid_size elements must be positive. Got Tr   r   )r>   r?   r   r0   rj   N.)
isinstancefloat	TypeErrortypetuplerJ   r   r+   r   r5   rg   r   rs   
reshape_asr1   r   )r   r   r
   r   r	   
hist_tiles
img_paddedr.   r4   rf   equalized_tileseq_imgsr"   r#   s                 r*   equalize_claher   K  s   D j%((B4
CSBTUVVi''A$y/ARSTT
9~NsS\~N^_``)A,&&*Yq\5*I*IWXX|qIaLA-J9+VWWD
 ,DTBJ","2"22"6
8H8H8L!MI!=j!TL&*AD %=\$PO ,33Aq!Q1EPPQ[\G::bc?DAc2A2rrk"G yy{gkkm#//!$Nr,   )F)         D@F)r   )   r   F)__doc__r   typingr   rD   torch.nn.functionalnn
functionalr   kornia.core.utilsr   kornia.image.utilsr   r   Tensorintboolr+   r5   r;   r   rg   r{   r   r    r,   r*   <module>r      s  $ O      / 7   LQ7
,,7#(c?7DH7
5<<%&7t,ell ,uSRUX ,[`[g[g ,^=U\\ = = =
 UZ33(+39>3MQ3
\\3l5ELL 5 5 5pM&5<< M&u|| M&PUP\P\ M&`  !'$)	G<<GG S#XG "	G
 \\G Gr,   