Python----OpenCV(图像的绘制——绘制椭圆,绘制文本,添加文字水印,添加图片水印)
一、绘制椭圆
cv2.ellipse(image, center, axes, angle, startAngle, endAngle, color, thickness)
参数 | 说明 |
---|---|
image | 目标图像。 |
center | 椭圆中心点 (x, y)。 |
axes | 椭圆的长轴和短轴长度 (major_axis, minor_axis)。 |
angle | 椭圆的旋转角度(以度为单位)。 |
startAngle | 椭圆弧的起始角度。 |
endAngle | 椭圆弧的终止角度。 |
color | 线条颜色,格式为 (B, G, R)。 |
thickness | 正值 - 椭圆边框粗细,负值 - 填充整个椭圆。 |
import cv2
import numpy as np# 创建一个空白图像
image = np.zeros((400, 400, 3), dtype=np.uint8)
# 使用NumPy创建一个400x400像素的数组,表示一个空白图像。
# (400, 400) 是图像的高度和宽度。
# 3 表示图像有3个颜色通道(蓝色、绿色、红色,即BGR格式)。
# dtype=np.uint8 指定数组中每个元素的类型是8位无符号整数,这意味着每个颜色通道的像素值范围是0到255。
# 初始值为0,所以图像是黑色的。# 绘制一个红色椭圆
cv2.ellipse(image, (256, 256), (100, 50), 50, 0, 360, (0, 0, 255), 2)
# 在图像上绘制一个椭圆。
# image: 要在其上绘制椭圆的图像。
# (256, 256): 椭圆中心的坐标。
# (100, 50): 椭圆的半轴长度。第一个值是长轴或短轴的一半,第二个值是另一个半轴的一半。这里是长轴100,短轴50。
# 50: 椭圆的旋转角度(以度为单位),表示长轴相对于x轴的旋转角度。
# 0: 椭圆弧的起始角度(以度为单位)。
# 360: 椭圆弧的结束角度(以度为单位)。0到360表示绘制整个椭圆。
# (0, 0, 255): 椭圆的颜色,BGR格式。这里是红色(蓝色和绿色通道0,红色通道255)。
# 2: 椭圆边框的线宽,像素单位。cv2.imshow("Polygon", image) # 显示图像,窗口标题为"Polygon"。尽管这里绘制的是椭圆,但窗口名仍沿用了之前的"Polygon"。
cv2.waitKey(0) # 等待用户按下任意按键。0表示无限等待。
cv2.destroyAllWindows() # 关闭所有OpenCV创建的窗口。
二、绘制文本
cv2.putText(image, text, org, fontFace, fontScale, color, thickness, lineType)
参数 | 说明 |
---|---|
image | 目标图像。 |
text | 要绘制的字符串。 |
org | 文本的左下角坐标 (x, y)。 |
fontFace | 字体类型,常用值包括: cv2.FONT_HERSHEY_SIMPLEX:普通字体。 cv2.FONT_HERSHEY_COMPLEX:复杂字体。 |
fontScale | 字体的缩放比例。 |
color | 线条颜色,格式为 (B, G, R)。 |
thickness | 字体的粗细。 |
lineType | 线条类型(如 cv2.LINE_AA 表示抗锯齿线条)。 |
import cv2
import numpy as np# 创建一个空白图像
image = np.zeros((400, 400, 3), dtype=np.uint8)
# 使用NumPy创建一个400x400像素的数组,表示一个空白图像。
# (400, 400) 是图像的高度和宽度。
# 3 表示图像有3个颜色通道(蓝色、绿色、红色,即BGR格式)。
# dtype=np.uint8 指定数组中每个元素的类型是8位无符号整数,这意味着每个颜色通道的像素值范围是0到255。
# 初始值为0,所以图像是黑色的。# 绘制文本
cv2.putText(image, "OpenCV Hello World", (50, 350), cv2.FONT_HERSHEY_SIMPLEX,fontScale=1, color=(255, 255, 255), thickness=2, lineType=cv2.LINE_AA)
# 在图像上绘制文本。
# image: 要在其上绘制文本的图像。
# "OpenCV Hello World": 要绘制的文本字符串。
# (50, 350): 文本的起始坐标(左下角)。
# cv2.FONT_HERSHEY_SIMPLEX: 字体类型。OpenCV提供了多种字体,这是其中一种常见的字体。
# fontScale=1: 字体的大小缩放因子。1表示原始大小。
# color=(255, 255, 255): 文本的颜色,BGR格式。这里是白色。
# thickness=2: 文本的笔画粗细。
# lineType=cv2.LINE_AA: 绘制线的类型。cv2.LINE_AA 表示使用抗锯齿线,使文本边缘更平滑。cv2.imshow("Text", image) # 显示图像,窗口标题为"Text"
cv2.waitKey(0) # 等待用户按下任意按键。0表示无限等待。
cv2.destroyAllWindows() # 关闭所有OpenCV创建的窗口。
三、制作水印
给图像添加水印是一种常见的图像处理操作,通常用于保护版权或标记图片来源。
水印类型
-
文字水印:在图像的指定位置绘制文字,文字可以设置字体、大小、颜色、透明度等属性。
-
图片水印:将一幅小图标(如 LOGO)叠加在图像上,并支持设置透明度和位置。
注意事项
透明度处理
透明水印效果通过 alpha 通道或混合操作实现。
透明度的值通常在
[0, 1]
之间调节,值越小,水印越透明。水印大小
确保水印大小适当,避免过大影响图像整体美观。
应用场景
-
版权保护:给图片添加 LOGO 或文字水印,用于版权保护。
-
商业用途:为商业图片、广告图添加品牌标识。
-
内容分类:标记图片类别、作者或日期信息。
3.1、添加文字水印
cv2.imread(image_path): 读取图像。
cv2.putText(): 在图像上添加文字。
cv2.addWeighted(): 通过加权方式合成带透明度的水印。
cv2.imwrite(): 保存处理后的图像。
参数 | 说明 |
---|---|
image_path | 输入图像路径 |
output_path | 输出图像路径 |
text | 水印文字内容 |
position | 文字水印的坐标(x, y) |
font | 文字字体(OpenCV 内置字体) |
font_scale | 文字大小 |
color | 文字颜色(BGR 格式) |
thickness | 文字线条粗细 |
alpha | 水印透明度(0~1 之间) |
import cv2img1 = cv2.imread('./images/nezha.png') # 读取当前目录下'images'文件夹中的'nezha.png'图片,并将其加载到img1变量中img2 = img1.copy() # 复制img1图像到img2。这一步是为了在img2上添加文本,而不影响原始的img1。
cv2.putText(img2, 'Hello World', (100, 255), cv2.FONT_HERSHEY_COMPLEX, 1, (0, 0, 255), 3)
# 在img2图像上绘制文本。
# 'Hello World': 要显示的文本内容。
# (100, 255): 文本的起始坐标(左下角),X轴100,Y轴255。
# cv2.FONT_HERSHEY_COMPLEX: 字体类型。
# 1: 字体缩放比例。
# (0, 0, 255): 文本颜色,BGR格式,这里是红色。
# 3: 文本的线宽(粗细)。img = cv2.addWeighted(img1, 0.5, img2, 0.5, 0)
# 将两张图片(img1和img2)进行加权混合,实现透明度叠加效果。
# img1: 第一张图片。
# 0.5: img1的权重(透明度),表示img1在混合结果中占据50%的比例。
# img2: 第二张图片。
# 0.5: img2的权重(透明度),表示img2在混合结果中占据50%的比例。
# 0: 伽马值,一个添加到最终结果的常数,通常设为0。
# 混合公式为:output = img1 * alpha + img2 * beta + gammacv2.imshow('img', img) # 显示混合后的图片,窗口标题为'img'
cv2.waitKey(0) # 等待用户按下任意按键。0表示无限等待。
cv2.destroyAllWindows() # 关闭所有OpenCV创建的窗口。
3.2、添加图片水印
将水印图像叠加到目标图像的指定区域,并通过混合操作实现透明效果。
import cv2# 读取目标图像和水印图像
image = cv2.imread('./images/nezha.png') # 读取名为 'nezha.png' 的目标图像。请确保该图片存在于 'images' 文件夹中。
watermark = cv2.imread("./images/hongloumeng.png", cv2.IMREAD_UNCHANGED)
# cv2.IMREAD_UNCHANGED 参数确保即使水印有透明度(alpha通道)也会被完整读取。# 确保水印图像包含 alpha 通道
if watermark.shape[2] != 4: # 检查水印图像的通道数是否为4(RGBA:红、绿、蓝、透明度)print("Watermark must have 4 channels (RGBA)") # 如果不是4通道,打印错误信息exit() # 退出程序# 调整水印大小
watermark = cv2.resize(watermark, (100, 100)) # 将水印图像的大小调整为100x100像素,以便它适合目标图像的一部分。# 提取水印的 alpha 通道和RGB通道
wm_alpha = watermark[:, :, 3] / 255.0 # 提取水印的第四个通道(alpha通道),并将其像素值从0-255归一化到0.0-1.0,用于表示透明度。
wm_rgb = watermark[:, :, :3] # 提取水印的前三个通道(RGB颜色通道)。# 指定水印位置(右下角)
h, w, _ = image.shape # 获取目标图像的高度(h)、宽度(w)和通道数(这里_表示不关心通道数)。
y1, y2 = h - watermark.shape[0], h # 计算水印在目标图像上Y轴的起始和结束坐标。使其位于底部。
x1, x2 = w - watermark.shape[1], w # 计算水印在目标图像上X轴的起始和结束坐标。使其位于右侧。
# 这样,水印就会被放置在目标图像的右下角。# 提取 ROI 区域 (Region of Interest - 感兴趣区域)
roi = image[y1:y2, x1:x2] # 从目标图像中截取与水印大小和位置相对应的区域,这个区域就是我们要放置水印的地方。# 融合水印和 ROI
for c in range(3): # 遍历图像的每个颜色通道(R, G, B)# 融合公式:新的像素值 = 原始ROI像素值 * (1 - 透明度) + 水印RGB像素值 * 透明度# 这是一种常用的alpha混合公式,它根据水印的alpha值来决定原始图像和水印图像的混合程度。roi[:, :, c] = roi[:, :, c] * (1 - wm_alpha) + wm_rgb[:, :, c] * wm_alpha# 替换图像中的 ROI
image[y1:y2, x1:x2] = roi # 将融合了水印的ROI区域重新放回原始图像的相应位置。# 显示结果
cv2.imshow("image", image) # 显示添加水印后的图像,窗口标题为"Watermark"。
cv2.waitKey(0) # 等待用户按下任意键。0表示无限等待。
cv2.destroyAllWindows() # 关闭所有OpenCV创建的窗口。