WolframRhodium / muvsfunc

Muonium's VapourSynth functions
75 stars 19 forks source link

Any way can direct pass numpy unit8 to vapoursynth 8bit? #17

Closed Ken1256 closed 5 years ago

Ken1256 commented 5 years ago

https://github.com/KotoriCANOE/MyTF/blob/master/utils/vshelper.py float32_vsclip only can pass float32, if direct pass numpy unit8 to vapoursynth need change clip.format.bits_per_sample, but show 'bits_per_sample' of 'vapoursynth.Format' objects is not writable.

WolframRhodium commented 5 years ago

Hi,

does the following code solve your problem?

def uint8_vsclip(u8, clip=None):
    assert isinstance(u8, np.ndarray)
    assert u8.dtype == np.uint8

    if len(u8.shape) <= 3: u8 = u8.reshape([1] + list(u8.shape))
    num = u8.shape[-4]
    height = u8.shape[-3]
    width = u8.shape[-2]
    planes = u8.shape[-1]
    if clip is None:
        clip = core.std.BlankClip(None, width, height, vs.RGB24 if planes == 3 else vs.GRAY8, num)

    def convert_func(n, f):
        fout = f.copy()
        for p in range(planes):
            d = np.asarray(fout.get_write_array(p))
            np.copyto(d, u8[n, :, :, p])
            del d
        return fout
    return core.std.ModifyFrame(clip, clip, convert_func)

Anyway, you should use some VapourSynth plugins (e.g. core.fmtc.bitdepth() from fmtconv, core.resize.* from vszimg) to change the clip.format.bits_per_sample, since the operation requires data scaling (0-1 → 0-255, for example), and simply modifying the flag is not enough.

Ken1256 commented 5 years ago

Thanks. I forgot to change vs.RGBS/vs.GRAYS to vs.RGB24/vs.GRAY8. numpy RGB uint16 == RGB48?

WolframRhodium commented 5 years ago

yes