Skip to content

Commit

Permalink
added extra garbage
Browse files Browse the repository at this point in the history
  • Loading branch information
dwiandhikaap committed May 19, 2021
1 parent 6451da9 commit d8f4add
Show file tree
Hide file tree
Showing 5 changed files with 92 additions and 73 deletions.
10 changes: 10 additions & 0 deletions Exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,15 @@ def __init__(self,message="The given output resolution value is invalid!"):

class VideoReadError(Exception):
def __init__(self,message="Unable to read video file!"):
self.message = message
super().__init__(self.message)

class InvalidCustomWeighting(Exception):
def __init__(self,message="Invalid custom weighting function!"):
self.message = message
super().__init__(self.message)

class InvalidBlendMode(Exception):
def __init__(self,message="Invalid blending mode!"):
self.message = message
super().__init__(self.message)
14 changes: 7 additions & 7 deletions SettingsLoader.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import argparse
import json

def load():
def loadSettings():
settingsJson = None
with open("settings.json") as settings:
settingsJson = json.load(settings)
Expand All @@ -20,12 +20,12 @@ def load():
help="""Framerate/FPS of the output file.\
\nExample : -fps 60""")

args_parser.add_argument("-m", "--blend_mode", type=int, default=settingsJson["blend_mode"],
help="""Weighting mode.\
\nTODO : add more explanation on this""")
args_parser.add_argument("-m", "--blend_mode", type=str, default=settingsJson["blend_mode"],
help="""Choose blending mode. (Check the GitHub readme for more info)\
\nExample : -m GAUSSIAN_SYM, -m EQUAL""")

args_parser.add_argument("-r", "--blend_range", type=float, default=settingsJson["blend_range"],
help="""Range or Blend Range is the number that you get from how many frames resampled divided by the ratio between input and output fps.\
help="""Range or Blend Range is the number that you get from calculating how many frames are resampled divided by the ratio between input and output fps.\
\nTips : Use value between 1.0 - 2.0, above 3.5 will cause blurry effect. This will also impact resampling performance""")

args_parser.add_argument("-res", "--resolution", type=str, default=settingsJson["resolution"],
Expand All @@ -37,10 +37,10 @@ def load():
\nExample : -fourcc MJPG""")

args_parser.add_argument("-cvfix", "--cv_colourfix", action='store_true', default=settingsJson["cv_colourfix"],
help="""Enable this if you're resampling video produced by osr2mp4 or anything that uses default OpenCV video writer codec\
help="""Enable this if you're resampling video produced by osr2mp4.\
\nExample : -cvfix""")

args_parser.add_argument('--version', action='version', version='HFR-Resampler v0.3')
args_parser.add_argument('--version', action='version', version='HFR-Resampler v0.4')


parsed_args = args_parser.parse_args()
Expand Down
110 changes: 52 additions & 58 deletions Weights.py
Original file line number Diff line number Diff line change
@@ -1,94 +1,88 @@
import math
import numpy as np
from enum import IntEnum
import json

class Mode(IntEnum):
CUSTOM = 0
EQUAL = 1
GAUSS = 2
GAUSS_SYM = 3
PYRAMID = 4
PYRAMID_SYM = 5
SIVEROO_1 = 6
SIVEROO_2 = 7
from Exceptions import *

#This function will return an list of value, like below:
settingsJson = None
with open("settings.json") as settings:
settingsJson = json.load(settings)["blend_settings"]

# This function will return an list of value, like below:
# [0,1,2,3,...,n] -> [a,...,b]
def scaleRange(n,a,b):
return [(x*(b-a)/(n-1))+a for x in range(0,n)]

def equal(n):
return [1/n]*n

def gauss(n):
r = range(n,0,-1)
val = [math.exp(-(2.0*x/n)**2) for x in r]
def gauss(n, c, bound):
r = scaleRange(n, bound[0], bound[1])
val = [math.exp(-((x)**2)/(2*(c**2))) for x in r]
val = val/np.sum(val)
return val

def gauss_sym(n):
n = n/2
r = range(int(n),-math.ceil(n),-1)
val = ([math.exp(-(2.0*x/(n))**2) for x in r])
def gauss_sym(n, c, bound):
r = scaleRange(n, -np.amax(np.abs(bound)), np.amax(np.abs(bound)))
val = [math.exp(-((x)**2)/(2*(c**2))) for x in r]
val = val/np.sum(val)
return val

def pyramid(n):
r = range(1,n+1)
val = [x/n for x in r]
def pyramid(n, reverse):
val = []
if reverse:
val = [x for x in range(n,0,-1)]
else:
val = [x for x in range(1,n+1)]
val = val/np.sum(val)
return val

def pyramid_sym(n):
r = range(0,n)
val = [(n/2)-abs(x-(n-1)/2) for x in r]
val = [((n-1)/2-abs(x-((n-1)/2))+1) for x in r]
val = val/np.sum(val)
return val

def siveroo1(n):
r = scaleRange(n,-3,0.1)
val = [math.floor(3*math.exp(-(x/1.9)**2))/3+0.1 for x in r]
def funcEval(func,nums):
try:
return eval(f"[({func}) for x in nums]")
except NameError as e:
raise InvalidCustomWeighting

def custom(n, func="", bound=(0,1)):
r = scaleRange(n, bound[0], bound[1])
val = funcEval(func, r)
if np.amin(val) < 0: val -= np.amin(val)
val = val/np.sum(val)
return val

# this function will stretch the given array (w) to a specific length (n)
# example : n = 10, w = [1,2]
# result : val = [1,1,1,1,1,2,2,2,2,2] , flip it, and then normalize it so its sum is equal to 1
def stretch(n,w):
r = scaleRange(n,0,len(w)-0.1)

# This function will stretch the given array (weights) to a specific length (n)
# Example : n = 10, weights = [1,2]
# Result : val = [1,1,1,1,1,2,2,2,2,2], then normalize it to [0.0667, 0.0667, 0.0667, 0.0667, 0.0667, 0.1333, 0.1333, 0.1333, 0.1333, 0.1333]
def divide(n,weights):
r = scaleRange(n,0,len(weights)-0.1)
val = []
idx = [math.floor(x) for x in r]
for x in range(0,n):
index = int(idx[x])
val.append(w[index])
val = val/np.sum(val)
val.append(weights[index])
if np.amin(val) < 0: val -= np.amin(val)
val = (val/np.sum(val))
return val

def null(n):
return [0]*n

def weight(mode,count):
if count == 1:
return [1.0]
return [1.0] # If only one frame is weighted, it's weight is always going to be 1.
else:
return {
Mode.EQUAL : equal(count),
Mode.GAUSS : gauss(count),
Mode.GAUSS_SYM : gauss_sym(count),
Mode.PYRAMID : pyramid(count),
Mode.PYRAMID_SYM : pyramid_sym(count),
Mode.SIVEROO_1 : siveroo1(count),
Mode.SIVEROO_2 : stretch(count,[1,3,3,2,2])
}[mode]

def modeName(mode):
return {
Mode.EQUAL : "[1] Equal",
Mode.GAUSS : "[2] Gaussian Asymmetric",
Mode.GAUSS_SYM : "[3] Gaussian Symmetric",
Mode.PYRAMID : "[4] Pyramid Asymmetric",
Mode.PYRAMID_SYM : "[5] Pyramid Symmetric",
Mode.SIVEROO_1 : "[6] Siveroo's Preset I",
Mode.SIVEROO_2 : "[7] Siveroo's Preset II"
}[mode]
try:
return {
"EQUAL" : equal(count),
"GAUSSIAN" : gauss(count, c=settingsJson['gaussian']['standard_deviation'], bound=settingsJson['gaussian']['bound']),
"GAUSSIAN_SYM" : gauss_sym(count, c=settingsJson['gaussian']['standard_deviation'], bound=settingsJson['gaussian']['bound']),
"PYRAMID" : pyramid(count, reverse=settingsJson['pyramid']['reverse']),
"PYRAMID_SYM" : pyramid_sym(count),
"CUSTOM_FUNCTION": custom(count, func=settingsJson['custom_function']['function'], bound=settingsJson['custom_function']['bound']),
"CUSTOM_WEIGHT" : divide(count, weights=settingsJson['custom_weight']['weight'])
}[mode.upper()]
except KeyError:
raise InvalidBlendMode
11 changes: 5 additions & 6 deletions resampler.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

from cv2 import cv2 as cv

from SettingsLoader import *
from SettingsLoader import loadSettings
from Exceptions import *
from Weights import *

Expand Down Expand Up @@ -94,7 +94,7 @@ def processVideo(settings):
imgs = []
input_video.set(cv.CAP_PROP_POS_FRAMES, 0)

# FIRST ITERATION, LOAD ALL FRAMES
# First iteration, load all frames needed
for _ in range(0, blended_nframes):
_, frame = input_video.read()
if needResize:
Expand All @@ -104,7 +104,7 @@ def processVideo(settings):
output_video.write(blend(np.asarray(imgs), weights))
del imgs[:fps_ratio]

# NEXT ITERATION, ONLY LOAD THE REMAINING UNLOADED FRAMES
# Next iteration, load remaining unloaded frames
for i in range(1, int(output_nframes)):
timer_start = time.process_time()
for _ in range(0, fps_ratio):
Expand Down Expand Up @@ -137,9 +137,8 @@ def processVideo(settings):
os.rename(f"to-fix_{input_name}", f"{input_name}")

def main():
settings = load()
print(settings)

settings = loadSettings()

processVideo(settings)

if __name__ == "__main__":
Expand Down
20 changes: 18 additions & 2 deletions settings.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,24 @@
{
"framerate": 60,
"resolution": "UNCHANGED",
"fourcc": "FFV1",
"fourcc": "mp4v",
"cv_colourfix": false,
"blend_range": 1.0,
"blend_mode": 5
"blend_mode": "EQUAL",
"blend_settings": {
"pyramid": {
"reverse": false
},
"gaussian": {
"standard_deviation": 2,
"bound": [0,2]
},
"custom_function": {
"function": "-x**2+1",
"bound": [-0.5,1]
},
"custom_weight":{
"weight": [1,3,2,2]
}
}
}

0 comments on commit d8f4add

Please sign in to comment.