Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

增加 jpg 输出质量的参数 & 一些问题 #13

Open
Erimus-Koo opened this issue Jul 2, 2020 · 5 comments
Open

增加 jpg 输出质量的参数 & 一些问题 #13

Erimus-Koo opened this issue Jul 2, 2020 · 5 comments

Comments

@Erimus-Koo
Copy link

Erimus-Koo commented Jul 2, 2020

感谢作者,感觉还挺好用的。
代码还没细看,先跑了点测试。然后有些问题请教一下。

加了个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_src256_wm32_block4_jpg60-100_mod16-32
  • plot_src512_wm32_block4_jpg60-100_mod16-32
    plot_src512_wm32_block4_jpg60-100_mod16-32
  • plot_src1024_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_src256_wm32_block4_jpg60-100_mod16-32
  • plot_src512_wm64_block4_jpg60-100_mod16-32
    plot_src512_wm64_block4_jpg60-100_mod16-32
  • plot_src1024_wm128_block4_jpg60-100_mod16-32
    plot_src1024_wm128_block4_jpg60-100_mod16-32

大图有好一些,但优势不明显。(个人理解是承载信息的范围和信息本身在同比增加,压缩之后干扰程度也就差不多)
接合上一条,也许水印可以有一个上限,比如128的bitmap,足够承载较多的内容。

block的影响

同样源图用到最大水印 block4->1

  • plot_src256_wm32_block4_jpg60-100_mod16-32
    plot_src256_wm32_block4_jpg60-100_mod16-32
  • plot_src256_wm128_block1_jpg60-100_mod16-32
    plot_src256_wm128_block1_jpg60-100_mod16-32

这里都是256的原图,分别用了32的水印和128的水印,明显128的品质更好,但block少了。

同样源图/水印/仅改变block

  • plot_src512_wm32_block2_jpg60-100_mod16-32
    plot_src512_wm32_block2_jpg60-100_mod16-32
  • plot_src512_wm32_block3_jpg60-100_mod16-32
    plot_src512_wm32_block3_jpg60-100_mod16-32
  • plot_src512_wm32_block4_jpg60-100_mod16-32
    plot_src512_wm32_block4_jpg60-100_mod16-32
  • plot_src512_wm32_block8_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,解水印效果就很好。

@Erimus-Koo
Copy link
Author

Erimus-Koo commented Jul 2, 2020

假设:

水印 = [32, 64, 128]  
block = [2, 4]  # 测试用1的话好像完全不能抗涂抹  
信息承载范围 = 源图 / block  
常数 = 信息承载范围 / 水印  
  • 然后如果水印上限128,block上限4的话,就对源图小于1024以内的部分,写一点适配规则自动取水印大小和block。

  • 再用这个 常数+jpg品质,出一套图,可能就能map出一个mod值。这样自动取mod也就有了。

  • 大致的一个想法,不知道行不行得通。考虑在作者的基础上套一层自动参数的壳试试。

  • 因为现在都是正方的在试,条状截图不知道会怎么样。现在block好像只接受两个相同的参数,不晓得条状图还原会不会有问题。有空我再试试。

@Erimus-Koo
Copy link
Author

测了下超窄图,128x2048,像素同512x512。

  • plot_src512_wm64_block4_jpg60-100_mod16-32
    plot_src512_wm64_block4_jpg60-100_mod16-32
  • plot_src128x2048_wm64_block4_jpg60-100_mod16-32
    plot_src128x2048_wm64_block4_jpg60-100_mod16-32

宽高1:16,看来条状图没什么问题。

@Erimus-Koo
Copy link
Author

Erimus-Koo commented Jul 2, 2020

测试了一张白色背景的图

  • 原图
    test512

  • 使用的水印图
    wm64

  • 测试结果
    test_plot_src512_wm64_block4_jpg60-100_mod16-32
    test_plot_src512_wm64_block4_jpg60-100_mod16-32

  • 使用反色(黑底白字)水印的结果
    test_plot_src512_wm64b_block4_jpg60-100_mod16-32
    test_plot_src512_wm64b_block4_jpg60-100_mod16-32

  • 使用纯黑白原图(接近bitmap)的测试结果
    testb_plot_src512_wm64_block4_jpg60-100_mod16-32
    testb_plot_src512_wm64_block4_jpg60-100_mod16-32

  • 使用纯黑白原图(接近bitmap)且黑底白字的测试结果
    testw_plot_src512_wm64_block4_jpg60-100_mod16-32
    testw_plot_src512_wm64_block4_jpg60-100_mod16-32

  • 使用纯黑白原图(接近bitmap)且黑底白字+黑底白字水印的测试结果
    testw_plot_src512_wm64b_block4_jpg60-100_mod16-32
    testw_plot_src512_wm64b_block4_jpg60-100_mod16-32


  • 基本跟预想的差不多,在灰度图上比较容易混入信息,纯黑纯白就很难。
  • 比较意外地是mod的有效性,跟之前的情况完全不同。
  • 这样会导致在一些场景效果不佳,比如黑白漫画,或者大幅白色背景的产品图,等等。
  • 主要问题还是mod的设置,又不可能全部导多份手动选图。
    多参数输出多份,然后用ncc或者ocr去判断水印有效性,最后择优选用虽然也可以,但比较绕。

@Erimus-Koo
Copy link
Author

Erimus-Koo commented Jul 2, 2020

做了一张没有Y通道(Y只有纯白色)的图

好像在哪里看到一眼说明说主要取Y通道,就试了试。
LAB,其中L也是明度。明度通道空白,另外两个通道用了同样的图。
特地看了下YUV输出时的Y,的确也是纯白。
image

  • 原图
    noy512

  • 测试结果
    noy_plot_src512_wm64_block4_jpg60-100_mod16-32
    noy_plot_src512_wm64_block4_jpg60-100_mod16-32

noy_plot_src512_wm32_block4_jpg60-100_mod16-32
noy_plot_src512_wm32_block4_jpg60-100_mod16-32


  • mod=24表现最好,感觉可能和8位3通道有关。
  • 但jpg70很奇怪地出现了断档。
  • mod=28也出现了个断档。

@guofei9987
Copy link

guofei9987 commented Aug 11, 2020

我看懂了代码,个人理解是这样的:

  1. block 越大,嵌入的图跟原图比较,变化越小,但水印越不稳定。
  2. 水印只取第一通道,并且bit化,所以水印通道、反色什么的,意义不是很大。
  3. 没测试,只是从代码中理解上是这样,不知道上面实际测试时候是不是这样
  4. 你的测试结果,横纵坐标和标题都没看懂,希望解释一下(另外,乘号会被解析为斜体,用✖️)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants