识别全屏水印or水印识别

一。背景

  现在非常多的公司和个人,都需要使用到网上的图片,比如用来做实验,用来做展示等等。但是呢,很多网上的图片,其实并不是免费使用的,都是有版权的,你要是使用了别人的、“未公开”的图片,那么别人可能就要起诉你了。
  所以,当我们需要使用到网上的图片的时候,一定看搞清楚你使用的图片是否合法。如果是少量图片,那么我们还可以人工观察是否有水印,但是如果是大批量的图片或者不定时的图片(比如开放给用户上传图片的页面,用户就可能上传其他竞品公司的图片进来,就可能造成侵权),那么通过人工就不好检测了。那么就需要技术来识别图片是否带水印了,从而达到高效、实时下架非法数据的作用。

  由于单个的深水印(水印小,而且明显),很好实现识别,下面讨论的都是全屏的浅水印。(本文以:中国最大的房产交易平台——房多多的图片为例,给大家讲解水印识别)


14728027.jpg

二。下面以python代码为例,讲解识别全屏水印的整个流程

0,流程图:(https://www.processon.com/view/link/5dca1ca4e4b0e3a6348a53fa)
process.png
1,先准备数据;

  1.1 提取水印边缘图的图片 —————— 图片大小相同、水印位置大小相同的图片;(比如20张-30张)
  1.2 用于计算阈值的带水印的图片(约50张);
  1.3 用于计算阈值的不带水印的图片(约50张);

2,提取水印边缘图;

(1)基于sobel算子,计算x方向的梯度、y方向的梯度;

 gradx = map(lambda x: cv2.Sobel(x, cv2.CV_64F, 1, 0, ksize=KERNEL_SIZE), images)
 grady = map(lambda x: cv2.Sobel(x, cv2.CV_64F, 0, 1, ksize=KERNEL_SIZE), images)

(2)基于多张模板图片,计算中值梯度;

    Wm_x = np.median(np.array(gradx), axis=0)
    Wm_y = np.median(np.array(grady), axis=0)

(3)基于上面x、y方向上的中值梯度,得到总梯度;

Wm = (np.average(np.sqrt(np.square(gx) + np.square(gy)), axis=2))

(4)归一化到 [0,255]的整数

_Wm = (255 * PlotImage(Wm)).astype(np.uint8)

(5) ostu进行二值化,阈值为0和255

 _, W_2 = cv2.threshold(_Wm, 0, 255, cv2.THRESH_OTSU)
wm.jpg
3,提取子水印边缘图

(1)膨胀5次

    W_2_dilate = cv2.dilate(bin_img, np.ones((2, 2), np.uint8), 5, iterations=5)
W_2_dilate.jpg

(2) 连通区域标记

    label_image = measure.label(W_2_dilate).astype(np.uint8)
image.png

(3)连通区域的提取(拿到最多像素值的连通区域即可)

# 循环得到每一个连通区域属性集
for region in measure.regionprops(label_image):  
       minr, minc, maxr, maxc = region.bbox
       _max_value = np.sum((bin_img[minr:maxr, minc:maxc] > 0) * 1.0)
       if _max_value > max_value:
           max_value = _max_value
           best_boundary = minr, minc, maxr, maxc
           best_sub_wm = bin_img[minr:maxr, minc:maxc] 
sub_wm.jpg

=================== 下面是计算待识别图片的最佳重合度 ==============

4,提取“待识别图片”的边缘(使用canny算子提取边缘,用弱边缘减去强边缘来优化)
# 对原图进行canny得到边沿图。
# 使用canny进行非极大值抑制。https://blog.csdn.net/fengye2two/article/details/79190759
img_edgemap = (cv2.Canny(img, 18, 20))  # 弱边缘
img_edgemap_strong = (cv2.Canny(img, 20, 200))  # 强边缘
img_edgemap_weak = img_edgemap * 1.0 - img_edgemap_strong * 1.0
image.png

我们可以从上图发现,经过减少强边缘,既能保留原来的水印边缘,又可以去除部分非水印边缘,起到优化的效果。

5,尺寸截取———— 将2的水印边缘图和4的待识别图片边缘图,截取成相同大小的图片
# 模板水印、图片,剪切成尽量大的图片。。并缩放到0和1
m, n, p = np.shape(img)  # 这个是图片的大小
m1, n1, p1 = np.shape(gx)  # 这个是水印的大小
W_2 = W_2[:min(m, m1), :min(n, n1)] / 255
img_edgemap_weak = img_edgemap_weak[:min(m, m1), :min(n, n1)] / 255

————————这步是为了识别不同大小的图片。(这样截取的前提是水印并没有根据图片大小进行缩放,而且水印都是左上角对齐)

6,计算重合度;
(1)# 计算重合图片【不用卷积】
img_wm = np.multiply(img_edgemap_weak, W_2)
img_wm.jpg

(2)# 计算最佳的子水印 与 待识别图的边缘图 的重合度。【注意:使用0边界填充参数】

chamfer_dist = cv2.filter2D(img_wm.astype(float), -1, sub_wm.astype(float), borderType=cv2.BORDER_CONSTANT)  
max_sim = np.max(chamfer_dist) / np.sum(sub_wm)  # 卷积重合的效果,跟理想最佳的重合的比例。(值域:[0,1])
7,针对1.2 和1.3 的图片,计算各自的重合度;然后设定阈值;
8,基于7中的阈值,识别待识别的图片。
        if max_sim > THRESHOLD:
            return True
        else:
            return False

三。其他的疑问:

1,同样是提取边缘,怎么一会是sobel算子,一会是canny算子?

  这个就是实验才知道哪个比较适用。不同场景下使用不同的算子会有不同的效果。

2,这整个流程是怎么来的?

  摸索着来的。。比如:1:为什么要提取子水印边缘图?因为全屏的水印边缘图,区分度不够,发现子水印边缘图区分度高。
  比如2:使用canny算子提取边缘,阈值为什么是18,20,200?每个参数有它的意义,要先搞清楚参数的意义。然后具体来说,为什么是18,而不是17,那就是要人工调试了,发现哪个的效果好,就用哪个。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,456评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,370评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,337评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,583评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,596评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,572评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,936评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,595评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,850评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,601评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,685评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,371评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,951评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,934评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,167评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,636评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,411评论 2 342

推荐阅读更多精彩内容

  • 边缘检测是图像处理和计算机视觉的基本问题,边缘检测的目的是标识数字图像中亮度变化明显的点,图像属性中的显著变化通常...
    Daniel大人阅读 6,025评论 0 0
  • 文章目录 1、给定0-1矩阵,求连通域。 二值图像分析最重要的方法就是连通区域标记,它是所有二值图像分析的基础,它...
    王永迪阅读 6,062评论 0 3
  • 1、阈值分割 1.1 简介 图像阈值化分割是一种传统的最常用的图像分割方法,因其实现简单、计算量小、性能较稳定而成...
    木夜溯阅读 22,555评论 9 15
  • 1、阈值分割 1.1 简介 图像阈值化分割是一种传统的最常用的图像分割方法,因其实现简单、计算量小、性能较稳定而成...
    Lornatang阅读 9,448评论 0 5
  • 晚安篇[月亮] 每一次成长的经历不管好的坏的总会记录下来,希望多年后回头看看自己发生了多大的变化,从去年到现在有好...
    LYY_愿i阅读 186评论 0 0