OpenCV例程 (五)

目录

17. 两张图像的渐变切换

18. 图像的掩模加法(mask)

19. 图像的圆形遮罩

20. 图像的按位运算

21. 图像的叠加

22. 图像添加非中文文字

23. 图像添加中文文字(ImageDraw.Draw

17. 两张图像的渐变切换

        通过改变两张图像的权重,来实现渐变变换

import cv2
import numpy as np

img0 = cv2.imread('test.jpg', flags=1)
img1 = cv2.imread('netdog.jpg', flags=1)
img0 = cv2.resize(img0, (300, 300))
img1 = cv2.resize(img1, (300, 300))

# 17
wlist = [0.0, 0.2, 0.5, 0.8, 1.0]
for w in wlist:
    img2 = cv2.addWeighted(img0, w, img1, 1-w, 0)
    cv2.imshow('alpha = {},beta = {}'.format(w, 1-w), img2)
cv2.waitKey()

18. 图像的掩模加法(mask)

        有一张图像,我们在做处理的时候,如果不想处理图像的某一部分或者只想处理图像的某一部分,我们就可以对图像设置掩模(mask),掩模可以是一个其他的图像也可以是函数,函数 cv2.add() 用于图像的加法运算,可以使用掩模图像进行遮蔽。函数 cv2.add 进行加法运算,对被掩模图像遮蔽的黑色区域不进行处理,保持黑色。

# 18
Mask = np.zeros((img1.shape[0], img1.shape[0]), dtype=np.uint8)  # 创建和img1尺寸相同的全0数组
xmin, ymin, w, h = 80, 90, 100, 100
Mask[ymin:ymin+h, xmin:xmin+w] = 255  # 模图像,ROI 为白色,其它区域为黑色
print(img0.shape, img1.shape, Mask.shape)
imgAddMask1 = cv2.add(img0, img1, mask=Mask)
cv2.imshow('Mask', Mask)
cv2.imshow('imgAddMask1', imgAddMask1)  # 将 img1 与 img2 进行饱和加法,其它区域为黑色遮蔽
cv2.waitKey()
cv2.destroyAllWindows()

19. 图像的圆形遮罩

        也就是在mask中把感兴趣的区域(白色区域)设置为圆形

cv2.ellipse(image, centerCoordinates, axesLength, angle, startAngle, endAngle, color [, thickness[, lineType[, shift]]])

image:要在其上绘制椭圆的图像。

centerCoordinates:它是椭圆的中心坐标。坐标表示为两个值的元组,即(X坐标值,Y坐标值)。 axesLength:它包含两个变量的元组,分别包含椭圆的长轴和短轴(长轴长度,短轴长度)。 angle:椭圆旋转角度,以度为单位。

startAngle:椭圆弧的起始角度,以度为单位。 endAngle:椭圆弧的终止角度,以度为单位。

color:它是要绘制的形状边界线的颜色。对于BGR,我们通过一个元组。例如:(255,0,0)为蓝色。

thickness:是形状边界线的粗细像素。厚度-1像素将用指定的颜色填充形状。 lineType:这是一个可选参数,它给出了椭圆边界的类型。 shift:这是一个可选参数。它表示中心坐标中的小数位数和轴的值。

# 19
Mask1 = np.zeros((img1.shape[0], img0.shape[1]), dtype=np.uint8)
Mask2 = Mask1.copy()
cv2.circle(Mask1, (150, 150), 50, (255, 255, 255), -1)  # 圆形:圆心,半径,颜色,-1代表实心
cv2.ellipse(Mask2, (150, 150), (50, 30), 0, 0, 360, 255, -1)  # 椭圆
imgAddMask2 = cv2.add(img0, img1, mask=Mask1)
imgAddMask3 = cv2.add(img0, img1, mask=Mask2)
imgAddMask4 = cv2.add(img1, (np.zeros(img1.shape, dtype=np.uint8)), mask=Mask1)
imgAddMask5 = cv2.add(img1, (np.zeros(img1.shape, dtype=np.uint8)), mask=Mask2)
cv2.imshow('imgAddMask2', imgAddMask2)
cv2.imshow('imgAddMask3', imgAddMask3)
cv2.imshow('imgAddMask4', imgAddMask4)
cv2.imshow('imgAddMask5', imgAddMask5)
cv2.waitKey()
cv2.destroyAllWindows()

20. 图像的按位运算

        按位运算包括:按位与、按位或、按位非、按位异或

imgAnd = cv2.bitwise_and(img0, img1)  # 按位与
imgOr = cv2.bitwise_or(img0, img1)  # 按位或
imgNot = cv2.bitwise_not(img0, img1)  # 按位非
imgXor = cv2.bitwise_xor(img0, img1)  # 按位异或
cv2.imshow('imgAnd', imgAnd)
cv2.imshow('imgOr', imgOr)
cv2.imshow('imgNot', imgNot)
cv2.imshow('imgXor', imgXor)
cv2.waitKey()
cv2.destroyAllWindows()

21.图像的叠加

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

以 test 图像叠加 logo 为例:

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

cv2.threshold(src, thresh, maxval, type[, dst]),返回值为retval, dst

src是灰度图像

thresh是起始阈值 m

maxval是最大值

cv2.THRESH_BINARY 意思是thresh设置为 maxval,其他设置为0

输出:第一个是阈值,第二个是处理过的图像

img2 = cv2.imread('test.jpg', flags=1)  # 读取图像
img3 = cv2.imread('logo.jpg', flags=1)  # 读取logo
img3 = cv2.resize(img3, (50, 50))
x, y = (0, 10)  # 图像叠加位置
w2, h2 = img2.shape[1::-1]
w3, h3 = img3.shape[1::-1]
if (x + w3) > w2: x = w2 - w3
if (y + h3) > h2: y = h2 - h3
print(w2, h2, w3, h3, x, y)
imgROI = img2[x:x+w3, y:y+h3]
img2Gray = cv2.cvtColor(img3, cv2.COLOR_BGR2GRAY)  # 把logo图像转换为灰色图像
ret, mask = cv2.threshold(img2Gray, 175, 255, cv2.THRESH_BINARY)  # 把灰色图像转换为二值图像
maskInv = cv2.bitwise_not(mask)  # 按位非(黑白转置),生成逆遮罩,LOGO 区域白色开窗,LOGO 以外区域黑色

img2Bg = cv2.bitwise_and(imgROI, imgROI, mask=mask)  # 生成背景,imgROI 的遮罩区域输出黑色
img3Fg = cv2.bitwise_and(img3, img3, mask=maskInv)  # 生成前景,LOGO 的逆遮罩区域输出黑
imgROIADD = cv2.add(img2Bg, img3Fg)
imgAdd = img2.copy()
imgAdd[x:x+w3, y:y+h3] = imgROIADD
cv2.imshow('img', imgAdd)
cv2.imwrite('imgAdd_21.jpg', imgAdd)
cv2.waitKey()
cv2.destroyAllWindows()

22.图像添加非中文文字

cv2.putText(img, text, pos, fontFace,fontScale,color[, thickness[, lineType[, bottomLeftOrigin]]]) → dst
img:添加文本字符串的图像,ndarray 多维数组
text:添加的文本字符串
pos:文本字符串左下角坐标,如元组 (x=100, y=100)
font:字体类型
fontScale:字体缩放比例因子
color:文本字符串的颜色,如元组 (255,0 ,0)
thickness:线条粗细,单位为像素数
lineType:线条类型
bottomLeftOrigin:可选参数,默认值 True 表示数据原点位于左下角,False 表示位于左上角
返回值:dst,结果图像,ndarray 多维数组
img4 = cv2.imread('test.jpg', flags=1)
text = 'Hello dog!'
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]
font_color = (255, 255, 255)
fontScale = 1
for i in range(10):
    pos = (10, 50*(i+1))
    img4 = cv2.putText(img4, text, pos, fontList[i], fontScale, font_color)
cv2.imshow('img4', img4)
cv2.waitKey()
cv2.destroyAllWindows()

23.图像添加中文文字

        在图像中添加中文字符,可以使用 python+opencv+PIL 实现

from PIL import ImageDraw, ImageFont, Image

imgBGR = cv2.imread('test.jpg', flags=1)
# 判断图像是不是BGR类型的
if (isinstance(imgBGR, np.ndarray)):
    imgPIL = Image.fromarray(cv2.cvtColor(imgBGR, cv2.COLOR_BGR2RGB))  # array转换成PIL中的image
pos = (20, 20)
text = '中文字体'
color = (255, 255, 255)
path = '电脑字体路径'
textSize = 40
ImageDraw = ImageDraw.Draw(imgPIL)   # 创建一个可以在给定图像上绘图的对象
fontText = ImageFont.truetype(path, textSize, encoding="utf-8")
ImageDraw.text(pos, text, color, font=fontText)
imageputText = cv2.cvtColor(np.asarray(imgPIL), cv2.COLOR_RGB2BGR)

cv2.imshow('imageputText', imageputText)
cv2.waitKey()
cv2.destroyAllWindows()

参考自:youcans@qq.com, youcans的OpenCV 例程200篇

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值