Welcome to Doom9's Forum, THE in-place to be for everyone interested in DVD conversion.

Before you start posting please read the forum rules. By posting to this forum you agree to abide by the rules.

 

Go Back   Doom9's Forum > Capturing and Editing Video > VapourSynth

Reply
 
Thread Tools Search this Thread Display Modes
Old 15th September 2019, 07:10   #1  |  Link
poisondeathray
Registered User
 
Join Date: Sep 2007
Posts: 5,345
Gradient Ramp function?

Is there a function to generate a gradient ramp ?

e.g. a ramp from x1,y1 to x2,y2 coordinates. Values from a to b



Or how would you do it in python ?

I know you can do it in other programs, but I'm just wondering how to do it procedurally in vapoursynth

Thanks
poisondeathray is offline   Reply With Quote
Old 15th September 2019, 23:28   #2  |  Link
_Al_
Registered User
 
Join Date: May 2011
Posts: 321
Do you work in RGB? You can then use numpy and use even opencv algorithms. Im sure you coul google some "opencv gradients" or better "numpy to gradient".
Just to demonstarate the process, here is some Eval function, where vs array is changed into numpy, opencv making gradients by some built in function and then using some numpy magic to paste that rectangle into original numpy array. Then numpy is going back to vs array.
Code:
import cv2
import numpy as np
import functools
import vshelper
import vapoursynth as vs
from vapoursynth import core
clip = core.ffms2.Source(r'C:/video.mp4')
clip = core.resize.Point(clip, matrix_in_s = '709', format = vs.RGB24)
X1,Y1 = (100,100)
X2,Y2 = (500,500)

def grad(n, clip):
   list_of_arrays = [np.array(clip.get_frame(n).get_read_array(i), copy=False) for i in range(3)]
   np_image = np.dstack(list_of_arrays)
   rectangle = cv2.applyColorMap(np_image, cv2.COLORMAP_JET)[Y1:Y2, X1:X2]
   np_image[Y1:Y2, X1:X2] = rectangle
   out = vshelper.uint8_vsclip(np_image, clip=None)
   out = core.resize.Bilinear(out, format = vs.RGB24)
   return out

clip = core.std.FrameEval(clip, functools.partial(grad, clip=clip))

clip.set_output()
_Al_ is offline   Reply With Quote
Old 16th September 2019, 00:47   #3  |  Link
poisondeathray
Registered User
 
Join Date: Sep 2007
Posts: 5,345
Thanks _Al_

RGB yes

I can't find vshelper

How would you specify the values ? Lets start with something simple: Lets say you wanted RGB30 linear ramp. RGB [0,0,0 - 1023,1023,1023] , from 0,0 to 1023,0 . So it's a 1024x(something height) dimension rectangle

I already did this in another program, I'm just wondering programatically how it can be done in vapoursynth, or what the syntax would be
poisondeathray is offline   Reply With Quote
Old 16th September 2019, 02:10   #4  |  Link
_Al_
Registered User
 
Join Date: May 2011
Posts: 321
https://github.com/KotoriCANOE/MyTF/...ls/vshelper.py

here is an example for floating point, vshelper can do floating point, going on from RGBS, not sure about RGB30, but RGB24 is ok too,
no opencv needed, just numpy

I'm not sure how that gradient suppose to be, one color changing into other from top to bottom then pasted into video:
Code:
import numpy as np
import functools
import vshelper
clip = core.ffms2.Source(r'C:/video.mp4')
clip = core.resize.Point(clip, matrix_in_s = '709', format = vs.RGBS)
X1,Y1 = (100,100)
X2,Y2 = (600,300)
WIDTH =  X2-X1
HEIGHT = Y2-Y1
#https://stackoverflow.com/questions/4337902/how-to-fill-opencv-image-with-one-solid-color
def create_blank(width, height, color=(0, 0, 0)):
    image = np.zeros((height, width, 3), np.uint8)
    #color = tuple(reversed(color))
    image[:] = color
    return image

def pip(n, clip, rectangle):
   list_of_arrays = [np.array(clip.get_frame(n).get_read_array(i), copy=False) for i in range(3)]
   np_image = np.dstack(list_of_arrays)
   np_image[Y1:Y2, X1:X2] = rectangle
   pip = vshelper.float32_vsclip(np_image, clip=None)
   return pip

color1 = (255, 0, 0)
color2 = (0, 0, 255)
img1 = create_blank(WIDTH, HEIGHT, color1).astype(np.float32)/255.0
img2 = create_blank(WIDTH, HEIGHT, color2).astype(np.float32)/255.0
c = np.linspace(0, 1, HEIGHT)[:, None, None]
gradient = img1 + (img2 - img1) * c
clip = core.std.FrameEval(clip, functools.partial(pip, clip=clip, rectangle = gradient))
clip.set_output()

Last edited by _Al_; 16th September 2019 at 02:32. Reason: I guess RGB to BGR is not necesarry
_Al_ is offline   Reply With Quote
Old 16th September 2019, 02:42   #5  |  Link
_Al_
Registered User
 
Join Date: May 2011
Posts: 321
and for gradient from left to right that one line for c would be:
c = np.linspace(0, 1, WIDTH)[None,:, None]
_Al_ is offline   Reply With Quote
Old 16th September 2019, 02:56   #6  |  Link
poisondeathray
Registered User
 
Join Date: Sep 2007
Posts: 5,345
Thanks, it works well
poisondeathray is offline   Reply With Quote
Old 16th September 2019, 04:24   #7  |  Link
_Al_
Registered User
 
Join Date: May 2011
Posts: 321
simple black & white gradient could be made something like this into vs.VideoNode , but to create pip might be timely using FrameEval, though did not try it, numpy is really fast, so those gradients created into numpy first makes sense, like above,
vapoursynth gradient (black&white for alpha or something):
Code:
import vapoursynth as vs
from vapoursynth import core
clip = core.ffms2.Source(r'C:/video.mp4')
clip = core.resize.Point(clip, matrix_in_s = '709', format = vs.RGB24)   #RGBS, RGB30 ...

X1,Y1 = (100,100)
X2,Y2 = (600,300)
WIDTH =  X2-X1
HEIGHT = Y2-Y1

gradient = core.std.BlankClip(width=1, height=HEIGHT, color=(0,0,0), format = clip.format.id)
if gradient.format.sample_type == vs.INTEGER: 
    size=2**gradient.format.bits_per_sample
else:
    size=1  #vs.FLOAT

for part in range(1,WIDTH):
    c = size/WIDTH*part
    add = core.std.BlankClip(clip, width=1, height=HEIGHT, color=(c,c,c))
    gradient = core.std.StackHorizontal([gradient, add])
    del add
gradient.set_output()

Last edited by _Al_; 16th September 2019 at 04:26.
_Al_ is offline   Reply With Quote
Old 16th September 2019, 04:34   #8  |  Link
poisondeathray
Registered User
 
Join Date: Sep 2007
Posts: 5,345
The 1st function is flexible enough for me; I just use blankclip for the video . It works well for my purposes
poisondeathray is offline   Reply With Quote
Reply

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT +1. The time now is 13:33.


Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2024, vBulletin Solutions Inc.