Python 基于 OpenCV 视觉图像处理实战 之 OpenCV 简单实战案例 之十三 简单去除图片水印效果
目录
[Python 基于 OpenCV 视觉图像处理实战 之 OpenCV 简单实战案例 之十三 简单去除图片水印效果](#Python 基于 OpenCV 视觉图像处理实战 之 OpenCV 简单实战案例 之十三 简单去除图片水印效果)
一、简单介绍
Python是一种跨平台的计算机程序设计语言。是一种面向对象的动态类型语言,最初被设计用于编写自动化脚本(shell),随着版本的不断更新和语言新功能的添加,越多被用于独立的、大型项目的开发。Python是一种解释型脚本语言,可以应用于以下领域: Web 和 Internet开发、科学计算和统计、人工智能、教育、桌面界面开发、软件开发、后端开发、网络爬虫。
这里使用 Python 基于 OpenCV 进行视觉图像处理,......
二、简单去除图片水印效果实现原理
去除图片水印是指从一张带有水印的图像中,通过算法或图像处理技术,将水印部分去除,以得到不带水印的图像。通常情况下,水印是以文字、图标或者图案的形式嵌入到图像中的,去除水印的目的是为了提高图像的美观度和可用性,以便更好地应用于各种场景,如展示、打印或者分析等。
当选择图片水印去除时,上述案例实现分为以下步骤:
选择水印的ROI(感兴趣区域):
- 用户使用鼠标在图片上框选出水印区域。
- 通过调用 OpenCV 的
cv2.selectROI()
函数实现框选操作,并在框选完成后返回框选区域的坐标和尺寸。- 如果未成功选择ROI(即框选的宽度或高度为0),则输出相应提示信息,终止水印去除操作。
自适应检测水印并生成遮罩:
- 在选择的ROI区域内,将图像转换为灰度图像,并利用 Otsu 自适应阈值处理方法进行二值化,以获取水印的二值图像。
- 根据二值化图像生成水印的遮罩,将水印区域设为白色(255),其他区域设为黑色(0)。
生成水印的遮罩:
- 对检测到的水印遮罩进行膨胀操作,以确保水印区域完全覆盖。
- 使用 OpenCV 的
cv2.dilate()
函数对水印遮罩进行膨胀操作,以扩展水印区域。应用遮罩去除水印:
- 利用水印遮罩对原始图像进行修复,将水印区域的像素值恢复为相邻像素的估计值。
- 使用 OpenCV 的
cv2.inpaint()
函数对图像进行修复,将水印区域填充为相邻像素的估计值。保存处理后的图片:
- 将去除水印后的图像保存到指定的输出路径。
案例中的关键函数说明:
select_roi_for_mask(image)
:
- 功能:从图像中选择水印的感兴趣区域(ROI)。
- 参数:
image
:输入的图像数据,应为 BGR 格式的图像。- 返回值:
- 如果成功选择了ROI,则返回水印的ROI坐标和尺寸 (x, y, w, h),其中 (x, y) 是左上角的坐标,w 是宽度,h 是高度。
- 如果未选择ROI,则返回 None。
- 注意事项:
- 输入图像应为 BGR 格式的图像数据。
- 用户需要在弹出的窗口中手动选择水印的ROI,按下空格键或回车键确认选择。
detect_watermark_adaptive(image, roi)
:
- 功能:自适应检测图像中的水印并生成对应的遮罩。
- 参数:
image
:输入的图像数据,应为 BGR 格式的图像。roi
:水印的ROI坐标和尺寸 (x, y, w, h)。- 返回值:
- 如果成功检测到水印,则返回水印的遮罩图像数据,与原始图像尺寸相同。
- 如果ROI未选择或出现其他错误,则返回 None。
- 注意事项:
- 输入图像应为 BGR 格式的图像数据。
- ROI参数应为有效的坐标和尺寸,即 (x, y, w, h) 均不应小于等于零。
generate_watermark_mask(image, roi)
:
- 功能:生成水印的遮罩。
- 参数:
image
:输入的图像数据,应为 BGR 格式的图像。roi
:水印的ROI坐标和尺寸 (x, y, w, h)。- 返回值:
- 如果成功生成水印的遮罩,则返回水印的遮罩图像数据,与原始图像尺寸相同。
- 如果ROI未选择或出现其他错误,则返回 None。
- 注意事项:
- 输入图像应为 BGR 格式的图像数据。
- ROI参数应为有效的坐标和尺寸,即 (x, y, w, h) 均不应小于等于零。
remove_watermark(image_path, output_path)
:
- 功能:去除输入图像中的水印。
- 参数:
image_path
:输入图像的文件路径。output_path
:输出图像的文件路径。- 返回值:
- 如果成功去除水印,则返回处理后的图像数据。
- 如果未成功去除水印,则返回 None。
- 注意事项:
- 输入图像应为存在的图像文件路径。
- 输出图像的文件路径应为有效的保存路径,且文件夹需提前存在。
三、简单去除图片水印效果案例实现简单步骤
1、编写代码
2、运行效果
1)选择图片水印位置;2、Space 或者 Enter 确认选择区域,后台会自动去除水印,并保存图片
3、具体函数
python
"""
简单去除图片水印效果
1、选择水印的ROI(感兴趣区域)
2、自适应检测水印并生成遮罩
3、生成水印的遮罩
4、应用遮罩去除水印
5、保存处理后的图片
"""
import cv2
import numpy as np
def select_roi_for_mask(image):
"""
从图像中选择水印的ROI
:param image: 图像数据
:return: 水印ROI的坐标和尺寸 (x, y, w, h),如果未选择ROI则返回 None
"""
if image is None or len(image.shape) != 3:
raise ValueError("Input image is invalid or not in BGR format.")
instructions = "Select ROI and press SPACE or ENTER"
font = cv2.FONT_HERSHEY_SIMPLEX
cv2.putText(image, instructions, (10, 30), font, 1, (255, 255, 255), 2, cv2.LINE_AA)
r = cv2.selectROI("Select ROI", image)
cv2.destroyAllWindows()
if r[2] == 0 or r[3] == 0:
print("ROI not selected. Watermark removal aborted.")
return None
return r
def detect_watermark_adaptive(image, roi):
"""
自适应检测水印并生成遮罩。
:param image: 图像数据
:param roi: 水印的ROI坐标和尺寸 (x, y, w, h)。
:return: 水印的遮罩图像数据,如果ROI未选择则返回 None
"""
if roi is None:
print("ROI not selected. Watermark removal aborted.")
return None
roi_image = image[roi[1]:roi[1] + roi[3], roi[0]:roi[0] + roi[2]]
gray_image = cv2.cvtColor(roi_image, cv2.COLOR_BGR2GRAY)
_, binary_image = cv2.threshold(gray_image, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
mask = np.zeros_like(image[:, :, 0], dtype=np.uint8)
mask[roi[1]:roi[1] + roi[3], roi[0]:roi[0] + roi[2]] = binary_image
return mask
def generate_watermark_mask(image, roi):
"""
生成水印的遮罩
:param image: 图像数据
:param roi: 水印的ROI坐标和尺寸 (x, y, w, h)
:return: 水印的遮罩图像数据,如果ROI未选择则返回 None
"""
if roi is None:
print("ROI not selected. Watermark removal aborted.")
return None
mask = detect_watermark_adaptive(image, roi)
kernel = np.ones((5, 5), np.uint8)
return cv2.dilate(mask, kernel)
def remove_watermark(image_path, output_path):
"""
去除图片中的水印
:param image_path: 输入图像路径
:param output_path: 输出图像路径
:return: 处理后的图片
"""
# 读取图像
image = cv2.imread(image_path)
# 拷贝一份用来框选位置
image_toSelect = image.copy()
# 选择水印的ROI
roi = select_roi_for_mask(image_toSelect)
# 生成水印遮罩
watermark_mask = generate_watermark_mask(image, roi)
# 如果没有选择ROI,则不进行处理
if roi is None or watermark_mask is None:
return
# 应用遮罩去除水印
result_image = cv2.inpaint(image, watermark_mask, 3, cv2.INPAINT_NS)
# 保存结果
cv2.imwrite(output_path, result_image)
print("Successfully removed watermark and saved result.")
return result_image
if __name__ == "__main__":
input_image_path = "Images/DogFace_Watermark.jpg"
output_image_path = "Images/DogFace_Watermark_ToRemove.jpg"
remove_watermark(input_image_path, output_image_path)
四、注意事项
-
选择合适的ROI:
- 用户应尽量选择完整覆盖水印的区域,以确保水印去除效果。
- 选择的ROI区域应该尽量准确、完整,以保证水印检测和去除的准确性。
-
水印去除效果:
- 选择合适的水印检测方法和参数,以确保水印区域的准确检测和去除。
- 对于复杂的水印或者背景,可能需要尝试不同的参数和方法来获取更好的去除效果。
-
处理过程中的异常情况:
- 对于未成功选择ROI的情况,应输出相应的提示信息并终止水印去除操作。
- 在处理过程中,应对可能出现的异常情况进行捕获和处理,确保程序的稳定性和可靠性。