首页 > 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

  • 哇哦。。好神奇~

    • 其实我只是来给Mathematica做传教士的~

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

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

  • 吊炸天

    • Mma用起来确实给人高大上的感觉。。2333

  • Rye

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

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

      • Rye

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

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

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

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

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

    • 不应该啊,个人感觉应该是你mask那张图片没弄出来吧,你专门看看掩模图是不是一张全黑的。。

      • 要全黑的?

      • 搞定了,谢谢。

        • Inpaint函数第三个参数貌似也挺有意思的~

          • 我是Inpaint[img, mask]。

            • 嗯,但是实际上还有第三个参数可是设置inpaint算法的系数的

              • 我刚接触Mathematica。。。

  • 学习了

  • 神器啊!

    • 嗯,我觉得这个比软件还方便。。

      • 有中文版本的么?看你的示例图,好像有英文

        • 有的。。。整个的教程都有中文的。。。代码是英文而已。。

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

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

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

  • 无影东瓜

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

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

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

    • 就Mma的一个函数。

  • OX

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

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

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

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

      • yuki

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

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

  • yuki

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

  • yuki

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

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

  • 哈哈哈

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

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

  • 膜拜,学习了

  • zuro007

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

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

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

  • 不错

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

  • 路人辛

    给图片去马赛克来一个呗

  • 我来留下脚印

  • unnamed5719

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