版权声明:原文为san1156原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。链接:https://blog.csdn.net/san1156/article/details/76854307
1,目的
将logo图标叠加到一张图片的右上角,要求有颜色的区域为不透明,例如将阿里影业的Logo叠加到战狼2的海报上,原始图和效果图如下。
2,思路
不同的logo有不同的处理方法,有的是黑色需要透明,有的是白色需要透明,但是,整理的思路是一致的。
注意
- cv2.add(img,mask) 对被掩模图像遮蔽的黑色区域不进行处理,保持黑色。
- 掩膜 遮蔽区域为黑色,非遮蔽区域为透明,开窗区域
- 掩膜 与 原图 尺寸必须相同
如下图所示,从上向下,对要形成的效果进行分解,一共分为3层。
- 第一层需要第二层的两张图片,做cv2.add运算即可
- 第二层第一张图片需要第三层前两张图片,做cv2.bitwise_and运算即可,后一张做mask
- 第二层第二张图片需要第三层后两张图片,做cv2.bitwise_and运算即可,后一张做mask
3,步骤分析
基于上述思路,制定详细的图像处理步骤,并进行编码调试。处理步骤如下图所示。
3. 1,对logo进行缩放,按照20%进行
logo_img = cv2.imread("logo.png", cv2.IMREAD_COLOR)
logo_img = cv2.resize(logo_img, (0, 0), fx=0.2, fy=0.2, interpolation=cv2.INTER_NEAREST) # inter..这个是为了对齐
3. 2,对logo做清洗,白色区域是255,其他区域置为黑色0
logo_gray = cv2.cvtColor(logo_img, cv2.COLOR_BGR2GRAY) # 变成灰度图
阈值, 二值化_logo_mask = cv2.threshold(logo_gray, 200, 255, cv2.THRESH_BINARY) # 二值化函数,大于200的当255,非黑即白
二值化_logo_mask_反 = cv2.bitwise_not(二值化_logo_mask)
3.3,提取目标图片的ROI
目标图 = cv2.imread("wolf.jpg", cv2.IMREAD_COLOR)
行_logo, 列_logo, 通道 = logo_img.shape
行_目标图, 列_目标图, 通道2 = 目标图.shape
ROI=目标图[:行_logo,列_目标图-列_logo:]
3.4,ROI和LOGO图像融合
融合二值化_ROI=cv2.bitwise_and(ROI,ROI,mask=二值化_logo_mask)
融合二值化_反_原logo=cv2.bitwise_and(logo_img,logo_img,mask=二值化_logo_mask_反)
融合相加=cv2.add(融合二值化_反_原logo,融合二值化_ROI)
3. 5, ROI 贴回目标图
目标图[:行_logo,列_目标图-列_logo:]=融合相加[:,:]
cv2.imwrite("wolf++.jpg",目标图)
4,MATPLOTLIB的SUBPLOT简单介绍 plt 列表
代码如下,效果图如method of img deal.png所示。
代码
plt.rcParams["font.sans-serif"] = ["SimHei"] # 显示汉字
plt.subplots(constrained_layout=True) # 子图自适应行距 constrained 受约束的
# 总3行, 本行3列 第二列
plt.subplot(332),plt.imshow(bgr2rgb(融合相加)),plt.title("融合相加")
# 总三行 本行2列 , 感觉应该是 4 5 但不行 只能 3 4
plt.subplot(323),plt.imshow(bgr2rgb(融合二值化_ROI)),plt.title("融合二值化_ROI")
plt.subplot(324),plt.imshow(bgr2rgb(融合二值化_反_原logo)),plt.title("融合二值化_反_原logo")
# 总 三行 本行4列 3*4 12 所以从 9-12,之所以用,隔开 是因为 10 11 12 两位数
plt.subplot(3,4,9),plt.imshow(bgr2rgb(ROI)),plt.title("ROI")
plt.subplot(3,4,10),plt.imshow(bgr2rgb(二值化_logo_mask),"gray"),plt.title("二值化")
plt.subplot(3,4,11),plt.imshow(bgr2rgb(logo_img)),plt.title("log原图")
plt.subplot(3,4,12),plt.imshow(bgr2rgb(二值化_logo_mask_反),"gray"),plt.title("二值化-反")
plt.show()
5,源码奉上
# coding:utf8
import numpy as np
import cv2
from matplotlib import pyplot as plt
# 图像处理,将logo图标叠加到一张图片的右上角,要求有颜色的区域为不透明
# 1,对logo进行缩放,按照20%进行
logo_img = cv2.imread("logo.png", cv2.IMREAD_COLOR)
logo_img = cv2.resize(logo_img, (0, 0), fx=0.2, fy=0.2, interpolation=cv2.INTER_NEAREST) # inter..这个是为了对齐
# 2,对logo做清洗,白色区域是255,其他区域置为黑色0
logo_gray = cv2.cvtColor(logo_img, cv2.COLOR_BGR2GRAY) # 变成灰度图
阈值, 二值化_logo_mask = cv2.threshold(logo_gray, 200, 255, cv2.THRESH_BINARY) # 二值化函数,大于200的当255,非黑即白
二值化_logo_mask_反 = cv2.bitwise_not(二值化_logo_mask)
# 3,提取目标图片的ROI
目标图 = cv2.imread("wolf.jpg", cv2.IMREAD_COLOR)
行_logo, 列_logo, 通道 = logo_img.shape
行_目标图, 列_目标图, 通道2 = 目标图.shape
ROI=目标图[:行_logo,列_目标图-列_logo:]
# 4,ROI和LOGO图像融合
融合二值化_ROI=cv2.bitwise_and(ROI,ROI,mask=二值化_logo_mask)
融合二值化_反_原logo=cv2.bitwise_and(logo_img,logo_img,mask=二值化_logo_mask_反)
融合相加=cv2.add(融合二值化_反_原logo,融合二值化_ROI)
# 5, ROI 贴回目标图
目标图[:行_logo,列_目标图-列_logo:]=融合相加[:,:]
cv2.imwrite("wolf++.jpg",目标图)
cv2.imshow("++", 目标图)
cv2.waitKey(100)
"""展示 勿删 plt"""
# cv2与matplotlib的图像转换,cv2是bgr格式,matplotlib是rgb格式
def bgr2rgb(cv2_img) :
# 灰度图片直接返回
if len(cv2_img.shape) == 2 :
return cv2_img
# 3通道的BGR图片
elif len(cv2_img.shape) == 3 and cv2_img.shape[2] == 3 : # 三位数,三通道
b, g, r = cv2.split(cv2_img)
return cv2.merge((r, g, b))
# 4通道的BGR图片
elif len(cv2_img.shape) == 3 and cv2_img.shape[2] == 4 : # 三位数,三通道+明度
b, g, r,a = cv2.split(cv2_img)
return cv2.merge((r, g, b,a))
# 未知格式
else: return cv2_img
plt.rcParams["font.sans-serif"] = ["SimHei"] # 显示汉字
plt.subplots(constrained_layout=True) # 子图自适应行距 constrained 受约束的
plt.subplot(441),plt.imshow(bgr2rgb(logo_img)),plt.title("log原图")
plt.subplot(442),plt.imshow(bgr2rgb(目标图)),plt.title("目标图")
plt.subplot(443),plt.imshow(bgr2rgb(ROI)),plt.title("ROI")
plt.subplot(445),plt.imshow(bgr2rgb(logo_gray),'gray'),plt.title("灰度图")
plt.subplot(446),plt.imshow(bgr2rgb(二值化_logo_mask),"gray"),plt.title("二值化")
plt.subplot(447),plt.imshow(bgr2rgb(二值化_logo_mask_反),"gray"),plt.title("二值化-反")
plt.subplot(449),plt.imshow(bgr2rgb(融合二值化_ROI)),plt.title("融合二值化_ROI")
plt.subplot(4,4,10),plt.imshow(bgr2rgb(融合二值化_反_原logo)),plt.title("融合二值化_反_原logo")
plt.subplot(4,4,11),plt.imshow(bgr2rgb(融合相加)),plt.title("融合相加")
plt.show()