youcans 的 OpenCV 学习课—4.图像的叠加与混合

本系列面向 Python 小白,从零开始实战解说 OpenCV 项目实战。

本节介绍图像的加法、叠加与混合,提供完整例程和运行结果:加法运算,加权加法,图像混合、切换、遮罩、叠加,添加文字。详细介绍综合运用图像阈值处理、图像掩模、位操作和图像加法的操作是基于掩模和位运算实现图像叠加的方法。

欢迎关注 『youcans 的 OpenCV 学习课』 系列,持续更新
youcans 的 OpenCV 学习课—1.安装与环境配置
youcans 的 OpenCV 学习课—2.图像读取与显示
youcans 的 OpenCV 学习课—3.图像的创建与修改
youcans 的 OpenCV 学习课—4.图像的叠加与混合
youcans 的 OpenCV 学习课—5.图像的几何变换
youcans 的 OpenCV 学习课—6.灰度变换与直方图处理
youcans 的 OpenCV 学习课—7.空间域图像滤波
youcans 的 OpenCV 学习课—8.频率域图像滤波(上)
youcans 的 OpenCV 学习课—9.频率域图像滤波(下)

1. 图像的加法运算

函数 cv2.add() 用于图像的加法运算。

函数说明:

cv2.add(src1, src2 [, dst[, mask[, dtype]]) → dst

函数 cv2.add() 对两张相同大小和类型的图像进行加法运算,或对一张图像与一个标量进行加法运算。

两张图像相加时,将两张图像相同位置像素的各通道值或灰度值分别相加,可以理解为一种图像叠加方式;对一张图像与一个标量相加时,则将图像所有像素的各通道值分别与标量的各通道值相加。

参数说明:

  • scr1, scr2:进行加法运算的图像,或一张图像与一个 numpy array 标量
  • dst:输出的图像,可选项,默认值为 None
  • mask:掩模图像,8位灰度格式;掩模图像数值为 0 的像素,输出图像对应像素的各通道值也为 0。可选项,默认值为 None
  • dtype:图像数组的深度,即每个像素值的位数,可选项
  • 返回值:dst,运算结果图像,ndarray 多维数组

注意事项:

  1. OpenCV 加法和 numpy 加法之间有区别:cv2.add() 是饱和运算(相加后如大于 255 则结果为 255),而 Numpy 加法是模运算。
  2. 使用 cv2.add() 函数对两张图片相加时,图片的大小和类型(通道数)必须相同。
  3. 使用 cv2.add() 函数对一张图像与一个标量相加,标量是指一个 1x3 的 numpy 数组,相加后图像整体发白。

基本例程:1.22 图像的加法

    # 1.22 图像的加法 (cv2.add)img1 = cv2.imread("../images/imgB1.jpg")  # 读取彩色图像(BGR)img2 = cv2.imread("../images/imgB3.jpg")  # 读取彩色图像(BGR)imgAddCV = cv2.add(img1, img2)  # OpenCV 加法: 饱和运算imgAddNP = img1 + img2  # # Numpy 加法: 模运算plt.subplot(221), plt.title("1. img1"), plt.axis('off')plt.imshow(cv2.cvtColor(img1, cv2.COLOR_BGR2RGB))  # 显示 img1(RGB)plt.subplot(222), plt.title("2. img2"), plt.axis('off')plt.imshow(cv2.cvtColor(img2, cv2.COLOR_BGR2RGB))  # 显示 img2(RGB)plt.subplot(223), plt.title("3. cv2.add(img1, img2)"), plt.axis('off')plt.imshow(cv2.cvtColor(imgAddCV, cv2.COLOR_BGR2RGB))  # 显示 imgAddCV(RGB)plt.subplot(224), plt.title("4. img1 + img2"), plt.axis('off')plt.imshow(cv2.cvtColor(imgAddNP, cv2.COLOR_BGR2RGB))  # 显示 imgAddNP(RGB)plt.show()

例程说明 1.22:

本例程运行结果如下图所示。图 3 是 cv2.add() 饱和加法的结果,图 4 是 numpy 取模加法的结果。

  • 饱和加法以 255 为上限,所有像素只会变的更白(大于原值);取模加法以 255 为模,会导致部分像素变黑 (小于原值)。
  • 因此,一般情况下应使用 cv2.add 进行饱和加法操作,不宜使用 numpy 取模加法。

基本例程:1.23 图像与标量相加

# 1.23 图像的加法 (与标量相加)img1 = cv2.imread("../images/imgB1.jpg")  # 读取彩色图像(BGR)img2 = cv2.imread("../images/imgB3.jpg")  # 读取彩色图像(BGR)Value = 100  # 常数# Scalar = np.array([[50., 100., 150.]])  # 标量Scalar = np.ones((1, 3), dtype="float") * Value  # 标量imgAddV = cv2.add(img1, Value)  # OpenCV 加法: 图像 + 常数imgAddS = cv2.add(img1, Scalar)  # OpenCV 加法: 图像 + 标量print("Shape of scalar", Scalar)for i in range(1, 6):x, y = i*10, i*10print("(x,y)={},{}, img1:{}, imgAddV:{}, imgAddS:{}".format(x,y,img1[x,y],imgAddV[x,y],imgAddS[x,y]))plt.subplot(131), plt.title("1. img1"), plt.axis('off')plt.imshow(cv2.cvtColor(img1, cv2.COLOR_BGR2RGB))  # 显示 img1(RGB)plt.subplot(132), plt.title("2. img + constant"), plt.axis('off')plt.imshow(cv2.cvtColor(imgAddV, cv2.COLOR_BGR2RGB))  # 显示 imgAddV(RGB)plt.subplot(133), plt.title("3. img + scalar"), plt.axis('off')plt.imshow(cv2.cvtColor(imgAddS, cv2.COLOR_BGR2RGB))  # 显示 imgAddS(RGB)plt.show()

例程说明 1.23:

本例程运行结果如下。

Shape of scalar [[150. 150. 150.]]
(x,y)=10,10, img1:[ 9  9 69], imgAddV:[159   9  69], imgAddS:[159 159 219]
(x,y)=20,20, img1:[  3 252 255], imgAddV:[153 252 255], imgAddS:[153 255 255]
(x,y)=30,30, img1:[  1 255 254], imgAddV:[151 255 254], imgAddS:[151 255 255]
(x,y)=40,40, img1:[  1 255 254], imgAddV:[151 255 254], imgAddS:[151 255 255]
(x,y)=50,50, img1:[  1 255 255], imgAddV:[151 255 255], imgAddS:[151 255 255]
  • 注意 cv2.add() 对图像与标量相加时,“常数” 与 “标量” 的区别:
  • 将图像与一个常数 value 相加,只是将 B 通道即蓝色分量与常数相加,而 G、R 通道的数值不变,因此图像发蓝。
  • 将图像与一个标量 scalar 相加,“标量” 是指一个 1x3 的 numpy 数组,此时 B/G/R 通道分别与数组中对应的常数相加,因此图像发白。
  • 标量 numpy 数组的形式为:np.array([[c1, c2, c3]]),常数 c1,c2,c3 可以相同或不同。


2. 图像的加权加法

函数 cv2.addWeight() 用于图像的加权加法运算。

函数说明:

cv2.addWeighted(src1, alpha, src2, beta, gamma[, dst[, dtype]]) → dst

函数 cv2.addWeighted() 对两张相同大小和类型的图像按权重相加,可以实现图像的叠加和混合。加权加法的计算表达式为:

dst = src1 * alpha + src2 * beta + gamma

参数说明:

  • scr1, scr2:ndarray 多维数组,表示一个灰度或彩色图像
  • alpha:第一张图像 scr1 的权重,通常取为 0~1 之间的浮点数
  • beta:第二张图像 scr2 的权重,通常取为 0~1 之间的浮点数
  • gamma: 灰度系数,图像校正的偏移量,用于调节亮度
  • dtype 输出图像的深度,即每个像素值的位数,可选项,默认等于 src1.depth()
  • 返回值:dst,加权加法运算结果的图像数组

注意事项:

  1. 使用 cv2.addWeight() 函数对两张图片相加时,图片的大小和类型(通道数)必须相同。
  2. alpha,beta,gamma 可调,可以根据需要调整图像的权重,以达到不同的显示效果。推荐取 beta=1-alpha, gamma=0。

基本例程:1.24 图像的混合(加权加法)

    # 1.24 图像的混合(加权加法)img1 = cv2.imread("../images/imgGaia.tif")  # 读取图像 imgGaiaimg2 = cv2.imread("../images/imgLena.tif")  # 读取图像 imgLenaimgAddW1 = cv2.addWeighted(img1, 0.2, img2, 0.8, 0)  # 加权相加, a=0.2, b=0.8imgAddW2 = cv2.addWeighted(img1, 0.5, img2, 0.5, 0)  # 加权相加, a=0.5, b=0.5imgAddW3 = cv2.addWeighted(img1, 0.8, img2, 0.2, 0)  # 加权相加, a=0.8, b=0.2plt.subplot(131), plt.title("1. a=0.2, b=0.8"), plt.axis('off')plt.imshow(cv2.cvtColor(imgAddW1, cv2.COLOR_BGR2RGB))  # 显示 img1(RGB)plt.subplot(132), plt.title("2. a=0.5, b=0.5"), plt.axis('off')plt.imshow(cv2.cvtColor(imgAddW2, cv2.COLOR_BGR2RGB))  # 显示 imgAddV(RGB)plt.subplot(133), plt.title("3. a=0.8, b=0.2"), plt.axis('off')plt.imshow(cv2.cvtColor(imgAddW3, cv2.COLOR_BGR2RGB))  # 显示 imgAddS(RGB)plt.show()

本例程运行结果如下:

扩展例程:1.25 不同尺寸的图像加法

    # 1.25 不同尺寸的图像加法imgL = cv2.imread("../images/imgB2.jpg")  # 读取大图imgS = cv2.imread("../images/logoCV.png")  # 读取小图 (LOGO)x,y = 300,50  # 叠放位置W1, H1 = imgL.shape[1::-1]  # 大图尺寸W2, H2 = imgS.shape[1::-1]  # 小图尺寸if (x + W2) > W1: x = W1 - W2  # 调整图像叠放位置,避免溢出if (y + H2) > H1: y = H1 - H2imgCrop = imgL[y:y + H2, x:x + W2]  # 裁剪大图,与小图 imgS 的大小相同imgAdd = cv2.add(imgCrop, imgS)  # cv2 加法,裁剪图与小图叠加alpha, beta, gamma = 0.2, 0.8, 0.0  # 加法权值imgAddW = cv2.addWeighted(imgCrop, alpha, imgS, beta, gamma)  # 加权加法,裁剪图与小图叠加imgAddM = np.array(imgL)imgAddM[y:y + H2, x:x + W2] = imgAddW  # 用叠加小图替换原图 imgL 的叠放位置cv2.imshow("imgAdd", imgAdd)cv2.imshow("imgAddW", imgAddW)cv2.imshow("imgAddM", imgAddM)cv2.waitKey(0)

需要说明的是,对不同尺寸的图像叠加可以有不同的理解和处理。本例程是将小图叠加到大图的指定位置。
本例程运行结果如下图所示。

扩展例程:1.26 两张图像的渐变切换 (改变加权叠加的权值)

    # 1.26 两张图像的的渐变切换 (改变加权叠加的权值)img1 = cv2.imread("../images/imgLena.tif")  # 读取图像 imgLenaimg2 = cv2.imread("../images/imgB3.jpg")  # 读取彩色图像(BGR)wList = np.arange(0.0, 1.0, 0.05)  # start, end, stepfor w in wList:imgAddW = cv2.addWeighted(img1, w, img2, (1 - w), 0)cv2.imshow("imgAddWeight", imgAddW)cv2.waitKey(100)

3. 图像的掩模加法

图像掩模(image mask),也常被写成 “图像掩膜”,是用特定的图像或函数对另一图像进行覆盖或遮蔽,以控制图像处理的区域或图像处理的过程。图像掩模常用于提取感兴趣区域(ROI)、提取结构特征,或制作特殊形状的图像。

用于遮蔽的图像或函数,称为掩模、掩像、模板或遮罩(mask)。对图像进行处理时,被遮蔽的区域不参加处理,或不参加处理参数的计算;或者相反地,仅对被遮蔽的区域进行处理或统计。

函数 cv2.add() 用于图像的加法运算,可以使用掩模图像进行遮蔽。

cv2.add(src1, src2 [, dst[, mask[, dtype]]) → dst

掩模图像中的黑色区域(数值为 0),cv2.add 的输出也为黑色(数值为 0);掩模图像中的非黑色区域(非 0 值),cv2.add 的输出为加法输出。换句话说,函数 cv2.add 进行加法运算,对被掩模图像遮蔽的黑色区域不进行处理,保持黑色。

注意事项:

  1. 掩模图像 mask 为 8位灰度格式,遮蔽区域为黑色(数值为 0),非遮蔽区域为白色(数值为 255),也称为开窗区域、窗口。
  2. 掩模图像与进行加法运算的图像 src1, src2 的形状必须相同。

基本例程:1.27 图像的掩模加法

    # 1.27 图像的加法 (掩模 mask)img1 = cv2.imread("../images/imgLena.tif")  # 读取彩色图像(BGR)img2 = cv2.imread("../images/imgB3.jpg")  # 读取彩色图像(BGR)Mask = np.zeros((img1.shape[0], img1.shape[1]), dtype=np.uint8)  # 返回与图像 img1 尺寸相同的全零数组xmin, ymin, w, h = 180, 190, 200, 200  # 矩形裁剪区域 (ymin:ymin+h, xmin:xmin+w) 的位置参数Mask[ymin:ymin+h, xmin:xmin+w] = 255  # 掩模图像,ROI 为白色,其它区域为黑色print(img1.shape, img2.shape, Mask.shape)imgAddMask1 = cv2.add(img1, img2, mask=Mask)  # 带有掩模 mask 的加法imgAddMask2 = cv2.add(img1, np.zeros(np.shape(img1), dtype=np.uint8), mask=Mask)  # 提取 ROIcv2.imshow("MaskImage", Mask)  # 显示掩模图像 Maskcv2.imshow("MaskAdd", imgAddMask1)  # 显示掩模加法结果 imgAddMask1cv2.imshow("MaskROI", imgAddMask2)  # 显示从 img1 提取的 ROIkey = cv2.waitKey(0)  # 等待按键命令

例程说明 1.27:

本例程运行结果如下。

imgAddMask1 是标准的掩模加法,在窗口区域将 img1 与 img2 进行饱和加法,其它区域为黑色遮蔽。imgAddMask2 中加法运算的第二图像是全黑图像(数值为 0),掩模加法的结果是从第一图像中提取遮蔽窗口,该操作生成的图像是从原图中提取感兴趣区域(ROI)、黑色遮蔽其它区域。

扩展例程:1.28 圆形和其它形状的图像遮罩

    # 1.28 图像的加法 (圆形和其它形状的遮罩)img1 = cv2.imread("../images/imgLena.tif")  # 读取彩色图像(BGR)img2 = cv2.imread("../images/imgB3.jpg")  # 读取彩色图像(BGR)Mask1 = np.zeros((img1.shape[0], img1.shape[1]), dtype=np.uint8)  # 返回与图像 img1 尺寸相同的全零数组Mask2 = Mask1.copy()cv2.circle(Mask1, (285, 285), 110, (255, 255, 255), -1)  # -1 表示实心cv2.ellipse(Mask2, (285, 285), (100, 150), 0, 0, 360, 255, -1)  # -1 表示实心imgAddMask1 = cv2.add(img1, np.zeros(np.shape(img1), dtype=np.uint8), mask=Mask1)  # 提取圆形 ROIimgAddMask2 = cv2.add(img1, np.zeros(np.shape(img1), dtype=np.uint8), mask=Mask2)  # 提取椭圆 ROIcv2.imshow("circularMask", Mask1)  # 显示掩模图像 Maskcv2.imshow("circularROI", imgAddMask1)  # 显示掩模加法结果 imgAddMask1cv2.imshow("ellipseROI", imgAddMask2)  # 显示掩模加法结果 imgAddMask2key = cv2.waitKey(0)  # 等待按键命令

本例程运行结果如下。

通过设计圆形、椭圆形或其它形状的图像遮罩,可以从一张图像中提取不同形状的区域。


4. 图像的按位运算

函数 cv2.bitwise 提供了图像的位运算,对图像的像素点值按位操作,快速高效、方便灵活。

函数说明:

cv.bitwise_and(src1, src2[, dst[, mask]] → dst  # 位操作: 与
cv.bitwise_or(src1, src2[, dst[, mask]] → dst  # 位操作: 或
cv.bitwise_xor(src1, src2[, dst[, mask]] → dst  # 位操作: 与或
cv.bitwise_not(src1, src2[, dst[, mask]] → dst  # 位操作: 非(取反)
  • 位运算包括四种方法:按位与、按位或、按位非、按位异或,其计算方法是对图像的像素点值的按位运算,运算效率高、速度快。

  • 以按位与操作 “bitwise_and” 为例:

      1. 对图像中的每一像素(矩阵中的每一元素),将数值转换为二进制;
      1. 对 src1 和 src2 同一位置像素的数值进行按位操作 (按位与): 1&1=1, 1&0=0, 0&0=0;
      1. 将位操作的二进制结果转换为十进制。
  • 类似地,按位或、按位非、按位异或操作,先将像素值转换为二进制,进行位操作后再将结果转换回十进制。

参数说明:

  • scr1, scr2:进行位运算的图像,ndarray 多维数组
  • mask:掩模图像,8位灰度格式,与 scr1 大小相同,可选参数
  • 返回值:dst,位运算结果图像,ndarray 多维数组

注意事项:

    1. 进行位运算的图像 scr1, scr2 的大小和类型(通道数)必须相同。
    1. 使用掩模图像时,掩模图像中的黑色区域(数值为 0),输出也为黑色(数值为 0);掩模图像中的非黑色区域(非 0 值),按位操作输出。

基本例程:1.29 图像的位操作

    # 1.29 图像的位操作img1 = cv2.imread("../images/imgLena.tif")  # 读取彩色图像(BGR)img2 = cv2.imread("../images/imgB2.jpg")  # 读取彩色图像(BGR)imgAnd = cv2.bitwise_and(img1, img2)  # 按位 与(AND)imgOr = cv2.bitwise_or(img1, img2)  # 按位 或(OR)imgNot = cv2.bitwise_not(img1)  # 按位 非(NOT)imgXor = cv2.bitwise_xor(img1, img2)  # 按位 异或(XOR)plt.figure(figsize=(9,6))titleList = ["img1", "img2", "and", "or", "not", "xor"]imageList = [img1, img2, imgAnd, imgOr, imgNot, imgXor]for i in range(6):plt.subplot(2,3,i+1), plt.title(titleList[i]), plt.axis('off')plt.imshow(cv2.cvtColor(imageList[i], cv2.COLOR_BGR2RGB), 'gray')plt.show()

例程说明 1.29:

本例程运行结果如下图所示。

图中给出了两张图像进行位运算的结果,看起来有些莫名其妙,很难理解位操作究竟有什么意义。确实如此,其实位操作基本上不会用于两张普通图像的操作,通常是用于图像的掩模操作,我们来看下一个例程。


5. 图像的叠加

两张图像直接进行加法运算后图像的颜色会改变,通过加权加法实现图像混合后图像的透明度会改变,都不能实现图像的叠加。

实现图像的叠加,需要综合运用图像阈值处理、图像掩模、位操作和图像加法的操作。

我们以 Lena 图像叠加 CVlogo 为例,讨论图像叠加的思路和步骤:

  1. 确定图像叠加位置,将 Lena 图像中的叠加位置裁剪出来,使叠加图像的尺寸相同;
  2. 对前景图像进行二值化处理,生成黑白掩模图像 mask(LOGO区域黑色遮盖)及其反转掩模图像 maskInv (LOGO区域白色开窗);
  3. 以黑白掩模 mask(LOGO区域黑色遮盖)作为掩模,对背景图像(Lena裁剪图)进行位操作,LOGO区域遮盖为黑色,其它区域保持不变,得到叠加背景图像 img1BG;
  4. 以反转掩模 maskInv(LOGO区域白色开窗)作为掩模,对前景图像(CVlogo)进行位操作,LOGO区域保持不变,其它区域遮盖为黑色,得到叠加前景图像 img2FG;
  5. 背景图像 img1BG 和 前景图像 img2FG 通过 cv2.add 加法运算,得到裁剪部分的叠加图像;
  6. 用叠加图像替换Lena 图像中的叠加位置,得到Lena 叠加 CVlogo 的图像。

基本例程:1.30 图像的叠加

    # 1.30 图像的叠加img1 = cv2.imread("../images/imgLena.tif")  # 读取彩色图像(BGR)img2 = cv2.imread("../images/logoCV.png")  # 读取 CV Logox, y = (0, 10)  # 图像叠加位置W1, H1 = img1.shape[1::-1]W2, H2 = img2.shape[1::-1]if (x + W2) > W1: x = W1 - W2if (y + H2) > H1: y = H1 - H2print(W1,H1,W2,H2,x,y)imgROI = img1[y:y+W2, x:x+H2]  # 从背景图像裁剪出叠加区域图像img2Gray = cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY)  # img2: 转换为灰度图像ret, mask = cv2.threshold(img2Gray, 175, 255, cv2.THRESH_BINARY)  # 转换为二值图像,生成遮罩,LOGO 区域黑色遮盖maskInv = cv2.bitwise_not(mask)  # 按位非(黑白转置),生成逆遮罩,LOGO 区域白色开窗,LOGO 以外区域黑色# mask 黑色遮盖区域输出为黑色,mask 白色开窗区域与运算(原图像素不变)img1Bg = cv2.bitwise_and(imgROI, imgROI, mask=mask)  # 生成背景,imgROI 的遮罩区域输出黑色img2Fg = cv2.bitwise_and(img2, img2, mask=maskInv)  # 生成前景,LOGO 的逆遮罩区域输出黑色# img1Bg = cv2.bitwise_or(imgROI, imgROI, mask=mask)  # 生成背景,与 cv2.bitwise_and 效果相同# img2Fg = cv2.bitwise_or(img2, img2, mask=maskInv)  # 生成前景,与 cv2.bitwise_and 效果相同# img1Bg = cv2.add(imgROI, np.zeros(np.shape(img2), dtype=np.uint8), mask=mask)  # 生成背景,与 cv2.bitwise 效果相同# img2Fg = cv2.add(img2, np.zeros(np.shape(img2), dtype=np.uint8), mask=maskInv)  # 生成背景,与 cv2.bitwise 效果相同imgROIAdd = cv2.add(img1Bg, img2Fg)  # 前景与背景合成,得到裁剪部分的叠加图像imgAdd = img1.copy()imgAdd[y:y+W2, x:x+H2] = imgROIAdd  # 用叠加图像替换背景图像中的叠加位置,得到叠加 Logo 合成图像plt.figure(figsize=(9,6))titleList = ["1. imgGray", "2. imgMask", "3. MaskInv", "4. img2FG", "5. img1BG", "6. imgROIAdd"]imageList = [img2Gray, mask, maskInv, img2Fg, img1Bg, imgROIAdd]for i in range(6):plt.subplot(2,3,i+1), plt.title(titleList[i]), plt.axis('off')if (imageList[i].ndim==3):  # 彩色图像 ndim=3plt.imshow(cv2.cvtColor(imageList[i], cv2.COLOR_BGR2RGB))  # 彩色图像需要转换为 RGB 格式else:  # 灰度图像 ndim=2plt.imshow(imageList[i], 'gray')plt.show()cv2.imshow("imgAdd", imgAdd)  # 显示叠加图像 imgAddkey = cv2.waitKey(0)  # 等待按键命令

例程说明 1.30:

  • 本例程实现图像的叠加,中间过程图像如上图所示,最终的叠加图像如下图所示。
  • 图像叠加所涉及的操作步骤较多,建议将上文的步骤说明与程序、中间过程图像相互对照进行阅读。
  • 使用位操作生成前景 img1Bg 时,使用掩模图像 mask 对 imgROI 与 imgROI 进行 “与操作”,而不是直接对 mask 与 imgROI 进行操作,是因为 mask 为灰度图像而 imgROI 为彩色图像,不能直接进行加法或位操作。
  • 使用位操作生成前景、背景图像时,遮罩区域以外 imgROI 与 imgROI 进行 “自与操作”,如果用 “自或操作” (参见程序注释语句)的效果也是相同的。此处甚至也可以用加法操作 cv2.add 实现(参见程序注释语句),但位操作的运算速度更快。
  • 函数 threshold() 将灰度图像转换为二值图像(Binarization),只有黑白两色。该方法通过固定阈值 thresh 处理图像,将像素点的灰度值设为 0 或 255。


6. 图像添加文字

函数 cv2.putText() 用于在图像上绘制文本字符串,即添加文字。

函数说明:

cv2.putText(img, text, pos, fontFace,fontScale,color[, thickness[, lineType[, bottomLeftOrigin]]]) → dst

函数 cv2.putText() 用于在图像上绘制文本字符串。

参数说明:

  • img:添加文本字符串的图像,ndarray 多维数组
  • text:添加的文本字符串
  • pos:文本字符串左下角坐标,如元组 (x=100, y=100)
  • font:字体类型
  • fontScale:字体缩放比例因子
  • color:文本字符串的颜色,如元组 (255,0 ,0)
  • thickness:线条粗细,单位为像素数
  • lineType:线条类型
  • bottomLeftOrigin:可选参数,默认值 True 表示数据原点位于左下角,False 表示位于左上角
  • 返回值:dst,结果图像,ndarray 多维数组

注意事项:

  1. OpenCV 不支持显示中文字符,使用 cv2.putText() 时添加的文本字符串不能包含中文字符(包括中文标点符号)。
  2. 在图像中添加中文字符,可以使用 python+opencv+PIL 实现,或使用 python+opencv+freetype 实现。具体方法详见扩展例程 1.32。

基本例程:1.31 图像添加文字

    # 1.31 图像添加文字img1 = cv2.imread("../images/imgLena.tif")  # 读取彩色图像(BGR)text = "OpenCV2021, youcans@xupt"fontList = [cv2.FONT_HERSHEY_SIMPLEX,cv2.FONT_HERSHEY_SIMPLEX,cv2.FONT_HERSHEY_PLAIN,cv2.FONT_HERSHEY_DUPLEX,cv2.FONT_HERSHEY_COMPLEX,cv2.FONT_HERSHEY_TRIPLEX,cv2.FONT_HERSHEY_COMPLEX_SMALL,cv2.FONT_HERSHEY_SCRIPT_SIMPLEX,cv2.FONT_HERSHEY_SCRIPT_COMPLEX,cv2.FONT_ITALIC]fontScale = 1  # 字体缩放比例color = (255, 255, 255)  # 字体颜色for i in range(10):pos = (10, 50*(i+1))imgPutText = cv2.putText(img1, text, pos, fontList[i], fontScale, color)cv2.imshow("imgPutText", imgPutText)  # 显示叠加图像 imgAddkey = cv2.waitKey(0)  # 等待按键命令

扩展例程:1.32 图像中添加中文文字

    # 1.32 图像中添加中文文字imgBGR = cv2.imread("../images/imgLena.tif")  # 读取彩色图像(BGR)from PIL import Image, ImageDraw, ImageFontif (isinstance(imgBGR, np.ndarray)):  # 判断是否 OpenCV 图片类型imgPIL = Image.fromarray(cv2.cvtColor(imgBGR, cv2.COLOR_BGR2RGB))text = "OpenCV2021, 中文字体"pos = (50, 20)  # (left, top),字符串左上角坐标color = (255, 255, 255)  # 字体颜色textSize = 40drawPIL = ImageDraw.Draw(imgPIL)fontText = ImageFont.truetype("font/simsun.ttc", textSize, encoding="utf-8")drawPIL.text(pos, text, color, font=fontText)imgPutText = cv2.cvtColor(np.asarray(imgPIL), cv2.COLOR_RGB2BGR)cv2.imshow("imgPutText", imgPutText)  # 显示叠加图像 imgAddkey = cv2.waitKey(0)  # 等待按键命令

【本节完】

版权声明:

youcans 的 OpenCV 学习课 @ youcans 原创作品
转载必须标注原文链接:https://blog.csdn.net/youcans/article/details/121136047
Copyright 2021 youcans, XUPT
Crated:2021-11-08

欢迎关注 『youcans 的 OpenCV 学习课』 系列,持续更新
youcans 的 OpenCV 学习课—1.安装与环境配置
youcans 的 OpenCV 学习课—2.图像读取与显示
youcans 的 OpenCV 学习课—3.图像的创建与修改
youcans 的 OpenCV 学习课—4.图像的叠加与混合
youcans 的 OpenCV 学习课—5.图像的几何变换
youcans 的 OpenCV 学习课—6.灰度变换与直方图处理
youcans 的 OpenCV 学习课—7.空间域图像滤波
youcans 的 OpenCV 学习课—8.频率域图像滤波(上)
youcans 的 OpenCV 学习课—9.频率域图像滤波(下)

youcans 的 OpenCV 学习课—4.图像的叠加与混合相关推荐

  1. youcans 的 OpenCV 学习课—5.图像的几何变换

    youcans 的 OpenCV 学习课-5.图像的几何变换 本系列面向 Python 小白,从零开始实战解说 OpenCV 项目实战. 几何变换是指对图像的位置.大小.形状.投影进行变换,是将图像从 ...

  2. youcans 的 OpenCV 学习课—3.图像的创建与修改

    youcans 的 OpenCV 学习课-3.图像的创建与修改 本系列面向 Python 小白,从零开始实战解说 OpenCV 项目实战. OpenCV 中图像的数据结构是 ndarray 多维数组, ...

  3. youcans 的 OpenCV 学习课—2.图像读取与显示

    youcans 的 OpenCV 学习课-2.图像读取与显示 本系列面向 Python 小白,从零开始实战解说 OpenCV 项目实战. 本节介绍图像的读取.保存和显示.除基本方法和例程外,还给出了从 ...

  4. youcans 的 OpenCV 学习课—8.频率域图像滤波(上)

    欢迎关注 『OpenCV 例程200篇』 系列,持续更新中 欢迎关注 『youcans 的 OpenCV 学习课』 系列,持续更新中 youcans 的 OpenCV 学习课-1.安装与环境配置 yo ...

  5. youcans 的 OpenCV 学习课—10. 图像复原与重建

    youcans 的 OpenCV 学习课-10. 图像复原与重建 本系列面向 Python 小白,从零开始实战解说 OpenCV 项目实战. 图像复原是对图像退化过程建模,并以图像退化的先验知识来恢复 ...

  6. youcans 的 OpenCV 学习课—6.灰度变换与直方图处理

    youcans 的 OpenCV 学习课-6.灰度变换与直方图处理 本系列面向 Python 小白,从零开始实战解说 OpenCV 项目实战. 空间域的图像处理方法直接对图像的像素点进行处理,空间域图 ...

  7. youcans 的 OpenCV 学习课—1.安装与环境配置

    youcans 的 OpenCV 学习课-1.安装与环境配置 作者: youcans@xupt 本系列面向 Python 小白,从零开始实战解说 OpenCV 项目实战. 什么叫从零开始?从软件安装. ...

  8. 【youcans 的 OpenCV 学习课】7. 空间域图像滤波

    专栏地址:『youcans 的图像处理学习课』 文章目录:『youcans 的图像处理学习课 - 总目录』 [youcans 的 OpenCV 学习课]7. 空间域图像滤波 图像滤波是在尽可能保留图像 ...

  9. 【youcans 的图像处理学习课】22. Haar 级联分类器

    专栏地址:『youcans 的图像处理学习课』 文章目录:『youcans 的图像处理学习课 - 总目录』 [youcans 的图像处理学习课]22. Haar 级联分类器 3. Haar 特征及其加 ...

最新文章

  1. 给定一个n,输出从1到n的整数
  2. 云场景实践研究第85期:墨迹天气
  3. 在YII2框架中使用UEditor编辑器发布文章
  4. POJ2236(并查集)
  5. mysql2012更改表名_sql alter table修改数据库的表名字
  6. 谷歌Android各版本的代号变迁
  7. python压缩教程_无需压缩软件,用python帮你操作压缩包
  8. centos7安装python3.6独立的virtualenv环境
  9. 浮点错误是什么意思_Excel函数计算常见错误值,都是什么意思
  10. WindowsXP相关设置对应的注册表位置
  11. 使用PMSM控制的puma560机械臂简单轨迹跟踪
  12. 机械制图之零件图表达
  13. JS实现轮播图(一看就懂逻辑清晰)
  14. 搭建多节点以太坊私链 10分钟搞定(超简洁)
  15. linux搭建http代理服务器
  16. EI、SCI和ISTP检索论文的收录号和期刊号查询方法
  17. 小米摄像头结合samba共享存储实现视频实时转存
  18. 十月上旬百度 阿里巴巴 迅雷搜狗最新面试七十题 第201 270题
  19. Mac关闭“屏幕截图”和“清倒废纸篓”音效
  20. CTF php反序列化总结

热门文章

  1. vue项目使用electron打包成桌面应用
  2. maven-compiler-plugin 插件详解
  3. RedisTemplate常用集合使用说明-opsForZSet(六)
  4. 比较Spring AOP和AspectJ
  5. Shiro——RememberMe
  6. mybatis获取表名——mybatis动态调用表名和字段名#{},${}
  7. hashSet与treeSet的去重原理
  8. python变量类型有几种_python十种变量类型
  9. Jackson高级操作————流式API与JsonGenerator、JsonParser
  10. 当面试官问我————Java是值传递还是引用传递?