python-opencv给图片或视频去水印

文章目录

引言

本文主要基于cv2.inpaint函数实现图片的水印去除。

inpaint函数基于图像修复算法,通过对缺陷区域周围像素的分析和插值,生成合适的像素值来填充缺陷区域。这种算法通常用于去除图像中的污点、划痕或其他不需要的对象。

inpaint函数的使用方法

inpaint函数在OpenCV中的原型如下:

python 复制代码
dst = cv2.inpaint(src, mask, dst, inpaintRadius, flags)

参数说明:

  • src:输入图像,即待修复的原始图像。
  • mask:掩膜图像,用于指定需要修复的区域。在掩膜图像中,需要修复的区域像素值为255(白色),其他区域像素值为0(黑色)。
  • dst:输出图像,即修复后的图像。
  • inpaintRadius:修复算法中使用的邻域半径。该参数决定了算法在修复每个像素时考虑的周围像素范围。半径越大,修复效果可能越平滑,但也可能丢失更多的细节。
  • flags:算法标志,用于指定使用的修复算法。OpenCV提供了两种算法选项:cv2.INPAINT_NS和cv2.INPAINT_TELEA。前者是Navier-Stokes流体动力学算法的简化版本,后者是Telea算法。

鼠标事件回调函数cv2.setMouseCallback介绍

cv2.setMouseCallback(winname , MouseCallback)是一个对 winname 窗口鼠标状态的监视函数,当 winname 窗口上有鼠标动作时,即自动调用 MouseCallback 函数,相当于这个窗口的一个鼠标中断。在此函数前,应该拥有相应的窗口声明函数 cv2.namedWindow(winname)以被 setMouseCallback() 函数做捕获,确认操作窗口。


python 复制代码
# 导入OpenCV包
import cv2 as cv
# 定义全局变量
point = (-1,-1)
# 编写回调函数
def action(event, x, y, flags, param):
    global point
    # 鼠标左键按下
    if event == cv.EVENT_LBUTTONDOWN:
		#左键按下更新全局变量
        point = (x, y)
        print("EVENT_LBUTTONDOWN")
        print(x, ' ', y)
 
# 窗口声明
cv.namedWindow('drawing')
# 鼠标事件绑定
cv.setMouseCallback('drawing', action)
camera = cv.VideoCapture(0)
while True:
    s, img = camera.read()
	# 通过全局变量在制定位置绘制图像
    cv.circle(img,point,4,(0,0,255),-1)
    cv.putText(img,f"{point}",point,cv.FONT_HERSHEY_TRIPLEX,1,(0,0,255),1)
    cv.imshow('drawing', img)
    # 按 q 键退出
    if cv.waitKey(1) & 0xFF == ord('q'):
        break
camera.release()
cv.destroyAllWindows()

去水印步骤

  1. 打开图像或视频
  2. 通过鼠标涂抹水印区域mask
  3. 预处理mask,转换为单通道并膨胀
  4. 调用cv2.inpaint函数对水印去进行修复

注:对于视频的去水印,通过读取第一帧图像获取mask后,其余图像帧都可以使用该mask进行操作

实现代码

python 复制代码
import cv2
import numpy as np


mode = False
drawing = False


# 鼠标回调函数
def draw_action(event, x, y, flags, param):
    global ix, iy, drawing, mode, img
    psize = 10
    print(psize)
    if event == cv2.EVENT_LBUTTONDOWN:
        drawing = True
        ix, iy = x, y

    elif event == cv2.EVENT_MOUSEMOVE:
        if drawing == True:
            if mode == True:
                cv2.rectangle(mask, (ix, iy), (x, y), (100, 255, 0), -1)
                cv2.rectangle(img, (ix, iy), (x, y), (100, 255, 0), -1)
            else:
                cv2.circle(mask, (x, y), psize, (100, 255, 0), -1)
                cv2.circle(img, (x, y), psize, (100, 255, 0), -1)
                cv2.imshow("frame", img)
    elif event == cv2.EVENT_LBUTTONUP:
        drawing = False
        if mode == True:
            cv2.rectangle(mask, (ix, iy), (x, y), (100, 255, 0), -1)
            cv2.rectangle(img, (ix, iy), (x, y), (100, 255, 0), -1)
        else:
            cv2.circle(mask, (x, y), psize, (100, 255, 0), -1)
            cv2.circle(img, (x, y), psize, (100, 255, 0), -1)


def watermask_remove(img):
    global mask
    # 开始操作
    # 设定要查找的颜色范围
    lower_green = np.array([50, 50, 50])
    upper_green = np.array([255, 255, 255])

    hsv = cv2.cvtColor(mask, cv2.COLOR_BGR2HSV)
    thresh = cv2.inRange(hsv, lower_green, upper_green)

    scan = np.ones((5, 5), np.uint8)
    cor = cv2.dilate(thresh, scan, iterations=1)

    dst = cv2.inpaint(img, cor, 3, cv2.INPAINT_TELEA)
    return dst


if __name__ == '__main__':
    pmode = "video"  # video image
    path = "demo.png"
    vieodpath = "1.mp4"
    cap = cv2.VideoCapture(vieodpath)

    if pmode == "video":
        ret, img = cap.read()
    else:
        img = cv2.imread(path)

    img_copy = np.copy(img)
    mask = np.copy(img)
    mask[:, :] = 0
	
	# 通过绘制获取mask
    cv2.imshow("frame", img)
    cv2.namedWindow('frame')
    cv2.setMouseCallback("frame", draw_action)
    cv2.waitKey(0)
    # 根据mask去水印
    no_watermask_frame= watermask_remove(img_copy)
    cv2.imshow('src', img_copy)
    cv2.imshow('dst', no_watermask_frame)
    cv2.waitKey(0)
    cv2.destroyAllWindows()

    # # 创建视频编写器
    # fourcc = cv2.VideoWriter_fourcc(*'mp4v')
    # # out = cv2.VideoWriter('output' + datetime.now().strftime("%H-%M-%S") + '.mp4', fourcc, 20.0, (width, height))
    #
    # if pmode == "video":
    #     if cap.isOpened():
    #         cap.release()
    #     cap = cv2.VideoCapture(vieodpath)
    #     while (cap.isOpened()):
    #         ret, frame = cap.read()
    #         if ret:
    #             # 写入输出视频
    #             no_watermask_frame= watermask_remove(frame)
    #             # out.write(no_watermask_frame)
    #
    #             # 显示帧
    #             cv2.imshow('frame', no_watermask_frame)
    #             # 
    #
    #         if cv2.waitKey(27) & 0xFF == ord('s'):
    #             # 释放资源
    #
    #             break
    #
    #     cap.release()
    #     # out.release()
    #     cv2.destroyAllWindows()
    # else:
    #     nowaterprint_frame = waterprint(img)
    #     cv2.imshow('frame', nowaterprint_frame)
    #     cv2.waitKey(0)
    #     cv2.destroyAllWindows()

效果如下:

使用cv2.inpaint函数进行图像修复,效果还是不佳,后续有空尝试训练去水印的AI模型。

相关推荐
python1566 分钟前
Python Pandas内存管理技巧助力高效处理大数据
大数据·python·pandas
Python大数据分析@9 分钟前
学习python中的pandas有没有好的教程推荐?
python·学习·pandas
哪 吒11 分钟前
华为OD机试 - 无重复字符的元素长度乘积的最大值(Python/JS/C/C++ 2024 C卷 100分)
javascript·python·华为od
科研小达人38 分钟前
Langchain调用模型使用FAISS
python·chatgpt·langchain·faiss
Biomamba生信基地43 分钟前
jupyter如何切换内核
ide·python·jupyter
T0uken43 分钟前
【ESP32+MicroPython】网络编程基础
网络·python·esp32
豆本-豆豆奶1 小时前
给初学者的 Jupyter Notebook 教程
开发语言·python·jupyter·安装教程·notebook
勤奋的大熊猫1 小时前
Jupyter lab 打开时默认使用 Notebook 而不是浏览器
ide·python·jupyter
AI视觉网奇2 小时前
pytorch3d报错:RuntimeError: Not compiled with GPU support.
人工智能·pytorch·python
虞书欣的62 小时前
Python小游戏22——吃豆豆小游戏
python·算法·游戏·编辑器·pygame