mirror of
https://github.com/master-of-zen/Av1an.git
synced 2024-11-25 10:40:51 +00:00
Target Quality to use implemented percentile for weighted vmaf reading
This commit is contained in:
parent
1039217a4a
commit
330f33b07e
3 changed files with 44 additions and 33 deletions
|
@ -5,9 +5,9 @@ from math import log as ln
|
||||||
|
|
||||||
import subprocess
|
import subprocess
|
||||||
from subprocess import STDOUT, PIPE
|
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 Projects import Project
|
||||||
from VMAF import read_weighted_vmaf
|
|
||||||
|
|
||||||
import matplotlib
|
import matplotlib
|
||||||
from matplotlib import pyplot as plt
|
from matplotlib import pyplot as plt
|
||||||
|
|
|
@ -1,12 +1,11 @@
|
||||||
import subprocess
|
import subprocess
|
||||||
from subprocess import STDOUT, PIPE
|
from subprocess import STDOUT, PIPE
|
||||||
from Av1an.commandtypes import CommandPair, Command
|
from Av1an.commandtypes import CommandPair, Command
|
||||||
|
|
||||||
from Projects import Project
|
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 Chunks.chunk import Chunk
|
||||||
from math import isnan
|
|
||||||
from math import log as ln
|
from math import log as ln
|
||||||
|
from math import ceil, floor
|
||||||
from Av1an.bar import process_pipe
|
from Av1an.bar import process_pipe
|
||||||
import numpy as np
|
import numpy as np
|
||||||
from scipy import interpolate
|
from scipy import interpolate
|
||||||
|
@ -16,10 +15,47 @@ def transform_vmaf(vmaf):
|
||||||
if vmaf<99.99:
|
if vmaf<99.99:
|
||||||
return -ln(1-vmaf/100)
|
return -ln(1-vmaf/100)
|
||||||
else:
|
else:
|
||||||
#return -ln(1-99.99/100)
|
# return -ln(1-99.99/100)
|
||||||
return 9.210340371976184
|
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):
|
def adapt_probing_rate(rate, frames):
|
||||||
"""
|
"""
|
||||||
Change probing rate depending on amount of frames in scene.
|
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)
|
return int(q[0]), round(q[1], 3)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def weighted_search(num1, vmaf1, num2, vmaf2, target):
|
def weighted_search(num1, vmaf1, num2, vmaf2, target):
|
||||||
"""
|
"""
|
||||||
Returns weighted value closest to searched
|
Returns weighted value closest to searched
|
||||||
|
@ -86,7 +121,6 @@ def weighted_search(num1, vmaf1, num2, vmaf2, target):
|
||||||
return new_point
|
return new_point
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def probe_cmd(chunk: Chunk, q, ffmpeg_pipe, encoder, probing_rate) -> CommandPair:
|
def probe_cmd(chunk: Chunk, q, ffmpeg_pipe, encoder, probing_rate) -> CommandPair:
|
||||||
"""
|
"""
|
||||||
Generate and return commands for probes at set Q values
|
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.
|
should be faster than the actual encoding commands.
|
||||||
These should not be moved into encoder classes at this point.
|
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}))',
|
pipe = ['ffmpeg', '-y', '-hide_banner', '-loglevel', 'error', '-i', '-', '-vf',
|
||||||
*ffmpeg_pipe]
|
f'select=not(mod(n\\,{probing_rate}))', *ffmpeg_pipe]
|
||||||
|
|
||||||
probe_name = gen_probes_names(chunk, q).with_suffix('.ivf').as_posix()
|
probe_name = gen_probes_names(chunk, q).with_suffix('.ivf').as_posix()
|
||||||
|
|
||||||
|
|
23
VMAF/vmaf.py
23
VMAF/vmaf.py
|
@ -30,29 +30,6 @@ def read_json(file):
|
||||||
return fl
|
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,
|
def call_vmaf(chunk: Chunk, encoded: Path, n_threads, model, res,
|
||||||
fl_path: Path = None, vmaf_filter=None, vmaf_rate=0):
|
fl_path: Path = None, vmaf_filter=None, vmaf_rate=0):
|
||||||
cmd = ''
|
cmd = ''
|
||||||
|
|
Loading…
Reference in a new issue