简体   繁体   English

从 Python 中的图像获取水印掩码

[英]Get mask of watermark from image in Python

Given a series of photos that are watermarked, I want to isolate the watermark, and generate a mask.给定一系列带水印的照片,我想隔离水印并生成蒙版。

I'm using Python and numpy.我正在使用 Python 和 numpy。

I've added the pictures on top of each other:我已将图片叠加在一起:

def compare_n_img(array_of_img_paths):

img_float_array = []

for path in array_of_img_paths:
    img_float_array.append(load_img_as_float(path))

additionF = sum(img_float_array)/len(img_float_array)

addition = additionF.astype('uint8')

return addition

This, convered to grayscale, gives me this composite image .这个,转换为灰度,给了我这个合成图像

The watermark is distinctly visible in this composite.水印在此合成中清晰可见。 For a human, it would be easy to trace.对于人类来说,很容易追踪。

What I want as a result is a white image, with the shape of the watermark filled in black.结果我想要的是一张白色的图像,水印的形状用黑色填充。 So that, if I overlay one of my watermarked images with the mask, the watermark would be completely covered.因此,如果我用蒙版覆盖我的水印图像之一,水印将被完全覆盖。

I've tried to use edge detection and thresholding on the composite image.我尝试在合成图像上使用边缘检测和阈值处理。 But I've not been able to find a way to programmatically isolate the watermark content.但是我一直无法找到一种以编程方式隔离水印内容的方法。 Much less to create a clear mask.更不用说创建一个清晰的面具了。

I'd like to do this in pure numpy, or cv2, if possible.如果可能的话,我想在纯 numpy 或 cv2 中执行此操作。

You can try blurring the image before using the canny edge detector.您可以在使用精明边缘检测器之前尝试模糊图像。 As the detected edges would be too thin, an iteration of dilation and erosion would fix the problem.由于检测到的边缘太薄,膨胀和腐蚀的迭代将解决问题。

After the edges are detected, there would most likely be a lot of noise in the background, so filtering out the contours with a small area would be effective.检测到边缘后,背景中很可能会有很多噪声,因此过滤掉小面积的轮廓会很有效。

Here is how it might go:这是 go 的可能方式:

import cv2

def process(img):
    img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    img_blur = cv2.GaussianBlur(img_gray, (3, 3), 0)
    img_canny = cv2.Canny(img_blur, 161, 54)
    img_dilate = cv2.dilate(img_canny, None, iterations=1)
    return cv2.erode(img_dilate, None, iterations=1)

def get_watermark(img):
    contours, _ = cv2.findContours(process(img), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
    img.fill(255)
    for cnt in contours:
        if cv2.contourArea(cnt) > 100:
            cv2.drawContours(img, [cnt], -1, 0, -1)

img = cv2.imread("watermark.jpg")
get_watermark(img)
cv2.imshow("Watermark", img)
cv2.waitKey(0)

Output: Output:

在此处输入图像描述

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM