Skip to content

Commit

Permalink
Bump Version 3.5.1
Browse files Browse the repository at this point in the history
Fixed bug in vs_degrain
vs_degrain is now applied only to DDColor
Changed some presets values (added "Yellow->Rose" to colormap)
  • Loading branch information
dan64 committed May 8, 2024
1 parent c995ea6 commit 0008194
Show file tree
Hide file tree
Showing 6 changed files with 69 additions and 51 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ To try to solve this problem has been developed _pre-_ and _post-_ process filte

The main filters introduced are:

**Degrain** : Since a BW clip with noise/grain can create artifacts on colored frames, this filter allows to reduce the noise/grain contained in the frames. This filter is applied only to the frames to be colored. At the end of the coloring process the original noise/grain of the clip is restored. The strength of the filter has range [0-5], the suggested value is 3 (if = 0 the filter is not applied).
**Degrain** : Since a BW clip with noise/grain can create artifacts on colored frames (this effect is more evident with DDColor), this filter allows to reduce the noise/grain contained in the frames. This filter is applied only to the frames to be colored by DDColor. At the end of the coloring process the original noise/grain of the clip is restored. The strength of the filter has range [0-5], the suggested value is 1 (if = 0 the filter is not applied).

**Chroma Smoothing** : This filter allows to reduce the _vibrancy_ of colors assigned by Deoldify/DDcolor by using the parameters _de-saturation_ and _de-vibrancy_ (the effect on _vibrancy_ will be visible only if the option **chroma resize** is enabled, otherwise this parameter has effect on the _luminosity_). The area impacted by the filter is defined by the thresholds dark/white. All the pixels with luma below the dark threshold will be impacted by the filter, while the pixels above the white threshold will be left untouched. All the pixels in the middle will be gradually impacted depending on the luma value.

Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ exclude = [

[project]
name = "vsdeoldify"
version = "3.5.0"
version = "3.5.1"
description = "Deoldify function for VapourSynth"
readme = "README.md"
requires-python = ">=3.10"
Expand Down
27 changes: 10 additions & 17 deletions vsdeoldify/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
Date: 2024-02-29
version:
LastEditors: Dan64
LastEditTime: 2024-05-03
LastEditTime: 2024-05-08
-------------------------------------------------------------------------------
Description:
-------------------------------------------------------------------------------
Expand Down Expand Up @@ -33,7 +33,7 @@
warnings.filterwarnings("ignore", category=UserWarning, message="Arguments other than a weight enum or `None`.*?")
warnings.filterwarnings("ignore", category=UserWarning, message="torch.nn.utils.weight_norm is deprecated.*?")

__version__ = "3.5.0"
__version__ = "3.5.1"

package_dir = os.path.dirname(os.path.realpath(__file__))
model_dir = os.path.join(package_dir, "models")
Expand Down Expand Up @@ -92,8 +92,9 @@ def ddeoldify_main(clip: vs.VideoNode, Preset: str = 'Fast', ColorFix: str = 'Vi
'Green->Red',
'Green->Blue',
'Red->Brown',
'Red->Blue'
:param degrain_strength: strenght of denoise/degrain pre-filter applied on BW clip, if = 0 the pre-filter is disabled, range [0-5], suggested = 3
'Red->Blue'
'Yellow->Rose'
:param degrain_strength: strenght of denoise/degrain pre-filter applied on BW clip, if = 0 the pre-filter is disabled, range [0-5], default = 0
:param enable_fp16: Enable/disable FP16 in ddcolor inference, range [True, False]
"""
# Select presets / tuning
Expand Down Expand Up @@ -143,8 +144,8 @@ def ddeoldify_main(clip: vs.VideoNode, Preset: str = 'Fast', ColorFix: str = 'Vi

# Select Color Mapping
ColorMap = ColorMap.lower()
colormap = ['none', 'blue->brown', 'blue->red', 'blue->green', 'green->brown', 'green->red', 'green->blue', 'red->brown', 'red->blue']
hue_map = ["none", "180:280|+140,0.1", "180:280|+100,0.1", "180:280|+220,0.1", "80:180|+260,0.1", "80:180|+220,0.1", "80:180|+140,0.1", "300:360,0:20|+40,0.3", "300:360,0:20|+260,0.3"]
colormap = ['none', 'blue->brown', 'blue->red', 'blue->green', 'green->brown', 'green->red', 'green->blue', 'red->brown', 'red->blue', 'yellow->rose']
hue_map = ["none", "180:280|+140,0.4", "180:280|+100,0.4", "180:280|+220,0.4", "80:180|+260,0.4", "80:180|+220,0.4", "80:180|+140,0.4", "300:360,0:20|+40,0.6", "300:360,0:20|+260,0.6", "30:90|+300,0.8"]

try:
cl_id = colormap.index(ColorMap)
Expand Down Expand Up @@ -265,7 +266,7 @@ def ddeoldify(
for a movie with a lot of dark scenes is suggested alpha > 1, if=0 is not activated, range [>=0]
[7] : gamma_min: minimum value for gamma, range (default=0.5) [>0.1]
[8] : "chroma adjustment" parameter (optional), if="none" is disabled (see the README)
:param degrain_strength: strenght of denoise/degrain pre-filter applied on BW clip, if = 0 the pre-filter is disabled, range [0-5], suggested = 3
:param degrain_strength: strenght of denoise/degrain pre-filter applied on BW clip, if = 0 the pre-filter is disabled, range [0-5], default = 0
:param cmc_tresh: chroma_threshold (%), used by: Constrained "Chroma Merge range" [0-1] (0.01=1%)
:param lmm_p: parameters for method: "Luma Masked Merge" (see method=4 for a full explanation)
[0] : luma_mask_limit: luma limit for build the mask used in Luma Masked Merge, range [0-1] (0.01=1%)
Expand Down Expand Up @@ -332,18 +333,10 @@ def ddeoldify(
if chroma_resize:
frame_size = min(max(ddcolor_rf, deoldify_rf) * 16, clip.width) # frame size calculation for inference()
clip_orig = clip;
clip = clip.resize.Spline64(width=frame_size, height=frame_size)

try:
d_clip = vs_degrain(clip, strength=degrain_strength, device_id=device_index)
except:
vs.core.log_message(2, "ddeoldify: KNLMeansCL is not installed/loaded properly")
d_clip = clip

clip = d_clip
clip = clip.resize.Spline64(width=frame_size, height=frame_size)

clipa = vs_deoldify(clip, method=method, model=deoldify_model, render_factor=deoldify_rf, tweaks_enabled=dotweak, tweaks=dotweak_p, package_dir=package_dir)
clipb = vs_ddcolor(clip, method=method, model=ddcolor_model, render_factor=ddcolor_rf, tweaks_enabled=ddtweak, tweaks=ddtweak_p, enable_fp16=ddcolor_enable_fp16, device_index=device_index)
clipb = vs_ddcolor(clip, method=method, model=ddcolor_model, render_factor=ddcolor_rf, tweaks_enabled=ddtweak, tweaks=ddtweak_p, dstrength=degrain_strength, enable_fp16=ddcolor_enable_fp16, device_index=device_index)

clip_colored = vs_combine_models(clip_a=clipa, clip_b=clipb, method=method, sat=[deoldify_sat, ddcolor_sat], hue=[deoldify_hue, ddcolor_hue], clipb_weight=merge_weight, CMC_p=cmc_tresh, LMM_p=lmm_p, ALM_p = alm_p, invert_clips=cmb_sw)

Expand Down
42 changes: 27 additions & 15 deletions vsdeoldify/vsslib/restcolor.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
Date: 2024-04-08
version:
LastEditors: Dan64
LastEditTime: 2024-04-29
LastEditTime: 2024-05-08
-------------------------------------------------------------------------------
Description:
-------------------------------------------------------------------------------
Expand All @@ -27,7 +27,7 @@
Restore the colors of past/future frame. The restore is applied using a mask
to selectect only the gray images on HSV color space.
The ranges that OpenCV manage for HSV format are the following:
- Hue range is [0,179],
- Hue range is [-180,+180],
- Saturation range is [0,255]
- Value range is [0,255].
For the 8-bit images, H is converted to H/2 to fit to the [0,255] range.
Expand All @@ -53,7 +53,7 @@ def restore_color(img_color: Image = None, img_gray: Image = None, sat: float=1.
scenechange = np.mean(hsv_mask)/255

if (tht_scen > 0 and tht_scen < 1 and scenechange > tht_scen):
if hue_adjust:
if hue_adjust!="" and hue_adjust!="none":
return adjust_hue_range(img_gray, hue_adjust=hue_adjust)
else:
return img_gray
Expand All @@ -69,11 +69,14 @@ def restore_color(img_color: Image = None, img_gray: Image = None, sat: float=1.
np_restored = np_image_mask_merge(np_gray, np_color_sat, mask_rgb)

if weight > 0:
np_restored = np_weighted_merge(np_restored, np_gray, weight)
np_restored = np_weighted_merge(np_restored, np_gray, weight) # merge with gray frame
if weight < 0:
np_restored = np_weighted_merge(np_restored, np_color_sat, -weight) # merge with colored frame


img_restored = Image.fromarray(np_restored,'RGB').convert('RGB')

if hue_adjust:
if hue_adjust!="" and hue_adjust!="none":
return adjust_hue_range(img_restored, hue_adjust=hue_adjust)
else:
return img_restored
Expand All @@ -87,7 +90,11 @@ def restore_color(img_color: Image = None, img_gray: Image = None, sat: float=1.
Change a given range of colors in HSV color space.
The range is defined by the hue values in degree (range: 0-360)
In OpenCV, for the 8-bit images, H is converted to H/2 to fit to the [0,255] range.
So the range of hue in the HSV color space of OpenCV is [0,179]
So the range of hue in the HSV color space of OpenCV is [0,179].
hue_range syntax: "hue1_min:hue1_max,..,hueN_min,hueN_max|adjust, weight"
where:
adjust: if > 0 and < 10 -> saturation parameter else -> hue_shift
weight: if > 0 -> merge with desaturared frame, if < 0 -> merge with colored orginal frame
"""
def adjust_hue_range(img_color: Image = None, hue_adjust: str='none', return_mask: bool=False) -> Image:

Expand Down Expand Up @@ -118,9 +125,9 @@ def adjust_chroma(img_color: Image = None, hue_range: str='none', sat: float = 0

hsv_color = cv2.cvtColor(np_color, cv2.COLOR_RGB2HSV)

#apply hue correction, range [-180.+180], converted to [-90.+90]
#apply hue correction, range [-180,+180]
if hue != 0:
np_gray[:, :, 0] = np_gray[:, :, 0] + hue*0.5
np_gray[:, :, 0] = np_hue_add(np_gray[:, :, 0], hue)

# desatured the color image
if sat != 1:
Expand Down Expand Up @@ -149,7 +156,9 @@ def adjust_chroma(img_color: Image = None, hue_range: str='none', sat: float = 0
np_restored = np_weighted_merge(np_restored, np_gray_rgb, weight)
else:
np_restored = np_weighted_merge(np_restored, np_color, weight)

if weight < 0:
np_restored = np_weighted_merge(np_restored, np_color, -weight)

return Image.fromarray(np_restored,'RGB').convert('RGB')

def np_image_chroma_tweak(img_color_rgb: np.ndarray, sat: float = 1, bright: float = 0, hue: int = 0, hue_adjust: str='none') -> np.ndarray:
Expand Down Expand Up @@ -206,11 +215,14 @@ def np_image_chroma_tweak(img_color_rgb: np.ndarray, sat: float = 1, bright: flo

np_restored = np_image_mask_merge(img_color_rgb, np_gray_rgb, mask_rgb)

if hue==0:
np_restored = np_weighted_merge(np_restored, np_gray_rgb, weight)
else:
np_restored = np_weighted_merge(np_restored, img_color_rgb, weight)

if weight > 0:
if hue==0:
np_restored = np_weighted_merge(np_restored, np_gray_rgb, weight)
else:
np_restored = np_weighted_merge(np_restored, img_color_rgb, weight)
if weight < 0:
np_restored = np_weighted_merge(np_restored, img_color_rgb, -weight)

return np_restored


Expand Down Expand Up @@ -253,7 +265,7 @@ def _parse_hue_adjust(hue_adjust: str='none') -> ():

hue_range = p[0]

if p==1:
if num==1:
return (hue_range, sat, hue, weight)

sw = p[1].split(",")
Expand Down
32 changes: 19 additions & 13 deletions vsdeoldify/vsslib/vsfilters.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
Date: 2024-04-08
version:
LastEditors: Dan64
LastEditTime: 2024-05-03
LastEditTime: 2024-05-08
-------------------------------------------------------------------------------
Description:
-------------------------------------------------------------------------------
Expand Down Expand Up @@ -94,10 +94,13 @@ def vs_chroma_stabilizer_ex(clip: vs.VideoNode = None, nframes: int = 5, mode: s
#vs.core.log_message(2, "algo= " + str(algo))

if algo == 0:
clip_rgb = _average_clips_ex(clip=clip, weight_list=weight_list, sat=sat, tht=tht, weight=weight, tht_scen=tht_scen, hue_adjust=hue_adjust)
clip_rgb = _average_clips_ex(clip=clip, weight_list=weight_list, sat=sat, tht=tht, weight=weight, tht_scen=tht_scen, hue_adjust="none")
else:
clip_rgb = _average_frames_ex(clip=clip, weight_list=weight_list, sat=sat, tht=tht, weight=weight, tht_scen=tht_scen, hue_adjust=hue_adjust)

clip_rgb = _average_frames_ex(clip=clip, weight_list=weight_list, sat=sat, tht=tht, weight=weight, tht_scen=tht_scen, hue_adjust="none")

#hue adjustment applied only on the final frame
clip_rgb = vs_adjust_clip_hue(clip=clip_rgb, hue_adjust=hue_adjust)

return clip_rgb

def _build_avg_arithmetic(nframes: int = 5) -> list:
Expand Down Expand Up @@ -283,6 +286,9 @@ def color_frame(n, f, sat: float = 1.0, tht: int = 0, weight: float = 0.2, tht_s
"""
def vs_adjust_clip_hue(clip: vs.VideoNode = None, hue_adjust: str='none') -> vs.VideoNode:

if hue_adjust=="" or hue_adjust=="none":
return clip

def color_frame(n, f, hue_adjust: str='none'):
f_out = f.copy()
if n < 1:
Expand Down Expand Up @@ -524,32 +530,32 @@ def copy_luma_frame(n, f):
Function to remove noise/grain from clip, strenght control the amount of noise/grain removed,
if = 0 the filter is not applied. It is based on function KNLMeansCL() with GPU suppot enabled.
"""
def vs_degrain(clip: vs.VideoNode = None, strength: int = 3, device_id: int = 0) -> vs.VideoNode:
def vs_degrain(clip: vs.VideoNode = None, strength: int = 1, device_id: int = 0) -> vs.VideoNode:

if strength == 0:
return clip

match strength:
case 1:
dstr = 1.5
dstr = 0.5
dtmp = 1
case 2:
dstr = 2.5
dstr = 1.0
dtmp = 1
case 3:
dstr = 3.5
dstr = 1.5
dtmp = 1
case 4:
dstr = 5.5
dtmp = 2
dstr = 2.5
dtmp = 1
case 5:
dstr = 8.5
dtemp = 2
dstr = 3.5
dtmp = 2
case _:
raise vs.Error("ddeoldify: not supported strength value: " + strength)

clip = clip.resize.Bicubic(format=vs.YUV444PS, matrix_s="709", range_s="full")
clip = vs.core.knlm.KNLMeansCL(clip=clip, d=dtemp, a=2, s=4, h=dstr, channels='Y', device_type="gpu", device_id=device_id)
clip = vs.core.knlm.KNLMeansCL(clip=clip, d=dtmp, a=2, s=4, h=dstr, channels='Y', device_type="gpu", device_id=device_id)
clip = clip.resize.Bicubic(format=vs.RGB24, matrix_in_s="709", range_s="full", dither_type="error_diffusion")

return clip
Expand Down
15 changes: 11 additions & 4 deletions vsdeoldify/vsslib/vsmodels.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
Date: 2024-04-08
version:
LastEditors: Dan64
LastEditTime: 2024-04-27
LastEditTime: 2024-05-08
-------------------------------------------------------------------------------
Description:
-------------------------------------------------------------------------------
Expand Down Expand Up @@ -92,7 +92,7 @@ def deoldify_colorize(n: int, f: vs.VideoFrame, colorizer: ModelImageVisualizer
-------------------------------------------------------------------------------
wrapper to function ddcolor() with tweak pre-process.
"""
def vs_ddcolor(clip: vs.VideoNode, method: int = 2, model: int = 0, render_factor: int = 24, tweaks_enabled: bool = False, tweaks: list = [0.0, 0.9, 0.7, False, 0.3, 0.3], enable_fp16: bool = True, device_index: int = 0, num_streams: int = 1) -> vs.VideoNode:
def vs_ddcolor(clip: vs.VideoNode, method: int = 2, model: int = 0, render_factor: int = 24, tweaks_enabled: bool = False, tweaks: list = [0.0, 0.9, 0.7, False, 0.3, 0.3], dstrength: int = 0, enable_fp16: bool = True, device_index: int = 0, num_streams: int = 1) -> vs.VideoNode:

if method == 0:
return None
Expand All @@ -101,7 +101,14 @@ def vs_ddcolor(clip: vs.VideoNode, method: int = 2, model: int = 0, render_facto

# input size must a multiple of 32
input_size = math.trunc(render_factor/2)*32


try:
d_clip = vs_degrain(clip, strength=dstrength, device_id=device_index)
except Exception as error:
vs.core.log_message(2, "ddeoldify: KNLMeansCL error -> " + str(error))
d_clip = clip
clip = d_clip

# unpack tweaks
bright = tweaks[0]
cont = tweaks[1]
Expand All @@ -123,7 +130,7 @@ def vs_ddcolor(clip: vs.VideoNode, method: int = 2, model: int = 0, render_facto
else:
clipb = vs_tweak(clip, bright=bright, cont=cont, gamma=gamma)
else:
clipb = clip
clipb = clip
# adjusting clip's color space to RGBH for vsDDColor
if enable_fp16:
clipb = vsddcolor.ddcolor(clipb.resize.Bicubic(format=vs.RGBH, range_s="full"), model=model, input_size=input_size, device_index=device_index, num_streams=num_streams)
Expand Down

0 comments on commit 0008194

Please sign in to comment.