本文来源公众号“OpenCV与AI深度学习”,仅用于学术分享,侵权删,干货满满。

原文链接:实战 | 文本图片去水印--同时保持文本原始色彩(附源码)

0 导读

本文主要介绍文本图片中去除水印并尽可能保留文本原始色彩的实例。

1 背景介绍

OpenCV中去除水印最常用的方法是inpaint,通过图像修复的方法来去除水印,最终效果也要根据实际图像来看(时好时坏)。有些图像并不适用inpaint方法来去除水印,比如下面的这种包含文本的图像中的水印,即便提供了水印的mask图,修复后也会丢失文字信息,这并不是我们想要的。

以下图为例:

提供水印mask图:

使用inpaint来去除水印的效果:

从上图我们可以明显看出inpaint处理后原有文字信息遭到破坏,这样的效果可以说很糟糕。

2 使用OpenCV亮度/对比度变换来去除图片水印

下面图像中的水印该如何去除?有没有一种通用方法,能很好去除这些水印?答案是:没有通用方法,只能具体问题具体分析

2.1 实现步骤

仔细观察上面的图像并分析文本与水印的像素值不难发现,图中文本和水印的灰度值或者RGB值有明显差异:

【1】图案水印RGB值(取样值:239,236,253)

【2】文字水印RGB值(取样值:215,215,215

【3】文本RGB值(取样值:114,112,125

接下来对图像做对比度和亮度变换:

result = alpha * src - beta (alpha = 2.0, beta = -165)

提高对比度*2时水印消失,然后降低亮度做补偿。

2.2 代码实现

Python-OpenCV实现代码:

import cv2
import numpy as np

img = cv2.imread("mark.jpg")
alpha = 2.0
beta = -165
#alpha = 3.0
#beta = -200
result= alpha * img + beta
result= np.clip(result, 0, 255).astype(np.uint8)
cv2.imwrite("result.png", result)

print('Done!')

C++ OpenCV实现代码:

#include <iostream>
#include <opencv2/opencv.hpp>

using namespace std;
using namespace cv;

int main()
{
  Mat src = imread("mark.jpg");
  if (src.empty())
  {
    cout << "src img load failed!" << endl;
    return 1;
  }
  imshow("src", src);
  Mat result = 2.0 * src - 165;
  imshow("result", result);
  waitKey();
  imwrite("result.png", result);
  return 0;
}

运行结果图

原图与结果图对比:

2.3 不足

但是这种方式也存在一定的问题,如下面的图片:

代码示例:

import cv2
import numpy as np

img = cv2.imread("kk.jpg")

alpha = 3.0
beta = -200

new = alpha * img + beta
new = np.clip(new, 0, 255).astype(np.uint8)

cv2.imwrite("cleaned.png", new)

实现效果如下图所示:

乍一看,水印很好的去除了,结果还不错!但是,仔细对比发现,部分文字信息颜色与原本的颜色产生了明显差异,如下图所示:

文字与箭头颜色明显变化

处理后文本颜色变化明显

所以这种方法,也有一定的弊端,使用时需注意!

3 使用inRange方法更好的保留文本原始色彩

那么我们如何让它去除水印的时候又能很好的保留文本原始的色彩呢?这里提供一种方法,具体步骤如下:

【1】使用inRange方法,获取水印区域的mask;

【2】与原图对比,mask区域内白色位置置为白色(255,255,255),mask区域内黑色位置保留原始文本像素值。

具体代码如下:

import numpy as np

import cv2

font = cv2.FONT_HERSHEY_SIMPLEX

img = cv2.imread("./kk.jpg")
lower_hsv = np.array([160,160,160])
upper_hsv = np.array([255,255,255])

mask = cv2.inRange(img,lower_hsv,upper_hsv)#根据颜色范围删选
mask = cv2.GaussianBlur(mask,(1,1),0)
for i in range(0,img.shape[0]): #访问所有行
  for j in range(0,img.shape[1]): #访问所有列
      if mask[i,j] == 255:
          img[i,j] = [255,255,255]  
cv2.imwrite('res.jpg', img)
print('Done!')

运行效果:

细节对比:

------------------------------------------------------------------------------------------------------------------

对比发现,去除水印的同时较好的保留了文本原始的色彩,方法仅供大家参考,具体问题还需具体分析!

THE END!

文章结束,感谢阅读。您的点赞,收藏,评论是我继续更新的动力。大家有推荐的公众号可以评论区留言,共同学习,一起进步。

GitHub 加速计划 / opencv31 / opencv
77.39 K
55.71 K
下载
OpenCV: 开源计算机视觉库
最近提交(Master分支:2 个月前 )
48668119 dnn: use dispatching for Winograd optimizations 6 天前
3dace76c flann: remove unused hdf5 header 6 天前
Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐