怎么用命令行让照片上的小痘痘消失

为什么要写这样一个文章

原本应该按TW的作业要求写一篇对命令行的认识,但看了半生不熟的點不小同学的一篇文章,里面提到了这样一个问题:

但不得不说,命令行不好的地方是
我就想让照片上妹子脸上的小痘痘消失,怎么用命令行实现呢

确实是个难题…不过也不是不可能,那下面就来试试吧。

我最常用的Linux命令

首先按TW国际惯例,列举出15个我最常用的Linux命令:

history | awk '{CMD[$2]++;count++;} END { for (a in CMD )print CMD[ a ]" " CMD[ a ]/count*100 "% " a }' | 
grep -v "./" | column -c3 -s " " -t |sort -nr | nl | head -n15 

用上面的命令就可以打印出使用过的排名前十五的命令:

   rank  times percentage command
     1  220  36.4842%   sudo
     2  28   4.64345%   sh
     3  28   4.64345%   cd
     4  24   3.9801%    git
     5  23   3.81426%   ifconfig
     6  22   3.64842%   exit
     7  18   2.98507%   ryu-manager
     8  18   2.98507%   ping
     9  17   2.81924%   vncserver
    10  16   2.6534%    ls
    11  15   2.48756%   echo
    12  10   1.65837%   wget
    13  9    1.49254%   ovs-ofctl
    14  9    1.49254%   gedit
    15  7    1.16086%   nslookup

好吧,第一竟然是sudo,如果要细分的话,应该还有apt-get、pip、mv、rm、kill、mn等命令没有显示出来;再加上管道之后的命令可能不统计,所以应该还有一大部分grep

命令行去痘之旅

下面我们就正式开始命令行去痘之旅。

  • 首先,选一张照片:
    《怎么用命令行让照片上的小痘痘消失》 带痘痘的原图
    如果都用命令行操作的话,就不能这样看图片了,假设机子上啥都没装,只有最基础的vi可以用,我们可以用vi打开这张图片,为了输出格式整齐,还可以将文件转换成16进制数据:
vi doudou.bmp
按ESC输入:%!xxd

《怎么用命令行让照片上的小痘痘消失》 以十六进制方式打开图片

  • 找痘痘
    根据bmp格式的定义,从0x8b开始就是图像像素数据,顺序为BGRA。由于痘痘部分的颜色比正常肤色深,所以可以根据其RGB值找出痘痘的区域。
    分析了一下,图中痘痘区域的RGB值约为ec8fab(236, 143, 171),正常肤色约为f79fc1(247, 159, 193),可见,痘痘的GreenBlue部分颜色较重,所以就可以根据这个数值的差别找出痘痘区域。但!画面复杂,找起来太费劲,况且这个任务的核心是让痘痘消失,所以找痘痘这一步可以略过。。
    实际操作中我是靠人力找的,并记录下像素区域位置。

来个色盲测试:

《怎么用命令行让照片上的小痘痘消失》 痘痘颜色(236, 143, 171)

《怎么用命令行让照片上的小痘痘消失》 正常肤色(247, 159, 193)

  • 找替换色块
    去痘的核心就是用正常肤色覆盖痘痘,所以可以用痘痘旁边的像素数据,覆盖到痘痘区域的数据。我用的是痘痘左边的11*11的像素块。

  • 替换像素块
    具体数据有点复杂,我举个例子。
    首先在vi中利用以下命令,跳转到正常肤色区域(假设为2cdd0行):

:2cdd0  (到该行,或使用2cdd0G)

《怎么用命令行让照片上的小痘痘消失》 假装是正常肤色区域

接着,
复制需要的像素(假设为此行的开始8个字节——“f3ff 97b8 f0ff 96b7”):

y4w  (用空格隔开,复制4个单词)

然后,光标移到下一行,并将已复制的数据粘贴到痘痘区域(假设为2cde0行):

p  (粘贴)

《怎么用命令行让照片上的小痘痘消失》 假装复制到了痘痘区域

删掉多余的痘痘数据:

d4w  (从光标开始,删除4个单词)

《怎么用命令行让照片上的小痘痘消失》 假装替换好了像素数据

如果事先知道源字符串和目标字符串的具体内容,可以用以下命令直接做
替换

:[range] s/search/replace/[flags] [count]
Example:
:1,$ s/Professor/Teacher/g  (将全文的Professor改为Teacher)

其实以上只完成了一行的覆盖操作,如果要将11*11的像素块全覆盖过来,那还要操作10次吗?。。
其实如果像素比较规整的话,就可以用宏操作去批量处理。

  • 批量替换像素块
    在上一节操作之前,先在Normal模式下进行宏操作录制
qa  (启用宏录制,使用a寄存器保存,命令行中会出现“记录中@a”字样)

之后依次进行上述操作,注意光标的移动即可。
然后,在需要重复进行此动作的像素位置进行回放:

@a  (回放a寄存器中的动作)
5@a  (重复5遍这个动作,注意宏录制时光标的最终位置)

《怎么用命令行让照片上的小痘痘消失》 宏操作举例

但如果像素位置比较乱,就不能用这个方法了。

  • 看看[伪]效果
    《怎么用命令行让照片上的小痘痘消失》 命令行去痘效果

什么?你看到了两块方方的块,那快把眼镜摘掉吧,这样是不是好多了?

开个玩笑,其实用这种方法去痘的效果肯定不好,太暴力了。如果引入一些图像处理算法,并完善细节,效果会更好。当然也可以利用一些图像美化的API,实现去痘的效果。
因此,可以用命令行去掉照片上的小痘痘,但效果不一定满意,而且过程也很繁琐。

对命令行的一点点看法

  • 某种意义上命令行可以完成所有事
    实际上,所有的I/O任务、计算任务等都是由程序完成的,换句话说,可以用命令行做到。
    但对于要与图像进行交互的任务,GUI是个很好的选择,它们将复杂的操作封装起来,对用户更友好。
  • 那命令行究竟好在哪里呢?
    一个重要原因是,对于IT工作者,鼠标操作的坐标不确定性,提高了工作的时间成本,相比于键位固定的键盘来说,鼠标操作的效率更低。
    对于大部分任务,如文件操作、编辑文本、压缩解压缩、网络配置等,都有强大的命令集做支撑,此时命令行显然更快。
    而对于与图形界面相关的任务,如浏览网页、图片处理等,虽然纯键盘也可以搞定,但还是不太方便,不然也不会有这么多UI工程师在GUI上花大力气去设计了。
  • 为什么那些黑客就一直在键盘上啪啪啪,他们不用图形界面吗
    他们的主要任务是底层逻辑分析、文本处理等,可以不需要鼠标操作。并且大部分工具都是黑客自己编写的,加一个GUI很费劲的啊!

像黑客一样装逼 http://geektyper.com/

彩蛋

最后分享一个命令,是不是有点像贪吃蛇呢~

alias cd='rm -rf'

参考文章

    原文作者:sunshy360
    原文地址: https://www.jianshu.com/p/423b0609441c
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞