o
    Fi#                     @  s   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mZm	Z	 d dl
Zd dlmZmZ d dlmZ d dlmZ g dZerEd dlad	and
\aadd ZG dd dZG dd dZG dd deeZG dd deeZdS )    )annotationsN)Callable)TYPE_CHECKINGAny)DatasetIterableDataset)
ColorOrder)optional_import)VideoDatasetVideoFileDatasetCameraDatasetT)NNc                   C  s   t d\aadS )zYImport cv2. Put it inside a function to avoid webcam lights blinking on ``import monai``.cv2N)r	   r   has_cv2 r   r   R/root/miniconda3/envs/fpt/lib/python3.10/site-packages/monai/data/video_dataset.py	import_cv$   s   r   c                   @  s    e Zd ZdZdd Zdd ZdS )SuppressStderrzQSuppress stderr. Useful as OpenCV (and dependencies) can produce a lot of output.c                 C  sT   t tjd| _tj | _ttj | _	tj| _
t| j | j | jt_| S )Nw)openosdevnullerrnull_filesysstderrfilenoold_stderr_fileno_undupdupold_stderr_fileno
old_stderrdup2selfr   r   r   	__enter__.   s   zSuppressStderr.__enter__c                 G  s2   | j t_t| j| j t| j | j  d S N)	r   r   r   r   r   r   r   closer   )r!   _r   r   r   __exit__7   s   zSuppressStderr.__exit__N)__name__
__module____qualname____doc__r"   r&   r   r   r   r   r   +   s    	r   c                   @  sT   e Zd Ze  ddejddfdddZedddZdd Z	dddZ
d ddZdS )!r
   NFr   video_source	str | int	transformCallable | Nonemax_num_frames
int | Nonecolor_orderstrmultiprocessingboolchannel_dimintreturnNonec                 C  sP   t std|tvrt|| _|| _|| _|| _|s | || _	|| _
|| _dS )a  
        Base video dataset.

        Args:
            video_source: filename of video.
            transform: transform to be applied to each frame.
            max_num_frames: Max number of frames to iterate across. If `None` is passed,
                then the dataset will iterate until the end of the file.
            color_order: Color order to return frame. Default is RGB.
            multiprocessing: If `True`, open the video source on the fly. This makes
                things process-safe, which is useful when combined with a DataLoader
                with `num_workers>0`. However, when using with `num_workers==0`, it
                makes sense to use `multiprocessing=False`, as the source will then
                only be opened once, at construction, which will be faster in those
                circumstances.
            channel_dim: OpenCV reads with the channel as the last dimension. Use this
                flag to move it elsewhere. By default this is zero, so the channel
                dimension is moved to the front.

        Raises:
            RuntimeError: OpenCV not installed.
            NotImplementedError: Unknown color order.
        zOpenCV not installed.N)r   RuntimeErrorr   NotImplementedErrorr1   r5   r+   r3   
open_videocapr-   r/   )r!   r+   r-   r/   r1   r3   r5   r   r   r   __init__B   s    
zVideoDataset.__init__c                 C  sl   t | trtj| std|  t  t| }W d   n1 s$w   Y  |	 s4td|  |S )a0  
        Use OpenCV to open a video source from either file or capture device.

        Args:
            video_source: filename or index referring to capture device.

        Raises:
            RuntimeError: Source is a file but file not found.
            RuntimeError: Failed to open source.
        zVideo file does not exist: NzFailed to open video: )

isinstancer2   r   pathisfiler9   r   r   VideoCaptureZisOpened)r+   r<   r   r   r   r;   p   s   zVideoDataset.open_videoc                 C  s   | j r	| | jS | jS )zaReturn the cap. If multiprocessing, create a new one. Else return the one from construction time.)r3   r;   r+   r<   r    r   r   r   _get_cap   s   zVideoDataset._get_capc                 C  s   |   tjS )z"Get the FPS of the capture device.)rB   getr   ZCAP_PROP_FPSr    r   r   r   get_fps   s   zVideoDataset.get_fpsr   c                 C  s^   |    \}}|std| jtjkrt|tj}t	
|d| j}| jdur-| |S |S )zGet next frame. For a file, this will be the next frame, whereas for a camera
        source, it will be the next available frame.zFailed to read frame.N)rB   readr9   r1   r   RGBr   ZcvtColorZCOLOR_BGR2RGBnpZmoveaxisr5   r-   )r!   retframer   r   r   	get_frame   s   zVideoDataset.get_frame)r+   r,   r-   r.   r/   r0   r1   r2   r3   r4   r5   r6   r7   r8   )r+   r,   r7   r6   )r7   r   )r'   r(   r)   r   r   rG   r=   staticmethodr;   rB   rD   rK   r   r   r   r   r
   >   s    .
r
   c                   @  sD   e Zd ZdZdddZedddZdd
dZdd ZdddZ	dS )r   zU
    Video dataset from file.

    This class requires that OpenCV be installed.
    r7   r8   c                 O  sB   t j| g|R i | |  }| jd u s|| jk r|| _d S d S r#   )r
   r=   get_num_framesr/   )r!   argskwargs
num_framesr   r   r   r=      s
   
zVideoFileDataset.__init__dict[str, str]c            	   	   C  s   t si S ddddddd} i }t S t 6}|  D ])\}}t }tj	|d| }tj
| }|||dd}|rA|||< |  qW d   n1 sPw   Y  W d   |S W d   |S 1 shw   Y  |S )	zTry different codecs, see which are available.
        Returns a dictionary with of available codecs with codecs as keys and file extensions as values.z.mp4z.aviz.mjpeg)Zmp4vZX264ZH264ZMP42ZMJPGZDIVXtest   )
   rU   N)r   r   tempfileTemporaryDirectoryitemsr   ZVideoWriterr   r?   joinZVideoWriter_fourccr   release)	Z
all_codecscodecsZtmp_dircodecextwriterfnameZfourccZnoviderrr   r   r   get_available_codecs   s.   







z%VideoFileDataset.get_available_codecsr6   c                 C  s(   t |  tj}|dkrtd|S )zz
        Return the number of frames in a video file.

        Raises:
            RuntimeError: no frames found.
        r   z0 frames found)r6   rB   rC   r   ZCAP_PROP_FRAME_COUNTr9   )r!   rQ   r   r   r   rN      s   zVideoFileDataset.get_num_framesc                 C  s   | j S r#   )r/   r    r   r   r   __len__   s   zVideoFileDataset.__len__indexr   c                 C  s2   | j dur|| j krt|  tj| |  S )z4
        Fetch single data item from index.
        N)r/   
IndexErrorrB   setr   ZCAP_PROP_POS_FRAMESrK   )r!   rb   r   r   r   __getitem__   s   zVideoFileDataset.__getitem__N)r7   r8   )r7   rR   rL   )rb   r6   r7   r   )
r'   r(   r)   r*   r=   rM   r`   rN   ra   re   r   r   r   r   r      s    

r   c                   @  s&   e Zd ZdZed	ddZdd ZdS )
r   a  
    Video dataset from a capture device (e.g., webcam).

    This class requires that OpenCV be installed.

    Args:
        video_source: index of capture device.
            `get_num_devices` can be used to determine possible devices.
        transform: transform to be applied to each frame.
        max_num_frames: Max number of frames to iterate across. If `None` is passed,
            then the dataset will iterate infinitely.

    Raises:
        RuntimeError: OpenCV not installed.
    r7   r6   c                  C  s<   t sdS d} 	 t| }| d s	 | S | d7 } |  q)zOGet number of possible devices detected by OpenCV that can be used for capture.r   TrT   )r   r   rA   rF   rZ   )Znum_devicesr<   r   r   r   get_num_devices   s   
zCameraDataset.get_num_devicesc                 c  s8    d}	 |   }|d7 }|V  | jd ur|| jkrd S q)Nr   TrT   )rK   r/   )r!   Zframe_countrJ   r   r   r   __iter__   s   

zCameraDataset.__iter__NrL   )r'   r(   r)   r*   rM   rf   rg   r   r   r   r   r      s
    r   )
__future__r   r   r   rV   collections.abcr   typingr   r   numpyrH   Ztorch.utils.datar   r   Zmonai.utils.enumsr   Zmonai.utils.moduler	   __all__r   r   r   r   r
   r   r   r   r   r   r   <module>   s(   \: