现要向一幅图像中添加标志,素材如下:
import cv2 as cv
# 读取原图和logo图像
img_a = cv.imread("./image/fengjing.jpg")
img_l = cv.imread("./image/imageaddlogo.png")
# 显示原图片
cv.imshow("Origin", img_a)
# 括号内单位为毫秒,0代表一直显示
cv.waitKey(0)
# 显示logo图像
cv.imshow("logo", img_l)
cv.waitKey(0)
# 创建ROI(感兴趣区)
row_a, col_a, channel_a = img_a.shape
row_l, col_l, channel_l = img_l.shape
print(row_a, col_a, channel_a)
print(row_l, col_l, channel_l)
# logo图片太长,做一个处理
img_l_new = img_l[0:row_a, :]
# 更新shape
row_l, col_l, channel_l = img_l_new.shape
# 将ROI区域放在右上角
roi = img_a[0: row_l, (col_a-col_l): col_a]
print("roi的shape", roi.shape)
cv.imshow("ROI_area", roi)
cv.waitKey(0)
# 将logo图像变为灰度图
img_l_gray = cv.cvtColor(img_l_new, cv.COLOR_BGR2GRAY)
cv.imshow("logo_gray", img_l_gray)
cv.waitKey(0)
# 将灰度图二值化,将logo图标变为黑色,背景为白色,类似于抠图
print(cv.threshold(img_l_gray, 235, 255, cv.THRESH_BINARY))
ret, mask = cv.threshold(img_l_gray, 235, 255, cv.THRESH_BINARY)
cv.imshow("mask", mask)
cv.waitKey(0)
# 将logo图标变为白色,背景为黑色 bitwise_not是非操作
mask_inv = cv.bitwise_not(mask)
cv.imshow("mask_inv", mask_inv)
cv.waitKey(0)
# 将ROI中logo的区域涂黑,方便后续放进去logo
img_a_bg = cv.bitwise_and(roi, roi, mask=mask)
cv.imshow("img_a_bg", img_a_bg)
cv.waitKey(0)
# 从logo图像中提取logo区域
img_l_fg = cv.bitwise_and(img_l_new, img_l_new, mask=mask_inv)
cv.imshow("img_l_fg", img_l_fg)
cv.waitKey(0)
# 将logo放入ROI中的涂黑区域,此时ROI区域已经处理好
logo_put_in = cv.add(img_a_bg, img_l_fg)
cv.imshow("logo_put_in", logo_put_in)
cv.waitKey(0)
# 将处理好的ROI区放入原图中
img_a[0:row_l, (col_a-col_l):col_a] = logo_put_in
# 输出的结果
cv.imshow("result", img_a)
cv.waitKey(0)
cv.destroyAllWindows()
运行结果:
在编写过程中,遇到了一些问题,如两幅图片的尺寸问题,原图的尺寸为(675 1200 3),标志的尺寸为(743 883 3),标志图片的长度大于原图的长度,在后续操作中导致报错,于是,在进行后续操作前,对标志区域进行裁剪,用到语句:
# logo图片太长,做一个处理
img_l_new = img_l[0:row_a, :]
将其的长度裁剪,后续操作得以进行。
此外,还有一些知识点:
# 括号内单位为毫秒,0代表一直显示
cv.waitKey(0)
# cvThreshold 对单通道数组应用固定阈值操作。该函数的典型应用是对灰度图像进行阈值操作得到二值图像。
cv.threshold(img_l_gray, 235, 255, cv.THRESH_BINARY)
欢迎大家查看作者的主页,主页中还有关于编程与算法方面的更多内容,欢迎大家相互沟通学习~