首页 > Mathematica > Mathematica给图片去水印

Mathematica给图片去水印

2014年2月2日 发表评论 阅读评论

去年华为在几所高校搞了个什么算法向的比赛(好吧,前年。。),看了一部分我们系里参赛的队伍最后的演示视频,印象比较深刻的是一个类似视频或者单帧图片去除不想要的部分的图像处理题目,当时记得貌似大量的人做了这道题目,然后大量的成果效果超好,那时还在想:现在的研究生算法已经这么厉害了?直到后来某一次我需要做一个去除水印的东西后,终于觉悟这不就是一个去除水印问题么??而且。。。搜了一下,这方面的研究已经无比成熟了。。。软件都满天飞了。。【果然技术这种东西只能吓唬行外人士。。】

就现在而言,一般给图片去水印比较常见的两个方法是:

  1. Photoshop:这个网上搜索教程一大堆。。
  2. 使用去水印专用软件

关于专用软件,由于我的这方面的需求极少,我才不会为了这种破事儿去专门搞一个软件呢。至于Photoshop,我电脑里装有这个,但是一般只用于两件事,有人(比如老板)叫我用photoshop修一下图或者做一个什么图标,还有就是把博客里面上传的图的背景搞成透明(考虑到以后可能博客主题背景不是白色,所以一般图片我都会把背景弄成透明的以适应背景颜色,比如本文下面的大部分图片其实背景都是透明而不是白色的。。),至于PS用于去水印嘛,以前学习PS的时候试过,但是效果感觉不好,果然我就是和PS气场不和。。

对我而言,最幸运的事就是Mathematica正好有一个Inpaint函数可以来修图去水印,更加幸运的是,Mma语法支持直接把图片当做参数直接传进去,这样就把使用的便捷程度Level MAX了!!

对于这个函数,先看几个官方文档里面的几个例子:

e.g. 1
inpaint1


e.g. 2
inpaint2


e.g. 3
inpaint7


可以看出这个函数本身就很强大,需要两个参数,原图片和抠图的MASK,而且事实上还可以添加第三个参数说明用什么算法来修图,这个我们就不管了,感兴趣的可以去看Mma的文档。

为了实现轻而易举的去水印,我们可以先看一下下面这个极具启发性的例子:
inpaint3

它完美地去掉了图片右下的日期标记,而且和上面相比最大的区别是,没有出现黑白的MASK图片了,我给大家解释一下思路,其实它是有Mask的,用的是二值化函数Binarize来生成二值黑白图片,生成的准则是把原图片分成RGB三层(ColorSeparate),然后把所有R层像素值大于255×0.93的设成白色,其余黑色,所以本质还是和上面的一样。【由于考虑到图片可能有损压缩导致边缘模糊,所以最后用了一个形态学处理函数Dilation

以此为基础,我就想到了一个操作上很简单的去水印的方法,比如我们要对下面这幅图去掉左上角的文字和图片中间的人,显然的,还要去掉倒影:
inpaint5

然后我们用最传统的工具——————QQ截图,然后在上面用画刷涂抹我们想要去掉的部分,请不要问我是怎么截到QQ截图的画面的:
inpaint4

这里涂抹的原则有三个,第一,画刷区域宜大不宜小,第二,请尽量不要不小心在画刷区域留下空洞,哪怕一个像素点!除非你本身刻意而为之,第三,画刷颜色一定要挑图片中没出现过的颜色,比如上图中用到的红色。

然后要做的事情就很简单了,首先和之前一样把纯红色(RGB=#F00)的部分用Binarize扣出来做成模板,然后考虑到QQ截图出来的图不一定可以做到和原图大小一样,所以再来一个缩放MASK图片到与原图一样就可以了。

之后去水印就是一行代码的事儿,最后两个参数分别就是原图和QQ截图画刷处理的图:

Inpaint[#1,ImageResize[Binarize[#2,#=={1,0,0}&], ImageDimensions@#1]]&[img,mask]

结果如下:
inpaint9

所以一般我去除水印的方法就是:打开Mma,然后Ctrl+C,Ctrl+V上面一行代码,把待处理图片直接贴上去,QQ截图抹两下,运行,收工。

没用过Mathematica的同学是不是觉得可以直接把图片作为参数来编程简直爽炸天?!

好吧,文章越写越短了。。这样不好。。这样不好。。。


【完】

本文内容遵从CC版权协议,转载请注明出自http://www.kylen314.com

  1. 2014年2月4日15:17 | #1

    哇哦。。好神奇~

  2. 2014年2月4日15:18 | #3

    我知道怎么截到QQ截图界面的

    • 2014年2月4日20:22 | #4

      其实我也觉得应该没什么人不知道。。。但是确实就是有人不知道。。囧。。

  3. 2014年2月4日15:38 | #5

    吊炸天

  4. 2014年2月5日18:36 | #7

    好玩儿 而且效果不错的样子唉 好奇用的啥算法

    • 2014年2月5日19:29 | #8

      我感觉Mma比起编程工具,更像是个玩具~其实效果还勉强,如果设置一下缺省的参数效果可以更好~

      • 2014年2月5日20:24 | #9

        对…… 基本一直拿它当计算器使…… 还有画画图啥的

        • 2014年2月5日20:46 | #10

          计算器。。。太大材小用了吧~用它来做五子棋,电子琴,爬虫,人人or微博发发状态什么的都是不错的~

  5. 2014年2月7日09:08 | #11

    用覆盖一个第三方色块的方法去除,你真是太有才了,膜拜

    • 2014年2月7日14:17 | #12

      方法是官方的那个照片去日期的例子里面得到的灵感。。。实现起来就一行代码。。

  6. 2014年2月7日12:24 | #13

    为什么我按照你所说的进行操作,图片却没有变化。

  7. 2014年2月7日22:15 | #21

    学习了

  8. 2014年2月16日11:26 | #22

    神器啊!

  9. 2014年2月27日13:16 | #27

    Mathematica的图像处理功能非常之强大!非常!什么图像修复、组件识别、制作各种格式的图片等,都有现成的函数。我是个纯数学专业的孩子,学了M之后也很喜欢处理图像了。

    • 2014年2月27日13:21 | #28

      如果是PS那种处理图片的功能的话,那确实很强大,但是有些函数涉及到参数的设定,可能用起来不一定有PS爽。。如果是人机交互那种级别的图像处理的话。。。那Mma还是不够。。

      • 2014年2月27日21:05 | #29

        嗯。一般修图制图还是用PS的。感觉PS与Mma的绘图功能,就像SPSS与SAS。

  10. 无影东瓜
    2014年3月1日22:21 | #30

    大赞,可以修照片玩了。不过本身色彩就比较齐全的图片这招就不太好使了,还是得老老实实手画黑白mask但是那个黑白mask该怎么做?我能想到的方法只有用PS新建图层然后涂白,但是实在懒得装PS,有没有什么简便些的方法?多谢了

    • 2014年3月1日23:43 | #31

      可以用出现得比较少的一种颜色去涂,然后二值化后可能有一些小杂点,要么用形态学那些开闭运算腐蚀掉,要么检测最大块。

  11. 2014年3月8日21:26 | #32

    这神马技术,得折腾看看。

  12. 2014年3月14日23:56 | #34

    我认为可以把这个做个GUI界面出来…搞个傻瓜去水印..之前用Mathematica榜图片去过噪…感觉很逆天٩(๑>∀<๑)۶

    • 2014年3月15日00:19 | #35

      靠谱,博客正好可以插入CDF文件给装有mma的人交互

  13. 2014年3月18日01:40 | #36

    Mma 这么强大啊!!!算法是基于什么原理的啊?

    • 2014年3月18日13:34 | #37

      可以设置算法的,默认是“Texture Synthesis”,帮助文档说这是利用随机采样的最佳拟合纹理合成方法,还可以指定迭代各向同性扩散方法,迭代全变差方法,Navier-Stokes 方法,快速行进方法这几个。【不明觉厉的样子。。】

      • yuki
        2014年4月15日00:12 | #38

        Navier-Stokes 方法是什么。。。看着像流体力学。。。

        • 2014年4月15日01:34 | #39

          你没猜错,就是从流力的那个公式里面引申出来的图像处理算法。。什么边界条件啊,梯度神马的。。

  14. yuki
    2014年4月17日00:19 | #40

    忧伤。。。我怎么重复不出来。。。

  15. yuki
    2014年4月17日00:37 | #41

    我想问下 Binarize[#2, # == {1, 0, 0} &] 里的# == {1, 0, 0} &是什么意思?~

    • 2014年4月17日00:43 | #42

      可以参见我最新那篇关于纯函数的描述。# == {1, 0, 0} &中&表示这是一个函数,#表示输入参数,也就是判断输进来的参数是不是等于{1,0,0},也就是红色。

  16. 哈哈哈
    2014年7月6日00:56 | #43

    太叼了,mma新人通过搜索进来的,跪舔。。

  17. 2014年9月27日19:05 | #44

    楼主,黑白图像好像不行吧。。。

  18. 2014年11月19日20:47 | #45

    膜拜,学习了

  19. zuro007
    2015年3月1日11:55 | #46

    请问我照原样输入Inpaint[#1,ImageResize[Binarize[#2,#=={1,0,0}&], ImageDimensions@#1]]&[img,mask],其中img就采用“插入”——“图片”——“来自文件”从你这下载的这个蓝色水面风景图,mask就用红色涂抹过的图,为何out结果木有任何变化呢?

    • 2015年3月1日17:00 | #47

      会不会是红色像素不是标准的(255,0,0)?因为代码是写死的必须{1,0,,0}

    • 2015年4月23日05:57 | #48

      你好,关于这句程序我还有点疑问想请教你, 能麻烦你加一下我QQ691449667么?非常感谢了

  20. 2015年4月6日23:55 | #49

    不错

  21. 2015年4月7日16:55 | #50

    我把水印涂成红色,用这个Inpaint[#,Dilantion[Binarize[Colorseparate[#][ ],0.93],1]&@img可以粗糙的除去水印,但是用Inpaint[#1,ImageResize[Binarize[#2,#=={1,0,0}&], ImageDimensions@#1]]&[img,mask]却没变化….是为什么呀?

  22. 路人辛
    2015年8月7日11:29 | #51

    给图片去马赛克来一个呗

  23. 2015年10月1日16:08 | #52

    我来留下脚印

  24. unnamed5719
    2016年11月6日00:05 | #53

    卧槽,强力马克,整篇看下来嘴巴都变大了,太逆天了

  25. 2018年9月26日12:25 | #54

    节操留言~

    我用的是8.0,弄不出来

验证码:8 + 0 = ?

友情提示:留言可以使用大部分html标签和属性;

添加代码示例:[code lang="cpp"]your code...[/code]

添加公式请用Latex代码,前后分别添加两个$$