Target Quality to use implemented percentile for weighted vmaf reading

This commit is contained in:
Zen 2020-11-25 11:15:36 +02:00
parent 1039217a4a
commit 330f33b07e
3 changed files with 44 additions and 33 deletions

View file

@ -5,9 +5,9 @@ from math import log as ln
import subprocess
from subprocess import STDOUT, PIPE
from .target_quality import make_pipes, vmaf_probe, transform_vmaf, weighted_search, get_target_q, adapt_probing_rate
from .target_quality import vmaf_probe, transform_vmaf, weighted_search, get_target_q, \
adapt_probing_rate, read_weighted_vmaf
from Projects import Project
from VMAF import read_weighted_vmaf
import matplotlib
from matplotlib import pyplot as plt

View file

@ -1,12 +1,11 @@
import subprocess
from subprocess import STDOUT, PIPE
from Av1an.commandtypes import CommandPair, Command
from Projects import Project
from VMAF import call_vmaf, read_weighted_vmaf
from VMAF import call_vmaf, read_json
from Chunks.chunk import Chunk
from math import isnan
from math import log as ln
from math import ceil, floor
from Av1an.bar import process_pipe
import numpy as np
from scipy import interpolate
@ -16,10 +15,47 @@ def transform_vmaf(vmaf):
if vmaf<99.99:
return -ln(1-vmaf/100)
else:
#return -ln(1-99.99/100)
# return -ln(1-99.99/100)
return 9.210340371976184
def read_weighted_vmaf(file, percentile=0):
"""Reads vmaf file with vmaf scores in it and return N percentile score from it.
:return: N percentile score
:rtype: float
"""
jsn = read_json(file)
vmafs = sorted([x['metrics']['vmaf'] for x in jsn['frames']])
percentile = percentile if percentile != 0 else 0.25
score = get_percentile(vmafs, percentile)
return round(score, 2)
def get_percentile(scores, percent):
"""
Find the percentile of a list of values.
:param scores: - is a list of values. Note N MUST BE already sorted.
:param percent: - a float value from 0.0 to 1.0.
:return: - the percentile of the values
"""
scores = sorted(scores)
key = lambda x: x
k = (len(scores)-1) * percent
f = floor(k)
c = ceil(k)
if f == c:
return key(scores[int(k)])
d0 = key(scores[int(f)]) * (c-k)
d1 = key(scores[int(c)]) * (k-f)
return d0+d1
def adapt_probing_rate(rate, frames):
"""
Change probing rate depending on amount of frames in scene.
@ -64,7 +100,6 @@ def get_target_q(scores, target_quality):
return int(q[0]), round(q[1], 3)
def weighted_search(num1, vmaf1, num2, vmaf2, target):
"""
Returns weighted value closest to searched
@ -86,7 +121,6 @@ def weighted_search(num1, vmaf1, num2, vmaf2, target):
return new_point
def probe_cmd(chunk: Chunk, q, ffmpeg_pipe, encoder, probing_rate) -> CommandPair:
"""
Generate and return commands for probes at set Q values
@ -95,8 +129,8 @@ def probe_cmd(chunk: Chunk, q, ffmpeg_pipe, encoder, probing_rate) -> CommandPai
should be faster than the actual encoding commands.
These should not be moved into encoder classes at this point.
"""
pipe = ['ffmpeg', '-y', '-hide_banner', '-loglevel', 'error', '-i', '-', '-vf', f'select=not(mod(n\\,{probing_rate}))',
*ffmpeg_pipe]
pipe = ['ffmpeg', '-y', '-hide_banner', '-loglevel', 'error', '-i', '-', '-vf',
f'select=not(mod(n\\,{probing_rate}))', *ffmpeg_pipe]
probe_name = gen_probes_names(chunk, q).with_suffix('.ivf').as_posix()

View file

@ -30,29 +30,6 @@ def read_json(file):
return fl
def read_weighted_vmaf(file, percentile=0):
"""Reads vmaf file with vmaf scores in it and return N percentile score from it.
:return: N percentile score
:rtype: float
"""
jsn = read_json(file)
vmafs = [x['metrics']['vmaf'] for x in jsn['frames']]
if percentile == 0:
# Using 2 standart deviations to weight for bad frames
mean = np.mean(vmafs)
minimum = np.min(vmafs)
score = (mean * 1/3) + (minimum * 2/3)
else:
score = round(np.percentile(vmafs, percentile), 2)
return round(score, 2)
def call_vmaf(chunk: Chunk, encoded: Path, n_threads, model, res,
fl_path: Path = None, vmaf_filter=None, vmaf_rate=0):
cmd = ''