U
    (dK                     @   s  d dl Z d dlZd dlZd dlmZmZ d dlmZ d dlmZ d dl	Z
d dlZd dlmZ ddlmZ dd	lmZ dd
lmZ dZG dd deeZG dd deZG dd deZG dd deZG dd deZG dd deZdd Zdd Zdd ZdS )    N)ABCabstractmethod)globPath)Image   )_read_png_16   )verify_str_arg)VisionDataset)	KittiFlowSintelFlyingThings3DFlyingChairsHD1Kc                       sN   e Zd ZdZd fdd	Zdd Zedd Zd	d
 Zdd Z	dd Z
  ZS )FlowDatasetFNc                    s$   t  j|d || _g | _g | _d S )N)root)super__init__
transforms
_flow_list_image_list)selfr   r   	__class__ F/tmp/pip-unpacked-wheel-vx7f76es/torchvision/datasets/_optical_flow.pyr       s    zFlowDataset.__init__c                 C   s"   t |}|jdkr|d}|S )NZRGB)r   openmodeconvert)r   	file_nameimgr   r   r   	_read_img(   s    


zFlowDataset._read_imgc                 C   s   d S Nr   r   r!   r   r   r   
_read_flow.   s    zFlowDataset._read_flowc                 C   s   |  | j| d }|  | j| d }| jrT| | j| }| jrN|\}}q\d }nd  }}| jd k	r~| ||||\}}}}| js|d k	r||||fS |||fS d S )Nr   r
   )r#   r   r   r&   _has_builtin_flow_maskr   )r   indeximg1img2flowvalid_flow_maskr   r   r   __getitem__3   s    

zFlowDataset.__getitem__c                 C   s
   t | jS r$   )lenr   )r   r   r   r   __len__J   s    zFlowDataset.__len__c                 C   s   t jj| g| S r$   )torchutilsdataZConcatDataset)r   vr   r   r   __rmul__M   s    zFlowDataset.__rmul__)N)__name__
__module____qualname__r'   r   r#   r   r&   r-   r/   r4   __classcell__r   r   r   r   r      s   
r   c                       s6   e Zd ZdZd fdd	Z fddZd	d
 Z  ZS )r   a  `Sintel <http://sintel.is.tue.mpg.de/>`_ Dataset for optical flow.

    The dataset is expected to have the following structure: ::

        root
            Sintel
                testing
                    clean
                        scene_1
                        scene_2
                        ...
                    final
                        scene_1
                        scene_2
                        ...
                training
                    clean
                        scene_1
                        scene_2
                        ...
                    final
                        scene_1
                        scene_2
                        ...
                    flow
                        scene_1
                        scene_2
                        ...

    Args:
        root (string): Root directory of the Sintel Dataset.
        split (string, optional): The dataset split, either "train" (default) or "test"
        pass_name (string, optional): The pass to use, either "clean" (default), "final", or "both". See link above for
            details on the different passes.
        transforms (callable, optional): A function/transform that takes in
            ``img1, img2, flow, valid_flow_mask`` and returns a transformed version.
            ``valid_flow_mask`` is expected for consistency with other datasets which
            return a built-in valid mask, such as :class:`~torchvision.datasets.KittiFlow`.
    traincleanNc              	      s  t  j||d t|ddd t|ddd |dkr<dd	gn|g}t|d
 }|d d }|D ]}|dkrndn|}|| | }t|D ]|}	ttt||	 d }
t	t
|
d D ]$}|  j|
| |
|d  gg7  _q|dkr|  jttt||	 d 7  _qq^d S )Nr   r   splitr9   testZvalid_values	pass_namer:   finalbothrC   r:   rB   r   Ztrainingr+   r9   *.pngr
   *.flo)r   r   r   r   oslistdirsortedr   strranger.   r   r   )r   r   r<   r@   r   passesZ	flow_rootZ	split_dirZ
image_rootZsceneZ
image_listir   r   r   r   z   s    "zSintel.__init__c                    s   t  |S a  Return example at given index.

        Args:
            index(int): The index of the example to retrieve

        Returns:
            tuple: A 3-tuple with ``(img1, img2, flow)``.
            The flow is a numpy array of shape (2, H, W) and the images are PIL images.
            ``flow`` is None if ``split="test"``.
            If a valid flow mask is generated within the ``transforms`` parameter,
            a 4-tuple with ``(img1, img2, flow, valid_flow_mask)`` is returned.
        r   r-   r   r(   r   r   r   r-      s    zSintel.__getitem__c                 C   s   t |S r$   	_read_flor%   r   r   r   r&      s    zSintel._read_flow)r9   r:   Nr5   r6   r7   __doc__r   r-   r&   r8   r   r   r   r   r   Q   s   (r   c                       s:   e Zd ZdZdZd fdd	Z fddZd	d
 Z  ZS )r   a  `KITTI <http://www.cvlibs.net/datasets/kitti/eval_scene_flow.php?benchmark=flow>`__ dataset for optical flow (2015).

    The dataset is expected to have the following structure: ::

        root
            KittiFlow
                testing
                    image_2
                training
                    image_2
                    flow_occ

    Args:
        root (string): Root directory of the KittiFlow Dataset.
        split (string, optional): The dataset split, either "train" (default) or "test"
        transforms (callable, optional): A function/transform that takes in
            ``img1, img2, flow, valid_flow_mask`` and returns a transformed version.
    Tr9   Nc                    s   t  j||d t|ddd t|d |d  }ttt|d d }ttt|d d	 }|rj|srtd
t||D ]\}}|  j	||gg7  _	q||dkrttt|d d | _
d S )Nr;   r<   r=   r?   r   Zingimage_2z*_10.pngz*_11.pngzZCould not find the Kitti flow images. Please make sure the directory structure is correct.r9   flow_occ)r   r   r   r   rH   r   rI   FileNotFoundErrorzipr   r   )r   r   r<   r   images1images2r)   r*   r   r   r   r      s    zKittiFlow.__init__c                    s   t  |S )a  Return example at given index.

        Args:
            index(int): The index of the example to retrieve

        Returns:
            tuple: A 4-tuple with ``(img1, img2, flow, valid_flow_mask)``
            where ``valid_flow_mask`` is a numpy boolean mask of shape (H, W)
            indicating which flow values are valid. The flow is a numpy array of
            shape (2, H, W) and the images are PIL images. ``flow`` and ``valid_flow_mask`` are None if
            ``split="test"``.
        rN   rO   r   r   r   r-      s    zKittiFlow.__getitem__c                 C   s   t |S r$   )_read_16bits_png_with_flow_and_valid_maskr%   r   r   r   r&      s    zKittiFlow._read_flow)r9   N)	r5   r6   r7   rS   r'   r   r-   r&   r8   r   r   r   r   r      s
   r   c                       s6   e Zd ZdZd
 fdd	Z fddZdd	 Z  ZS )r   a  `FlyingChairs <https://lmb.informatik.uni-freiburg.de/resources/datasets/FlyingChairs.en.html#flyingchairs>`_ Dataset for optical flow.

    You will also need to download the FlyingChairs_train_val.txt file from the dataset page.

    The dataset is expected to have the following structure: ::

        root
            FlyingChairs
                data
                    00001_flow.flo
                    00001_img1.ppm
                    00001_img2.ppm
                    ...
                FlyingChairs_train_val.txt


    Args:
        root (string): Root directory of the FlyingChairs Dataset.
        split (string, optional): The dataset split, either "train" (default) or "val"
        transforms (callable, optional): A function/transform that takes in
            ``img1, img2, flow, valid_flow_mask`` and returns a transformed version.
            ``valid_flow_mask`` is expected for consistency with other datasets which
            return a built-in valid mask, such as :class:`~torchvision.datasets.KittiFlow`.
    r9   Nc           
         s  t  j||d t|ddd t|d }ttt|d d }ttt|d d }d	}tj	|| svt
d
tjt|| tjd}tt|D ]h}|| }	|dkr|	dks|dkr|	dkr|  j|| g7  _|  j|d|  |d| d  gg7  _qd S )Nr;   r<   )r9   valr?   r   r2   z*.ppmrE   zFlyingChairs_train_val.txtzmThe FlyingChairs_train_val.txt file was not found - please download it from the dataset page (see docstring).Zdtyper9   r
   r\   r   )r   r   r   r   rH   r   rI   rF   pathexistsrV   npZloadtxtZint32rJ   r.   r   r   )
r   r   r<   r   imagesflowsZsplit_file_nameZ
split_listrL   Zsplit_idr   r   r   r      s      zFlyingChairs.__init__c                    s   t  |S )a  Return example at given index.

        Args:
            index(int): The index of the example to retrieve

        Returns:
            tuple: A 3-tuple with ``(img1, img2, flow)``.
            The flow is a numpy array of shape (2, H, W) and the images are PIL images.
            ``flow`` is None if ``split="val"``.
            If a valid flow mask is generated within the ``transforms`` parameter,
            a 4-tuple with ``(img1, img2, flow, valid_flow_mask)`` is returned.
        rN   rO   r   r   r   r-     s    zFlyingChairs.__getitem__c                 C   s   t |S r$   rP   r%   r   r   r   r&     s    zFlyingChairs._read_flow)r9   NrR   r   r   r   r   r      s   r   c                       s6   e Zd ZdZd fdd	Z fdd	Zd
d Z  ZS )r   a  `FlyingThings3D <https://lmb.informatik.uni-freiburg.de/resources/datasets/SceneFlowDatasets.en.html>`_ dataset for optical flow.

    The dataset is expected to have the following structure: ::

        root
            FlyingThings3D
                frames_cleanpass
                    TEST
                    TRAIN
                frames_finalpass
                    TEST
                    TRAIN
                optical_flow
                    TEST
                    TRAIN

    Args:
        root (string): Root directory of the intel FlyingThings3D Dataset.
        split (string, optional): The dataset split, either "train" (default) or "test"
        pass_name (string, optional): The pass to use, either "clean" (default) or "final" or "both". See link above for
            details on the different passes.
        camera (string, optional): Which camera to return images from. Can be either "left" (default) or "right" or "both".
        transforms (callable, optional): A function/transform that takes in
            ``img1, img2, flow, valid_flow_mask`` and returns a transformed version.
            ``valid_flow_mask`` is expected for consistency with other datasets which
            return a built-in valid mask, such as :class:`~torchvision.datasets.KittiFlow`.
    r9   r:   leftNc              	      s  t  j||d t|ddd | }t|ddd dgdgddgd| }t d	d
d  dkrjddgn g}t|d }d}t|||D ]\\} ttt	|| | d }	t fdd|	D }	ttt	|d | d }
t fdd|
D }
|	r|
st
dt|	|
D ]\}}ttt	|d }ttt	|d }tt|d D ]}dkr|  j|| ||d  gg7  _|  j|| g7  _nBdkr^|  j||d  || gg7  _|  j||d  g7  _q^qqd S )Nr;   r<   r=   r?   r@   rA   Zframes_cleanpassZframes_finalpasscamera)rc   rightrC   rC   rc   re   r   )into_future	into_pastz*/*c                 3   s   | ]}t |  V  qd S r$   r   ).0	image_dir)rd   r   r   	<genexpr>U  s     z*FlyingThings3D.__init__.<locals>.<genexpr>Zoptical_flowc                 3   s   | ]}t |   V  qd S r$   r   )rh   flow_dirrd   	directionr   r   rj   X  s     zcCould not find the FlyingThings3D flow images. Please make sure the directory structure is correct.rD   z*.pfmr
   rf   rg   )r   r   r   upperr   	itertoolsproductrH   r   rI   rV   rW   rJ   r.   r   r   )r   r   r<   r@   rd   r   rK   ZcamerasZ
directionsZ
image_dirsZ	flow_dirsri   rk   ra   rb   rL   r   rl   r   r   @  sB    
 
 zFlyingThings3D.__init__c                    s   t  |S rM   rN   rO   r   r   r   r-   k  s    zFlyingThings3D.__getitem__c                 C   s   t |S r$   )	_read_pfmr%   r   r   r   r&   z  s    zFlyingThings3D._read_flow)r9   r:   rc   NrR   r   r   r   r   r   #  s   +r   c                       s:   e Zd ZdZdZd fdd	Zdd Z fd	d
Z  ZS )r   a  `HD1K <http://hci-benchmark.iwr.uni-heidelberg.de/>`__ dataset for optical flow.

    The dataset is expected to have the following structure: ::

        root
            hd1k
                hd1k_challenge
                    image_2
                hd1k_flow_gt
                    flow_occ
                hd1k_input
                    image_2

    Args:
        root (string): Root directory of the HD1K Dataset.
        split (string, optional): The dataset split, either "train" (default) or "test"
        transforms (callable, optional): A function/transform that takes in
            ``img1, img2, flow, valid_flow_mask`` and returns a transformed version.
    Tr9   Nc                    sJ  t  j||d t|ddd t|d }|dkrtdD ]}ttt|d d	 |d
d }ttt|d d |d
d }tt|d D ]8}|  j	|| g7  _	|  j
|| ||d  gg7  _
qq:nbttt|d d d }ttt|d d d }	t||	D ]\}
}|  j
|
|gg7  _
q| j
sFtdd S )Nr;   r<   r=   r?   Zhd1kr9   $   Zhd1k_flow_gtrU   Z06dz_*.pngZ
hd1k_inputrT   r
   Zhd1k_challengez*10.pngz*11.pngzTCould not find the HD1K images. Please make sure the directory structure is correct.)r   r   r   r   rJ   rH   r   rI   r.   r   r   rW   rV   )r   r   r<   r   Zseq_idxrb   ra   rL   rX   rY   Zimage1Zimage2r   r   r   r     s$    $$&zHD1K.__init__c                 C   s   t |S r$   rZ   r%   r   r   r   r&     s    zHD1K._read_flowc                    s   t  |S )a  Return example at given index.

        Args:
            index(int): The index of the example to retrieve

        Returns:
            tuple: A 4-tuple with ``(img1, img2, flow, valid_flow_mask)`` where ``valid_flow_mask``
            is a numpy boolean mask of shape (H, W)
            indicating which flow values are valid. The flow is a numpy array of
            shape (2, H, W) and the images are PIL images. ``flow`` and ``valid_flow_mask`` are None if
            ``split="test"``.
        rN   rO   r   r   r   r-     s    zHD1K.__getitem__)r9   N)	r5   r6   r7   rS   r'   r   r&   r-   r8   r   r   r   r   r   ~  s
   r   c              
   C   s   t | d}tj|ddd }|dkr0tdttj|ddd}ttj|ddd}tj|d	d
| | d}|||d
d
ddW  5 Q R  S Q R X dS )z#Read .flo file in Middlebury formatrbc   )counts   PIEHz)Magic number incorrect. Invalid .flo filez<i4r
   z<f4r   r   N)r   r`   fromfiletobytes
ValueErrorintreshape	transpose)r!   fmagicwhr2   r   r   r   rQ     s    rQ   c                 C   sf   t | tj}|d dd d d d f |dd d d d f  }}|d d }| }| | fS )Nr   i   @   )r	   tor0   float32boolnumpy)r!   Zflow_and_validr+   r,   r   r   r   r[     s
    2r[   c           	   	   C   s   t | d}|  }|dkr(tdtd| }|sDtddd | D \}}t|  }|dk r~d	}| }nd
}t	j
||d d}W 5 Q R X |||dddd}t	j|dd}|ddddddf }|t	jS )zRead flow in .pfm formatrs   s   PFzInvalid PFM files   ^(\d+)\s(\d+)\s$zMalformed PFM header.c                 s   s   | ]}t |V  qd S r$   )rz   )rh   Zdimr   r   r   rj     s     z_read_pfm.<locals>.<genexpr>r   <>r}   r]      r   r
   )ZaxisN)r   readlinerstripry   rematch	Exceptiongroupsfloatr`   rw   r{   r|   ZflipZastyper   )	r!   r}   headerZ	dim_matchr   r   ZscaleZendianr2   r   r   r   rq     s$    rq   )ro   rF   r   abcr   r   r   pathlibr   r   r`   r0   ZPILr   Zio.imager	   r1   r   Zvisionr   __all__r   r   r   r   r   r   rQ   r[   rq   r   r   r   r   <module>   s*   	7Q=D[C