o
    i~'                     @   s*  d dl T d dlmZ d dlZd dlZd dlZd dlmZ d dlZd dl	Z	ddl
mZ dFd	ejd
ejdeeeedf f dededejfddZdFd	ejd
ejdeeeedf f dededejfddZdejfdedededejdejf
ddZdejfddZdejfddZd ejdeejejf fd!d"Zd#ejfd$d%Zd&ejd'ejfd(d)Zd&ejd'ejdefd*d+ZdGd#ejd-ejded.eeef fd/d0Zd	ejdejfd1d2ZdHd4ejd-ejd5ed6efd7d8Zd9edejfd:d;Z d<ejd9edejfd=d>Z!	?dId@ejdAejdBedCedejf
dDdEZ"dS )J    )*)partialN)fftconvolve   )timeitFHz>xwaxis.keepdimsepsreturnc                 C   sH   |d u rt j| |dS || j}| | j|dt |j|d|d  S )Nr
   )npmeanastypedtypeclipr   r	   r
   r   r    r   4/data/cameron/moge_repo/moge/utils/geometry_numpy.pyweighted_mean_numpy   s   &r   c                 C   sT   |d u rddt | |d  j|d S || j}dtd| |  ||||d|  S )Nr   r   )r
   r   r   )r   r   r   r   r   r   r   r   r   r   harmonic_mean_numpy   s   "r   widthheightaspect_ratior   c           	      C   s   |du r| | }|d|d  d  }dd|d  d  }t j| | d  |  || d  |  | |d}t j| |d  | ||d  | ||d}t j||dd\}}t j||gdd	}|S )
zUV with left-top corner as (-width / diagonal, -height / diagonal) and right-bottom corner as (width / diagonal, height / diagonal)Nr            ?r   xy)indexingr   )r   linspacemeshgridstack)	r   r   r   r   span_xspan_yuvuvr   r   r   normalized_view_plane_uv_numpy   s   ,,r*   focalc                 C   s   dt d|   S )Nr   r   )r   arctanr+   r   r   r   focal_to_fov_numpy-      r.   fovc                 C   s   dt | d  S )Nr   r   )r   tan)r0   r   r   r   fov_to_focal_numpy1   r/   r2   
intrinsicsc                 C   s    t | d }t | d }||fS )N).r   r   ).r   r   )r.   )r3   fov_xfov_yr   r   r   intrinsics_to_fov_numpy5   s   r6   pointsc                 C   sR  | j dd \}}|d |d  d }t||| jd}t| dd df |\}}|| ddd f  jg | j d d dR  }tj| dd df | gddjg | j d d ddR  }|dd| }tj	|d	t
d  |dd|d
   d}	|	\}
}| d |d  }t|| |
 d }t|| |
 d }||||fS )Nr!   r   r   r   .r   gư>).N.r   ).NN)shaper*   r   r   broadcast_arraysreshaper$   swapaxeslinalginveyesqueezer,   )r7   r   r   diagonalr)   _bAMsolutionr+   shiftdepthr4   r5   r   r   r   point_map_to_depth_legacy_numpy;   s   .>4rK   r)   xyzc           
      C   s   ddl m} | dd|dddf dd|d d} }}dtjd	tjd
tjdtjfdd}|t|| ||dddd}|d  tj}||| dddf  }||  	 t
|	  }	||	fS )zKSolve `min |focal * xy / (z + shift) - uv|` with respect to shift and focalr   least_squaresr!   r   .Nr:   r)   r   zrI   c                 S   sF   ||| d d d f  }||    t|   }|| |   }|S N)sumr   squareravel)r)   r   rO   rI   xy_projferrr   r   r   fnT   s   z%solve_optimal_focal_shift.<locals>.fnMbP?lmx0Zftolmethodr   )scipy.optimizerN   r=   r   ndarrayr   rB   r   float32rQ   rR   )
r)   rL   rN   r   rO   rW   rH   optim_shiftrT   optim_focalr   r   r   solve_optimal_focal_shiftO   s   6"rb   c           	         s   ddl m} | dd|dddf dd|d d} }}dtjd	tjd
tjdtjf fdd}|t|| ||dddd}|d  tj}|S )zASolve `min |focal * xy / (z + shift) - uv|` with respect to shiftr   rM   r!   r   .Nr:   r)   r   rO   rI   c                    s,   ||| d d d f  } | |    }|S rP   )rS   )r)   r   rO   rI   rT   rV   r-   r   r   rW   h   s   zsolve_optimal_shift.<locals>.fnrX   rY   rZ   r   )	r]   rN   r=   r   r^   r   rB   r   r_   )	r)   rL   r+   rN   r   rO   rW   rH   r`   r   r-   r   solve_optimal_shiftc   s   6&rc   @   re   maskdownsample_sizec                 C   s   dd l }| jd dksJ d| jd | jd }}|d |d  d }t||d	}|d u rI|j| ||jd
dd}	|j|||jd
dd}
ntjj| |||d\}	}
}|	j	dk r]dS |d u rlt
|
|	\}}||fS t|
|	|}||fS )Nr   r!      zPoints should (H, W, 3)r8   r9   r   r   )r   r   )interpolation)rf   size)g      ?g        )cv2r;   r*   resizeZINTER_LINEARr=   utils3dr   Zmasked_nearest_resizerj   rb   rc   )r7   rf   r+   rg   rk   r   r   rC   r)   	points_lruv_lrmask_lrrI   r   r   r   recover_focal_shift_numpys   s    
rq   c                 C   s0   t t | d t | d  t | d  S )z2Faster `np.linalg.norm(x, axis=-1)` for 3D vectors).r   ).r   r:   )r   sqrtrR   )r   r   r   r   norm3d   s   0rs   皙?rJ   	thicknesstolc                 C   s   t |d|  d}t j|||fdd}t j|||fdd}d| d }tj j|||fddd}tj j|||fddd}	t||	dd}
||d| |
 k@ }||
d| | k@ }tj|t j	t j
dt j	d	|d
dktj|t j	t j
dt j	d	|d
dk@ }|S )Nr   r   )constant_valuesFr   )r9   r!   r   )rh   rh   r   
iterations)r   wherepadrm   sliding_windowr   rk   dilater   uint8ones)rJ   rf   ru   rv   dispZdisp_padZmask_padkernel_sizeZdisp_windowmask_windowZ	disp_meanZfg_edge_maskZbg_edge_maskZ	edge_maskr   r   r   depth_occlusion_edge_numpy   s   &&r   radiusc                 C   sT   t |  | d }t ||\}}|d |d  | d kt j}|t | }|S )z
    Generate disk kernel with given radius.
    
    Args:
        radius (int): Radius of the disk (in pixels).
    
    Returns:
        np.ndarray: (2*radius+1, 2*radius+1) normalized convolution kernel.
    r   r   )r   aranger#   r   r_   rQ   )r   LXYkernelr   r   r   disk_kernel   s
    r   imagec                 C   s   |dkr| S t |}| jdkrt| |dd}|S | jdkrBg }t| jd D ]}t| d|f |dd}|| q&tj|dd}|S td	)
z
    Apply disk blur to an image using FFT convolution.

    Args:
        image (np.ndarray): Input image, can be grayscale or color.
        radius (int): Blur radius (in pixels).

    Returns:
        np.ndarray: Blurred image.
    r   r   same)moderh   .r!   r   zImage must be 2D or 3D.)	r   ndimr   ranger;   appendr   r$   
ValueError)r   r   r   ZblurredchannelsiZblurred_channelr   r   r   	disk_blur   s   
	
r   
   imgr   
focus_dispmax_blur_radiusc                 C   sh  t |}|| }|| }g }t|d D ]}|tj|ttjd| d d| d fdd qt t	|| | d|
t j}t|d D ])}t t	|| | | d|
t j}||k||k@ || |k@ }	||	 ||	< qIt |d|}t|d}t |}
i }t|d D ]}||
vrqt| |||< qt | }|
D ]}||k}	|| |	 ||	< q|S )a  
    Apply depth of field effect to an image.

    Args:
        img (numpy.ndarray): (H, W, 3) input image.
        depth (numpy.ndarray): (H, W) depth map of the scene.
        focus_depth (float): Focus depth of the lens.
        strength (float): Strength of the depth of field effect.
        max_blur_radius (int): Maximum blur radius (in pixels).
        
    Returns:
        numpy.ndarray: (H, W, 3) output image with depth of field effect applied.
    r   r   rx   r   )   r   )r   maxr   r   rk   r}   ZgetStructuringElementZMORPH_ELLIPSEr   absr   int32Zbluruniquer   
zeros_like)r   r   r   r   Zmax_dispZdilated_dispr   Z
blur_radiiZdialted_blur_radiirf   Zunique_radiiprecomputedoutputrr   r   r   depth_of_field   s0   
6"&

r   )NNFr   )NNrd   )r   rt   )r   )#typing	functoolsr   mathrk   numpyr   Zscipy.signalr   rm   toolsr   r^   UnionintTupleboolfloatr   r   r_   r   r*   r.   r2   r6   rK   rb   rc   rq   rs   r   r   r   r   r   r   r   r   <module>   sF    ::* ( 