python+OpenC不仅能用来为图片添加水印logo,还能用来去除图片的水印。从理论上来说,除非原图中水印所在区域为纯色或有规律的图案,否则无法真正去掉水印,因为加水印的过程是不可逆的,我们无法准确判断水印遮盖区域的像素点颜色,因此无法将图像完全恢复成之前的样子。通常的做法是识别出水印的轮廓,使用膨胀算法覆盖水印。
上篇文章我们介绍了python+OpenC为图片添加水印logo的方法(实现效果如上图),本文就来讨论如何去掉上图中的水印。我们首先要手动取得水印所在区域ROI(感兴趣区域),并为水印创建蒙层(mask),然后借助蒙层对图片进行修补以消除水印。
提取ROI:我们在画图中打开图片,放大之后将鼠标停留在图片中某一位置即可在左下角查看到具体的坐标。使用切片roi = img[918:999, 455,679]提取ROI,需要注意的是图片坐标与二维数组位置是相反的,图片坐标(x, y)中x表示像素点到图片左侧的距离,y表示像素点到图片顶部的距离,而二维数组位置(x, y)中x表示该像素点所在行数,y表示该像素点所在列数,两者虽然都是两个数字,但顺序正好相反。
为水印创建蒙层:通过对水印logo的观察可以发现,该水印由红蓝两种颜色构成,因此我们需要对两种颜色分别处理。为了精确处理蓝色,我们可以先将ROI的颜色格式由BGR转换为HS,然后调用inRange( )函数对ROI进行二值化处理,将蓝色区域变成白色,将其它区域变成黑色,这样就创建好了蓝色的蒙层(mask)。关于inRange函数和HS请读者自行百度,本文不做详细介绍。
图片修补:将水印区域放大之后发现在水印的边缘有很多锯齿噪点,这些噪点与水印的颜色相差较大,很影响去除水印的效果。为了消除这些边缘噪点需要调用dilate( )函数对水印蒙层进行膨胀操作,膨胀是数学形态学的基本操作之一,会使蒙层适当扩大“淹没”边缘可能存在的噪点;接下来就是利用膨胀后的蒙层对ROI进行修补,用到的函数是inPaint( );最后一步把修补之后的水印区域回填到原图中,完整代码如下图:
因为原图中水印有两种颜色,我们需要先后对水印中的蓝色和红色部分进行处理。需要提醒的是:HS格式也是由三个数字表示,H的取值范围是0-180,S和的取值范围是0-255,不同颜色对应的HS的取值范围也是不同的,读者可以从网上。去除水印之后的图片如下所示:
不得不说这个水印消除的很完美,即使将上图放大还几倍也很难发现这是一张去除水印的图片。文中使用的图片素材和完整代码已上传至网盘,请移步我的同名微博获取下载链接。如果你对本文内容感兴趣请点个赞,我将持续更新精彩内容,请保持。