增加 jpg 输出质量的参数 & 一些问题
Opened this issue · 5 comments
感谢作者,感觉还挺好用的。
代码还没细看,先跑了点测试。然后有些问题请教一下。
加了个jpg压缩的参数
cv2.imwrite(output_filename, img_data, [int(cv2.IMWRITE_JPEG_QUALITY), 90])
png也有对应的IMWRITE_PNG_COMPRESSION,但那个有损得比较厉害,不太用到。
jpg的还是挺常用的。
做了一些测试
同水印大小不同源图大小
- plot_src256_wm32_block4_jpg60-100_mod16-32
- plot_src512_wm32_block4_jpg60-100_mod16-32
- plot_src1024_wm32_block4_jpg60-100_mod16-32
显然大图包含信息更多,还原更精准。(横坐标为jpg品质,纵坐标为mod)
水印刚好是图源1/8
- plot_src256_wm32_block4_jpg60-100_mod16-32
- plot_src512_wm64_block4_jpg60-100_mod16-32
- plot_src1024_wm128_block4_jpg60-100_mod16-32
大图有好一些,但优势不明显。(个人理解是承载信息的范围和信息本身在同比增加,压缩之后干扰程度也就差不多)
接合上一条,也许水印可以有一个上限,比如128的bitmap,足够承载较多的内容。
block的影响
同样源图用到最大水印 block4->1
这里都是256的原图,分别用了32的水印和128的水印,明显128的品质更好,但block少了。
同样源图/水印/仅改变block
- plot_src512_wm32_block2_jpg60-100_mod16-32
- plot_src512_wm32_block3_jpg60-100_mod16-32
- plot_src512_wm32_block4_jpg60-100_mod16-32
- plot_src512_wm32_block8_jpg60-100_mod16-32
我的理解是block越多,单个block就越小,能承载的信息越少,所以解码质量越低。
这里我源码还没细看,请问block在这里的作用是什么?从原图反解码的效果来看是越少品质越好,那block增加是能实现什么效果呢?防遮挡,多处采样比较吗?
其他一些问题
- 从多次保存等情况下看,jpg还是按60的标准来处理比较保险,那样的话貌似mod就只能取24-32这个范围。
- 请问block具体作用是什么?有没有所谓的上限,比如4就足够应付大部分场景了?
考虑自动根据源图生成参数
- 另外逆向出来水印的质量,除了除数,还是和图片/水印大小,block分区,压缩品质,源图大小及保护价值(源图太小就牺牲block)等各种因素相关。
- 我现在考虑能不能自动根据源图大小(锁定源图和jpg60这两个参数),自动判断所需的block/水印尺寸/除数,这三个参数,获得一个画质和保护的平衡。
- 解码的时候考虑方式一是通过上述的自动参数来做,二是固定水印大小(比如128/64/32/16)试个4次,变相自动。
读完源码自答一下
block有一个比较隐蔽的问题是配合dwt,要凑到8px,因为jpg是按8px来压缩的,也就是block*(2^dwt_deep)刚好。
block过小,运算量几何级数增加,效率过慢。而且block过细,会导致画面有明显噪点感。
block过大,解高压缩的jpg水印会出问题。
jpg60时,block数量的宽高,达到水印2倍后解水印质量不错。比如画布1024,dwt1次,有效画布512,block4,可记载宽度128,如果用来记载32的水印,就达到了4:1,解水印效果就很好。
假设:
水印 = [32, 64, 128]
block = [2, 4] # 测试用1的话好像完全不能抗涂抹
信息承载范围 = 源图 / block
常数 = 信息承载范围 / 水印
-
然后如果水印上限128,block上限4的话,就对源图小于1024以内的部分,写一点适配规则自动取水印大小和block。
-
再用这个 常数+jpg品质,出一套图,可能就能map出一个mod值。这样自动取mod也就有了。
-
大致的一个想法,不知道行不行得通。考虑在作者的基础上套一层自动参数的壳试试。
-
因为现在都是正方的在试,条状截图不知道会怎么样。现在block好像只接受两个相同的参数,不晓得条状图还原会不会有问题。有空我再试试。
测试了一张白色背景的图
-
使用反色(黑底白字)水印的结果
test_plot_src512_wm64b_block4_jpg60-100_mod16-32
-
使用纯黑白原图(接近bitmap)的测试结果
testb_plot_src512_wm64_block4_jpg60-100_mod16-32
-
使用纯黑白原图(接近bitmap)且黑底白字的测试结果
testw_plot_src512_wm64_block4_jpg60-100_mod16-32
-
使用纯黑白原图(接近bitmap)且黑底白字+黑底白字水印的测试结果
testw_plot_src512_wm64b_block4_jpg60-100_mod16-32
- 基本跟预想的差不多,在灰度图上比较容易混入信息,纯黑纯白就很难。
- 比较意外地是mod的有效性,跟之前的情况完全不同。
- 这样会导致在一些场景效果不佳,比如黑白漫画,或者大幅白色背景的产品图,等等。
- 主要问题还是mod的设置,又不可能全部导多份手动选图。
多参数输出多份,然后用ncc或者ocr去判断水印有效性,最后择优选用虽然也可以,但比较绕。
我看懂了代码,个人理解是这样的:
- block 越大,嵌入的图跟原图比较,变化越小,但水印越不稳定。
- 水印只取第一通道,并且bit化,所以水印通道、反色什么的,意义不是很大。
- 没测试,只是从代码中理解上是这样,不知道上面实际测试时候是不是这样
- 你的测试结果,横纵坐标和标题都没看懂,希望解释一下(另外,乘号会被解析为斜体,用✖️)