如题,一些良心番看番送壁纸,但右上角有水印。于是弹幕里充斥着“万恶的水印”“有水印”等等。
我原来用 Ps 去水印,后来发现太低效,于是想找出水印算法,用逆变换还原打水印前的图片。
基本思想是摸清加水印的算法,然后逆向求出原图。
经过一晚上的研究,发现以下公式:
ln(255 - s) = c ln(255 - w)
上式中 s 为原图像素,w 为加了水印的像素。c 为常数,对于水印中间的像素取 1.08856,对于没有水印的地方就是 1。可见加水印算法是类似 gamma 变换的算法。
接下来的任务就是对于图片的不同位置的像素,求出对应的常数 c,然后代以上公式。我找 了一张背景几乎纯色的截图作为蒙版。经过 Ps 处理后可以得到一张背景纯色的带水印字样的图片(下图)。
利用这张图就可算出 c 值。因为原图已知(去除右上角的图就是原图),带入公式求 c,再根据 c 求要去水印图片的原图即可。
去水印前
去水印后
B站什么时候又搞了个'BiliBili正版',害得我又做了一张
图片肯定和你们的截图大小不一样,自己做吧。
r2_b2_g2_独播.png 来源忘了
r73_g34_b35_正版.png 来源《伽百璃的堕落》ep.01 08:04
r39_g51_b70_独播.png 来源《天使降临到我身边》ep.09 17:55
蒙版图命名规则:代码简洁起见,蒙版图片文件名必须包含蒙版图背景的rgb信息。规则是 'r'/'g'/'b' + 像素值,例如 'r39_g51_b70', 'r39g51b70.png', 'maskr39_g51b70.jpg' 都是合法的文件名。
使用时
python3.6 main.py -i example.png -o example-out.png -m r39_g51_b70_独播.png
自己制作蒙版图:用相同截图方式截一张字样附近几乎纯色的图,把其他地方填充同样的颜色。尽量保留字样周围的像素,不要做处理。对字样周围像素做 Ps 处理会使公式中 c 值发生变化,导致处理出来的图有白边。
对于浅色的图,效果非常不错,但对于深色的图效果不佳。因为深色图 RGB 值过小,最终结果会有色差。
yuchenxi2000
2019.10.22
应issue要求做了去除B漫水印的脚本/蒙版,详见“B漫”目录。
算法是一张带alpha通道的水印图叠加到原图上。
out = in alpha + watermark (1 - alpha)
out是加了水印的图,in是原图,alpha是透明通道,watermark是水印(除透明通道外)
因为网上爬下的图没有alpha通道,所以需要一张白背景+一张黑背景蒙版把alpha通道算出来。多爬一些图总能找到水印周围全白/全黑的图,实在不行多找几张拼出来。
⚠️注意,B漫的水印会改,所以发现本仓库的蒙版不好用时自己做一个。
yuchenxi2000
2022.02.05