opencv-python实战项目十二:去除鼠标选择区域的水印

一,简介

在日常生活中,我们常常会遇到带有水印的图片,这些水印虽然保护了版权,但有时也会影响图像的美观和使用。本次博客将向您介绍如何运用OpenCV这一强大的计算机视觉库,轻松实现图像去水印,让您的照片恢复纯净之美。在这篇文章中,我们将深入探讨OpenCV在图像处理领域的应用,特别是如何通过简单的代码操作,定位并去除图像中的水印。

二,算法实现:

2.1 鼠标事件定位水印区域

在本次项目中,我们使用OpenCV库来读取用户的鼠标状态,以便选择需要去除水印的区域。首先,通过初始化全局变量来监控鼠标事件和矩形绘制状态。当用户按下鼠标左键时,算法会开始绘制矩形,并记录下起始点坐标(ix, iy)。在鼠标移动过程中,如果绘制状态为真,则会在原始图像的副本上动态绘制一个绿色矩形框,其边界由起始点和当前鼠标位置共同确定。用户释放鼠标左键后,绘制状态会被关闭,并记录矩形的终点坐标(fx, fy)。同时,在掩码图像上绘制一个与之坐标相同的白色填充矩形。这个掩码图像将在后续的水印去除操作中使用。
代码:

def draw_rectangle(event, x, y, flags, param):
    global ix, iy, fx, fy, drawing, mask
    if event == cv2.EVENT_LBUTTONDOWN:
        drawing = True
        ix, iy = x, y
    elif event == cv2.EVENT_MOUSEMOVE:
        if drawing:
            img_draw = img.copy()
            cv2.rectangle(img_draw, (ix, iy), (x, y), (0, 255, 0), 2)
            cv2.imshow('image', img_draw)
    elif event == cv2.EVENT_LBUTTONUP:
        drawing = False
        fx, fy = x, y
        cv2.rectangle(mask, (ix, iy), (fx, fy), (255,255,255), -1)

2.2 水印区域修复:

本次水印区域修复运用的是opencv自带函数cv2.inpaint()
cv2.inpaint()是OpenCV库中的一个函数,用于修复图像中的损坏区域。它通过分析图像中未损坏的像素,来推断并填充损坏区域的像素值,从而使得修复后的区域与周围图像内容尽可能融合,减少视觉上的不连续性。
函数介绍:

输入:
● src:输入的原始图像,通常是8位单通道或3通道(彩色)图像。
● mask:一个8位单通道图像,与src具有相同的尺寸。掩码图像中的非零像素表示需要修复的损坏区域。
● inpaintRadius:一个正数,表示修复过程中考虑的邻域半径(以像素为单位)。这个半径定义了在修复一个像素时,函数将考虑多少周围的像素。
● flags:修复方法标志,有两个选项:
○ cv2.INPAINT_TELEA:使用基于快速行进方法的算法,由Alexandru Telea提出。
○ cv2.INPAINT_NS:使用基于Navier-Stokes方程和流体动力学的方法。
返回值:
返回一个图像,它与src具有相同的尺寸和类型,其中损坏的区域已经被修复。
cv2.inpaint()函数常用于去除图像中的小缺陷,如噪点、划痕或小面积的水印等。不过,其修复效果取决于损坏区域的大小和图像的纹理复杂度,有时可能需要调整inpaintRadius和flags参数来获得最佳效果。

代码:

inpainted_img = cv2.inpaint(img, mask, 3, cv2.INPAINT_TELEA)

三,整体代码:

import cv2
import numpy as np

# 初始化全局变量
drawing = False
ix, iy = -1, -1
fx, fy = -1, -1

# 鼠标回调函数
def draw_rectangle(event, x, y, flags, param):
    global ix, iy, fx, fy, drawing, mask

    if event == cv2.EVENT_LBUTTONDOWN:
        drawing = True
        ix, iy = x, y

    elif event == cv2.EVENT_MOUSEMOVE:
        if drawing:
            img_draw = img.copy()
            cv2.rectangle(img_draw, (ix, iy), (x, y), (0, 255, 0), 2)
            cv2.imshow('image', img_draw)

    elif event == cv2.EVENT_LBUTTONUP:
        drawing = False
        fx, fy = x, y
        cv2.rectangle(mask, (ix, iy), (fx, fy), (255,255,255), -1)

# 加载图像
img = cv2.imread(r'F:\traditional_vison\1a0c30580ad44357a4d625845ec32db5.png')
img = cv2.resize(img,(0,0),fx=0.5,fy=0.5)
mask = np.zeros(img.shape[:2], dtype=np.uint8)
cv2.namedWindow('image')
cv2.setMouseCallback('image', draw_rectangle)

while True:
    cv2.imshow('image', img)
    k = cv2.waitKey(1) & 0xFF
    if k == ord('q'):
        break

# 检查是否已经框选了一个区域
if ix >= 0 and iy >= 0 and fx >= 0 and fy >= 0:

    # 使用 inpaint 函数修复图像
    inpainted_img = cv2.inpaint(img, mask, 3, cv2.INPAINT_TELEA)
    cv2.imshow('Inpainted Image', inpainted_img)
    cv2.waitKey(0)
cv2.destroyAllWindows()

四,效果:

去除水印前:
在这里插入图片描述
去除水印后:
在这里插入图片描述

  • 17
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值