头像
KazamaSion
帖子: 29
注册时间: 2016-08-22 6:36

有关std.MakeDiff的一个疑惑

n = 255
clip = core.std.MakeDiff(core.std.BlankClip(clip, color = [0, 0, 0]), core.std.BlankClip(clip, color = [n, 0, 0]), planes = 0)
clip = core.std.ShufflePlanes(clips = clip, planes = 0, colorfamily=vs.GRAY)
mvf.Preview(clip).set_output()

当我把n设置为255时,返回的是一张纯黑的图像。
图片
当n为0时,返回是一张灰色的图像
图片

我不能理解为什么当n=0时,返回的为什么不是纯白的图像?
如果我想要通过比较2个clip,在完全相同的时候返回黑色/白色,完全不相同的时候返回白色/黑色,应该怎样做呢?
我突然想起来有个东西叫std.Levels {:cat_4}
上次由 KazamaSion 在 2016-10-12 14:58,总共编辑 2 次。
头像
msg7086
帖子: 600
注册时间: 2011-02-19 0:49

Re: 有关std.MakeDiff的一个疑惑

MaskTools2/mt makediff
Description

mt_makediff subtracts two clips; equivalent to mt_lutxy("x y - 128 +"), but faster.
Delogo LGD Collections 各种台标下载 | Home Of VapourSynth Evolution

<回答が無い理由>
1. 誰も知らない
2. 質問文が意味不明
3. 知ってるが、お前の態度が気に入らない
4. 良いボケが思いつかない
NAVras
帖子: 141
注册时间: 2016-04-24 1:32

Re: 有关std.MakeDiff的一个疑惑

一个简单的原因,如果是0/255,那么相减得负如何储存? {:cat_2} 所以同楼上式子,取128为中点
头像
KazamaSion
帖子: 29
注册时间: 2016-08-22 6:36

Re: 有关std.MakeDiff的一个疑惑

感谢各位的回复,但我仍旧有一个疑惑

测试代码如下:

代码: 全选

n = 200 #可为任意0-255之间的值
mask = core.std.BlankClip(clip, color = [n, 0, 0])
        mask_change = core.std.MakeDiff(clipa = mvf.ToRGB(mask), clipb = core.std.BlankClip(clip, color = [0, 0, 0]))
        mask_change = core.std.Levels(mask_change, min_in = 128, max_in = 255, min_out = 0, max_out = 255, planes = 0)
        mask_change = core.std.ShufflePlanes(clips = mask_change, planes = 0, colorfamily = vs.GRAY)

结果:在n[128,255]间,输出结果为纯白没有变化
请问这是为什么呢?
头像
mawen1250
核心会员
核心会员
帖子: 670
注册时间: 2011-07-24 20:33

Re: 有关std.MakeDiff的一个疑惑

因为diff clip储存的是差值,而8bit下[0, 255]的范围,生成的差值范围能够达到[-255, 255],由于:
1. 对于unsigned int,负值是不允许的
2. diff clip仍然是8bit,只允许[0, 255]的范围
所以他实际的方法是对差值+128,然后clamp掉超出范围的值,最后得到一个以128代表0,0代表-128,255代表+127的diff clip,也就是只能表示一半的范围。

解决办法:
1. 生成更高bit depth的差值clip,可以使用std.Expr自己实现
例如生成bit depth +1的diff clip

代码: 全选

srcFormat = clip1.format
bps = srcFormat.bits_per_sample
newFormat = core.register_format(srcFormat.color_family, srcFormat.sample_type, bps + 1, srcFormat.subsampling_w, srcFormat.subsampling_h)
core.std.Expr([clip1, clip2], 'x y - {} +'.format(1 << bps), format=newFormat)
这种方法比较tricky,需要自己注意后续处理可能的各种问题,而且我不确定std.Expr是否支持输出大于16bit int的格式,就算支持,后续的滤镜也基本不太会支持17bit int这种格式。

2. 直接转换为32bit float再作差(对于int输入也可以自己用Expr实现,效率更高),浮点格式数值没有上下限(准确地说是一般不需要考虑)。
PS. VS R34刚刚修正了之前版本中对于float格式,MakeDiff、MergeDiff仍然会clamp范围的问题。

回到 “VapourSynth”