
    iC                         d dl mZmZ d dlZd dlmZ d dlmZmZ erd dlZ	d dl
mZ ndgZerd dlmZ ded	efd
Z	 ddededed	eeeeef   f   fdZy)    )DictUnionN)Tensor)_EINOPS_AVAILABLE_TORCH_VMAF_AVAILABLE)VMAF$video_multi_method_assessment_fusion)	rearrangevideoreturnc                     | dddddddddf   }| dddddddddf   }| dddddddddf   }d|z  d|z  z   d|z  z   j                  d      dz  S )	z/Calculate the luma component of a video tensor.Nr         gA`"?gbX9?gv/?   )	unsqueeze)r   rgbs       w/Volumes/fast/ai/experiments/voice-extract-mac/.venv/lib/python3.12/site-packages/torchmetrics/functional/video/vmaf.pycalculate_lumar      sj    aAq!mAaAq!mAaAq!mAAI	!EAI-88;cAA    predstargetfeaturesc                 P   t         st        d      | j                  d   }| j                  | j                  }}t        |       }t        |      }t               j                  |      }|svt        |      D 	cg c].  }	|j                  t        ||	   d      t        ||	   d            0 }
}	t        j                  |
d      j                         j                  |      S t        |      D 	cg c].  }	|j                  t        ||	   d      t        ||	   d            0 }}	t        |      D 	cg c]&  }	||	   j                  t         j"                  d      ( }}	t        |      D 	cg c]K  }	||	   j$                  D ci c]0  }|dk7  s	|t        j&                  ||	   |   j(                  |	      2 c}M }}	}|d   D 	ci c]5  }|t        j*                  t        |      D 	cg c]
  }	||	   |    c}	      7 c}	}S c c}	w c c}	w c c}	w c c}w c c}}	w c c}	w c c}	}w )
a  Calculates Video Multi-Method Assessment Fusion (VMAF) metric.

    VMAF is a full-reference video quality assessment algorithm that combines multiple quality assessment features
    such as detail loss, motion, and contrast using a machine learning model to predict human perception of video
    quality more accurately than traditional metrics like PSNR or SSIM.

    The metric works by:

       1. Converting input videos to luma component (grayscale)
       2. Computing multiple elementary features:
          - Additive Detail Measure (ADM): Evaluates detail preservation at different scales
          - Visual Information Fidelity (VIF): Measures preservation of visual information across frequency bands
          - Motion: Quantifies the amount of motion in the video
       3. Combining these features using a trained SVM model to predict quality

    .. note::
        This implementation requires you to have vmaf-torch installed: https://github.com/alvitrioliks/VMAF-torch.
        Install either by cloning the repository and running `pip install .` or with `pip install torchmetrics[video]`.

    Args:
        preds: Video tensor of shape (batch, channels, frames, height, width). Expected to be in RGB format
            with values in range [0, 1].
        target: Video tensor of shape (batch, channels, frames, height, width). Expected to be in RGB format
            with values in range [0, 1].
        features: If True, all the elementary features (ADM, VIF, motion) are returned along with the VMAF score in
            a dictionary. This corresponds to the output you would get from the VMAF command line tool with the `--csv`
            option enabled. If False, only the VMAF score is returned as a tensor.

    Returns:
        - If `features` is False, returns a tensor with shape (batch, frame) of VMAF score for each frame in
          each video. Higher scores indicate better quality, with typical values ranging from 0 to 100.

        - If `features` is True, returns a dictionary where each value is a (batch, frame) tensor of the
          corresponding feature. The keys are:

            - 'integer_motion2': Integer motion feature
            - 'integer_motion': Integer motion feature
            - 'integer_adm2': Integer ADM feature
            - 'integer_adm_scale0': Integer ADM feature at scale 0
            - 'integer_adm_scale1': Integer ADM feature at scale 1
            - 'integer_adm_scale2': Integer ADM feature at scale 2
            - 'integer_adm_scale3': Integer ADM feature at scale 3
            - 'integer_vif_scale0': Integer VIF feature at scale 0
            - 'integer_vif_scale1': Integer VIF feature at scale 1
            - 'integer_vif_scale2': Integer VIF feature at scale 2
            - 'integer_vif_scale3': Integer VIF feature at scale 3
            - 'vmaf': VMAF score for each frame in each video

    Example:
        >>> import torch
        >>> from torchmetrics.functional.video import video_multi_method_assessment_fusion
        >>> # 2 videos, 3 channels, 10 frames, 32x32 resolution
        >>> preds = torch.rand(2, 3, 10, 32, 32, generator=torch.manual_seed(42))
        >>> target = torch.rand(2, 3, 10, 32, 32, generator=torch.manual_seed(43))
        >>> vmaf_score = video_multi_method_assessment_fusion(preds, target)
        >>> torch.round(vmaf_score, decimals=2)
        tensor([[ 9.9900, 15.9000, 14.2600, 16.6100, 15.9100, 14.3000, 13.5800, 13.4900, 15.4700, 20.2800],
                [ 6.2500, 11.3000, 17.3000, 11.4600, 19.0600, 14.9300, 14.0500, 14.4100, 12.4700, 14.8200]])
        >>> vmaf_dict = video_multi_method_assessment_fusion(preds, target, features=True)
        >>> # show a couple of features, more features are available
        >>> vmaf_dict['vmaf'].round(decimals=2)
        tensor([[ 9.9900, 15.9000, 14.2600, 16.6100, 15.9100, 14.3000, 13.5800, 13.4900, 15.4700, 20.2800],
                [ 6.2500, 11.3000, 17.3000, 11.4600, 19.0600, 14.9300, 14.0500, 14.4100, 12.4700, 14.8200]])
        >>> vmaf_dict['integer_adm2'].round(decimals=2)
        tensor([[0.4500, 0.4500, 0.3600, 0.4700, 0.4300, 0.3600, 0.3900, 0.4100, 0.3700, 0.4700],
                [0.4200, 0.3900, 0.4400, 0.3700, 0.4500, 0.3900, 0.3800, 0.4800, 0.3900, 0.3900]])

    zSvmaf-torch is not installed. Please install with `pip install torchmetrics[video]`.r   zc f h w -> f c h wr   )dimcoerce)errorsFrame)dtype)r   RuntimeErrorshaper    devicer   r   torangecompute_vmaf_scorer
   torchcatttableapplypd
to_numericcolumnstensorvaluesstack)r   r   r   r   
orig_dtyper#   
preds_lumatarget_lumavmafr   scoresscores_and_featuresdfscolresults                  r   r	   r	   '   s=   R !pqqAAellJ&J (K699VD 
 q	
 " ##+e,.BCYzZ_O`bvEw "	 	 
 yyQ'))+..z:: 1X	 E 	

k%(*>?:V[K\^rAs	
 	   Z__`Ya
bYaPUu%++BMM(+KYaC
b 1XE QTTYPZPbPbuPbfimtftell3u:c?11D	DPbu   U[[\T]^T]SCeAhGhUfUmC0hGHHT]^^'
 cu H^sH   73H-3H/+H*H 
H*H5H"H"'H6	H"HH")F)typingr   r   r'   r   torchmetrics.utilities.importsr   r   pandasr,   
vmaf_torchr   __doctest_skip__einopsr
   r   boolstrr	    r   r   <module>rD      s       S>? B& BV B g_g_g_ g_ 64V$$%	g_r   