+
    اj$                     :    R t ^ RIt^ RItR tRR ltR tRR ltR# )z]
KMeans algorithm for image color palette extraction.
Manual implementation without sklearn.
Nc                0    ^ RI Hp VP                  V 4      P                  R4      pVP	                  RVP
                  P                  4       \        P                  ! V\        P                  R7      P                  R^4      pV#   \         d     R# i ; i)z
Load image and return pixel array as (N, 3) float32 numpy array.

Args:
    image_path: absolute path to the image file

Returns:
    np.ndarray of shape (N, 3) with RGB values in [0, 255], or None on error
)ImageRGBdtypeN)d   r   )PILr   openconvert	thumbnail
ResamplingLANCZOSnparrayfloat32reshape	Exception)
image_pathr   imgpixelss   &   O/Users/jokubas/Desktop/KTU/big_data/engineering/processing/algorithms/kmeans.pyload_image_pixelsr   	   su    jj$,,U3j%"2"2":":;#RZZ088Q? s   BB BBc                2   \        V 4      pV^ 8X  dO   \        P                  ! V^3\        P                  R7      \        P                  ! V\        P                  R7      3# \        W4      p\        P                  ! V4      p. pVP                  ^ V^,
          4      pVP                  W,          P                  4       4       \        ^V4       EF_  p	\        P                  ! V\        P                  R7      p
V R\        P                  R3,          V
\        P                  RR3,          ,
          p\        P                  ! V^,          ^R7      p\        P
                  ! V^R7      p\        \        P                  ! V4      4      pV^ 8X  d   VP                  ^ V^,
          4      pM`W,          p\        P                   ! V4      pVP                  4       p\#        \        P$                  ! VV4      4      p\        W^,
          4      pVP                  W,          P                  4       4       EKb  	  \        P                  ! V\        P                  R7      p\        P                  ! V\        P                  R7      p\        V4       EF  pV R\        P                  R3,          V\        P                  RR3,          ,
          p\        P                  ! V^,          ^R7      p\        P&                  ! V^R7      P)                  \        P                  4      p\        P*                  ! V4      p\        V4       Fj  pVV8H  p\        P,                  ! V4      '       d%   \        P.                  ! V V,          ^ R7      VV&   KH  WP                  ^ V^,
          4      ,          VV&   Kl  	  \        \        P0                  ! \        P2                  ! \        P                  ! VV,
          ^,          ^R7      4      4      4      pTpTpVV8  g   EK   VV3# 	  VV3# )ab  
Manual KMeans implementation.

Args:
    pixels: np.ndarray of shape (N, 3)
    k: number of clusters
    max_iter: maximum iterations
    tol: convergence tolerance (centroid shift)
    seed: random seed

Returns:
    (centroids, assignments)
    - centroids: np.ndarray of shape (k, 3)
    - assignments: np.ndarray of shape (N,) with cluster indices
r   :NNNaxis)lenr   zerosr   int32minrandomRandomrandintappendcopyranger   newaxissumfloatcumsumintsearchsortedargminastype
zeros_likeanymeanmaxsqrt)r   kmax_itertolseednrng	centroids	first_idx_centroid_arrdiffssq_distsmin_sq_diststotalidxprobscumprobsrassignments	iterationnew_assignmentsnew_centroidsjmaskshifts   &&&&&                     r   kmeansrL      s     	FAAvxxAbjj1288ARXX3NNNA	A
--
C IAq1u%IV&++-.1a[xx	<q"**a'(<

Aq8H+II66%1*1-vvhQ/ bff\*+A:++aQ'C (Eyy'H

Abooh23Ccq5/C))+,' * "**5I((1BHH-K8_	q"**a'(9RZZA5E+FF66%1*1-))H15<<RXXF i0qA"a'Dvvd||#%776$<a#@a  $*++aQ*?#@a   bffRWWRVV]Y-F1,LST%UVWX!	%3;k!!1 %0 k!!    c                   \        V 4      p\        P                  ! WR7      p\        P                  ! V) 4      pW,          pW28  dI   \        P                  ! W#,
          ^3\        P
                  R7      p\        P                  ! Wg.^ R7      pMW28  d   VRV pVP                  4       R,          pVP                  \        P
                  4      # )z
Sort clusters by size (descending) and return flat RGB feature vector.

Args:
    centroids: np.ndarray of shape (k, 3)
    assignments: np.ndarray of shape (N,)
    k: number of clusters

Returns:
    np.ndarray of length k*3 (float32)
)	minlengthr   r   Ng     o@)	r   r   bincountargsortr   r   concatenateflattenr-   )	r9   rE   r3   k_actualcountsordersorted_centroidspadfeature_vectors	   &&&      r   build_feature_vectorrZ   n   s     9~H[[9FJJwE ' |hha(

;>>+;*AJ	+BQ/ &--/%7N  ,,rM   c                    \        V 4      pVe   \        V4      ^ 8X  d   R#  \        W!R7      w  r4\        W4V4      pV#   \         d     R# i ; i)z
Full pipeline: load image -> run KMeans -> return feature vector.

Args:
    image_path: absolute path to the image file
    k: number of color clusters

Returns:
    np.ndarray of length k*3, or None if error
N)r3   )r   r   rL   rZ   r   )r   r3   r   r9   rE   rY   s   &&    r   compute_image_featurer\      sW     z*F~V)!'!4	-iaH s   ? AA)
      g      ?*   )r]   )__doc__numpyr   r    r   rL   rZ   r\    rM   r   <module>rc      s(     *M"`->rM   