U
    d                     @   sf   d Z ddlZddlmZmZ dd Zdd ZG dd	 d	eZ	e	 Z
G d
d deZG dd deZdS )a(  Functions that could be used to visualize Tensors.

This is adapted from the old-time iceberk package that Yangqing wrote... Oh gold
memories. Before decaf and caffe. Why iceberk? Because I was at Berkeley,
bears are vegetarian, and iceberg lettuce has layers of leaves.

(This joke is so lame.)
    N)cmpyplotc                 C   s*   | j }| |d |d |d |d S )zConvert a HWC array to CHW.         ndimswapaxesZarrr    r   ;/tmp/pip-unpacked-wheel-ua33x9lu/caffe2/python/visualize.pyChannelFirst   s    r   c                 C   s*   | j }| |d |d |d |d S )zConvert a CHW array to HWC.r   r   r   r   r
   r   r   r   ChannelLast   s    r   c                   @   sV   e Zd ZdZdddZdddZddejfdd	Zd
d Z	dejfddZ
dd ZdS )PatchVisualizerz&PatchVisualizer visualizes patches.
  r   c                 C   s
   || _ d S N)gap)selfr   r   r   r   __init__    s    zPatchVisualizer.__init__Nc                 C   sr   t |jdkr || |}n$t |jdkrD|jd dkrDtdt |jdkr`|dkr`tj}tj||d |S )zVisualizes one single patch.

    The input patch could be a vector (in which case we try to infer the shape
    of the patch), a 2-D matrix, or a 3-D matrix whose 3rd dimension has 3
    channels.
    r   r   r   $The input patch shape isn't correct.N)cmap)	lenshapereshapeget_patch_shape
ValueErrorr   grayr   imshow)r   patchr   r   r   r   
ShowSingle#   s    zPatchVisualizer.ShowSinglec                 C   s  |j d }|dkr&ttt|}tt|t| }t|j dkrj||j d f| |d  }t	|j dd | j
 }|t	||g | j
 }t|j dkr|j d dkr||j dd }t|}	|dkrtj}n&|j d dkrt|d }	ntd	nt|}	|dkr&tj}t|	|| }
t|D ]R}|| |d  }|| |d  }|| |
|||j d  |||j d  f< q@tj|
|d
d td |
S )a3  Visualize multiple patches.

    In the passed in patches matrix, each row is a patch, in the shape of either
    n*n, n*n*1 or n*n*3, either in a flattened format (so patches would be a
    2-D array), or a multi-dimensional tensor. We will try our best to figure
    out automatically the patch size.
    r   Nr   r   r      )r   z%The input patch shape isn't expected.Znearest)r   interpolationoff)r   intnpceilsqrtfloatr   r   r   arrayr   tupler   r   r   Zonesranger   r   Zaxis)r   patchesZncolsr   bg_funcZnum_patchesZnrowsZpatch_size_expandZ
image_sizeZimage_shapeimagepidrowcolr   r   r   ShowMultiple4   s>    


*
zPatchVisualizer.ShowMultiplec                 O   s<   |t | }|t |t t jj  }| j|f||S )z~Similar to ShowMultiple, but always normalize the values between 0 and 1
    for better visualization of image-type data.
    )r$   minmaxZfinfoZfloat64Zepsr1   )r   r+   argskwargsr   r   r   
ShowImages`   s    zPatchVisualizer.ShowImagesc                 C   s6   t |jdkrtdt|jdd}| j|||dS )z This function shows the channels of a patch.

    The incoming patch should have shape [w, h, num_channels], and each channel
    will be visualized as a separate gray patch.
    r   r   r   r   )r   r,   )r   r   r   r$   r	   Tr1   )r   r   r   r,   Zpatch_reorderedr   r   r   ShowChannelsh   s    zPatchVisualizer.ShowChannelsc                 C   s^   t |j}|t |krJt |jd }|t |kr@td||dfS t|}||fS dS )zGets the shape of a single patch.

    Basically it tries to interpret the patch as a square, and also check if it
    is in color (3 channels)
    g      @z#I can't figure out the patch shape.r   N)r$   r&   sizefloorr   r#   )r   r   ZedgeLenr   r   r   r   s   s    
zPatchVisualizer.get_patch_shape)r   )N)__name__
__module____qualname____doc__r   r   r$   Zmeanr1   r6   r8   r   r   r   r   r   r      s   

,r   c                   @   s<   e Zd Zedd Zedd Zedd Zedd Zd	S )
NHWCc                  O   s   t j| | d S r   )_default_visualizerr   r4   r5   r   r   r   r      s    zNHWC.ShowSinglec                  O   s   t j| | d S r   )r@   r1   rA   r   r   r   r1      s    zNHWC.ShowMultiplec                  O   s   t j| | d S r   )r@   r6   rA   r   r   r   r6      s    zNHWC.ShowImagesc                  O   s   t j| | d S r   )r@   r8   rA   r   r   r   r8      s    zNHWC.ShowChannelsNr;   r<   r=   staticmethodr   r1   r6   r8   r   r   r   r   r?      s   


r?   c                   @   s<   e Zd Zedd Zedd Zedd Zedd Zd	S )
NCHWc                 O   s   t jt| f|| d S r   )r@   r   r   r   r4   r5   r   r   r   r      s    zNCHW.ShowSinglec                 O   s   t jt| f|| d S r   )r@   r1   r   rE   r   r   r   r1      s    zNCHW.ShowMultiplec                 O   s   t jt| f|| d S r   )r@   r6   r   rE   r   r   r   r6      s    zNCHW.ShowImagesc                 O   s   t jt| f|| d S r   )r@   r8   r   rE   r   r   r   r8      s    zNCHW.ShowChannelsNrB   r   r   r   r   rD      s   


rD   )r>   Znumpyr$   Z
matplotlibr   r   r   r   objectr   r@   r?   rD   r   r   r   r   <module>   s   	i	