【DIP】一种去水印的方案

这是一个用来去除水印的小demo。

适合于去除水印颜色较浅,保留元素颜色较深的图片。

比如白底黑字,但带白色或灰色的图片或者其他彩色图片但有白色或灰色水印

该算法对于偏暗的图片去水印的效果不是很好。

基于滑动窗口的图片去水印方法

  • 传统去水印方式是统计图片上水印的像素值范围,将RGB值属于某一范围内的像素赋值为[0,0,0]或[255,255,255]已达到去水印效果。

  • 但对于受光照影响或本身图片较暗的图片,上述去水印方法效果不理想。

  • 针对以上特征的图片,采用局部去水印的方式。

  • 具体体现在三个改进点上:

  • 1、 利用滑动窗口分割图片

  • 2、 针对局部图片采用像素替换的方案A。

像素替换方案A:

图片中需要识别的文字均为黑色,其对应的像素值低。图片中水印位置以及有光照的位置颜色偏白,对应的像素值较高。

将RGB值和高于某个阈值的像素,重置其像素值为[255,255,255]即将颜色置为为白色。达到去除水印的效果。该阈值的设定根据整体像素和的分位数来确定。

滑动窗口的设计让算法关注于局部的颜色差异,分位数的设计让需要改变的像素点根据局部的情况独立确定,避免全局的明暗和其他元素(如国徽)等的影响。

  • 3、通过将滑动窗口由小至大的调整,可以进一步增强去水印的效果,使得去除水印后的文字像素损失进一步降低。

【DIP】一种去水印的方案_第1张图片

我把代码放在了github上。

import cv2
import numpy as np
import os

def move_mark(slices,percentile_ratio):
    hight, width, depth = slices.shape[0:3]
    sum_ = slices.sum(2)
    t = list(set(list(np.array(sum_).flat)))
    qual = np.percentile(t,percentile_ratio)
    for h in range(hight):
        for w in range(width):
            if sum_[h][w] > qual:
                slices[h][w] = [255,255,255]
    return slices


def sliding_window(image, stepSize, windowSize):
    # slide a window across the image
    for y in range(0, image.shape[0], stepSize[1]):
        for x in range(0, image.shape[1], stepSize[0]):
            # yield the current window
            yield (x, y, image[y:y + windowSize[1], x:x + windowSize[0]])


# 返回滑动窗结果集合,本示例暂时未用到
def get_slice(image, stepSize, windowSize):
    slice_sets = []
    for (x, y, window) in sliding_window(image, stepSize, windowSize):
        # if the window does not meet our desired window size, ignore it
        if window.shape[0] != windowSize[1] or window.shape[1] != windowSize[0]:
            continue
        slice = image[y:y + windowSize[1], x:x + windowSize[0]]
        slice_sets.append(slice)
    return slice_sets


def do_remove_mark(image,percentile_ratio,size_):

    # 自定义滑动窗口的大小
    w = image.shape[1]
    h = image.shape[0]
    # 本代码将图片分为3×3,共九个子区域,winW, winH和stepSize可自行更改
    (winW, winH) = (int(w/size_),int(h/size_))
    stepSize = (int(w/size_), int(h/size_))

    for (x, y, window) in sliding_window(image, stepSize=stepSize, windowSize=(winW, winH)):
        # if the window does not meet our desired window size, ignore it
        if window.shape[0] != winH or window.shape[1] != winW:
            continue
        slice = image[y:y+winH,x:x+winW]
        image[y:y+winH,x:x+winW] = move_mark(slice,percentile_ratio)

    return image
    
    
# TODO
# path = "./train/1/"
# for img_ in os.listdir(path):
#     if img_[-3:] != "png":continue
#     image = cv2.imread(path + img_)
#     img = do_remove_mark(image,50,500)
#     img = do_remove_mark(img,50,3)
#     cv2.imwrite("./trainres/" + img_,img)   

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

以上方法致力于解决工商图片的水印去除问题。在以上解决方案的基础上,我们可以得到比较可行的结果。但是还有一些遗留问题,请教各位前辈相关解决方案:

去除水印后文字像素有所损失,对于这些损失的像素有什么方案可以补全或者增强?

本身是灰色的图片其像素值与水印接近,做以上处理之后,整个图片的文字细节大部分丢失,如何改进?

欢迎留言赐教,恭候,百拜!

【DIP】一种去水印的方案_第2张图片

 

你可能感兴趣的:(机器学习,python)