网络信息时代为了注明图片出处,大部分图像都存在水印,去除图片水印最常用的方法就是Photoshop,但是作为计算机视觉工程师我们可以开发在即去水印专用小工具。
在Opencv中有一个现成的函数inpaint
CV_EXPORTS_W void inpaint( InputArray src, InputArray inpaintMask,
OutputArray dst, double inpaintRadius, int flags );
根据选择中区域的邻域修复图像区域
@param src 输入灰度图或彩色图.
@param inpaintMask 修复区域的掩摸图像.
@param dst 输出图像.
@param inpaintRadius 每一个点修复时需要考虑周围区域的的范围
@param flags 选用的具体修复算法.
关于采用的具体修复算法,我也查了一些资料
flag设置为INPAINT_TELEA时是一种快速区域匹配方法,从图像区域的边界开始逐渐进入区域,根据周围区域的权重进行修复,为人工启发式操作,具体方法可以参见论文"An Image Inpainting Technique Based on the Fast Marching Method"
flag设置为INPAINT_NS时采用流体动力学和偏微分方差的方法,从已知区域沿边缘进入未知区域,使颜色最小方差最小化。具体方法可以参见论文Navier-Stokes, Fluid Dynamics, and Image and Video Inpainting"
为了验证方法的有效性,我找了如下图所示的带水印的图像。
首先通过灰度转化、阈值分割、膨胀等方法获取到图像水印区域。
然后调用opencv的修复函数即可完成图像修复。
Mat Img = imread("Img.jpg");//读取源图像
Mat GrayImage, MaskImage;
cvtColor(Img, GrayImage, CV_BGR2GRAY);
threshold(GrayImage, MaskImage, 220, 255, THRESH_BINARY);//阈值分割得到水印区域
dilate(MaskImage, MaskImage, getStructuringElement(MORPH_RECT, Size(5, 5)));//水印区域膨胀
Mat PaintImg;
inpaint(Img, MaskImage, PaintImg, 20, INPAINT_NS);//去水印
imshow("原图像", Img);
imshow("修复图像", PaintImg);
原图像
去水印后的图像