cv2将png透明图粘贴到其他图片 作者:马育民 • 2020-04-30 20:06 • 阅读:11249 需要掌握:[通过python、numpy理解png alpha通道(透明)原理](https://www.malaoshi.top/show_1EF5RBxcyfIV.html "通过python、numpy理解png alpha通道(透明)原理") # 介绍 cv2 没有将 png透明图粘贴到 其他图片的方法 >这点与 PIL 库不同,PIL库有简单易用的方法 只能通过 掩膜的方式 手动进行处理 ### png图片 下面png图片,四周是透明,中间是个猪头 [](https://www.malaoshi.top/upload/0/0/1EF5R6YBa9l0.png) ### jpg图片 [](https://www.malaoshi.top/upload/0/0/1EF5RBWxrTqr.jpg) ### 粘贴结果 [](https://www.malaoshi.top/upload/0/0/1EF5RBw6cd7U.png) # 代码 ### 读取图片 ``` import cv2 covered=cv2.imread("/Users/mym/Desktop/可删除/pig.png",cv2.IMREAD_UNCHANGED) print(covered.shape) background=cv2.imread("/Users/mym/Desktop/可删除/QQ20200428-151456.jpg") print(background.shape) ``` ### 分离png通道 png 有bgra 4个通道,分离4个通道后,将bgr组成新的图片 ``` b,g,r,a = cv2.split(png) # 合并bgr3个通道,构成普通的3通道图片 foreground = cv2.merge((b,g,r)) ``` ### 掩膜(mask) 掩膜是二维矩阵数组,通过对图像进行遮挡,来控制图像处理的区域 举个例子:掩膜相当于下图中 镂空喷漆的遮挡版 [](https://www.malaoshi.top/upload/0/0/1EF5REiVabjz.png) 图像矩阵,原图 与 mask 进行乘法运算,或者 与运算(x & 1 = x;x & 0 = 0): [](https://www.malaoshi.top/upload/0/0/1EF5REkuXTL3.png) 具体作用(摘自百度百科): 1. 提取感兴趣区,用预先制作的感兴趣区掩模与待处理图像相乘,得到感兴趣区图像,感兴趣区内图像值保持不变,而区外图像值都为0。 2. 屏蔽作用,用掩模对图像上某些区域作屏蔽,使其不参加处理或不参加处理参数的计算,或仅对屏蔽区作处理或统计。 3. 结构特征提取,用相似性变量或图像匹配方法检测和提取图像中与掩模相似的结构特征。 4. 特殊形状图像的制作。 ### 将alpha通道转成掩膜 将3个 alpha 通道合并,在二值化,转成 alpha 掩模,用于后面计算 ``` alpha = cv2.merge((a,a,a)) # 二值化处理,大于254的值为1,否则为0 ret, alpha = cv2.threshold(alpha, 254, 1, cv2.THRESH_BINARY) ``` 透明的部分为0,不透明的部分为1 ### 将png的bgr图片与掩膜运算(关键) 将png的bgr图片 与 掩膜运算(显示部分为1,透明部分为0),乘法运算 或 与运算均可,运算后结果:不显示的部分就是0,显示的部分是原像素值 ``` foreground = cv2.multiply(alpha,foreground) cv2.imshow("1",foreground) cv2.waitKey(0) ``` [](https://www.malaoshi.top/upload/0/0/1EF5RCcNKS4M.png) ### 截取背景图 从背景图截取 png图片大小的区域,用于后面处理 ``` background_temp=background[0:foreground.shape[0],0:foreground.shape[1],:] cv2.imshow("1",background_temp) cv2.waitKey(0) ``` [](https://www.malaoshi.top/upload/0/0/1EF5RCUIBGbB.png) ### 将截取背景图片与反掩膜运算(关键) 将截取的背景图和 1-alpha 相乘, foreground 显示的部分,截取的背景图中值为0, foreground 不显示的部分,截取的背景图中为原像素值 ``` background_temp = cv2.multiply(1-alpha,background_temp) cv2.imshow("1",background_temp) cv2.waitKey(0) ``` [](https://www.malaoshi.top/upload/0/0/1EF5RCefYowQ.png) ### 将两个矩阵相加 ``` outImage = foreground + background_temp cv2.imshow("1",outImage) cv2.waitKey(0) ``` [](https://www.malaoshi.top/upload/0/0/1EF5RCjkYp0Z.png) ### 回填背景图中 ``` background[0:foreground.shape[0],0:foreground.shape[1],:]=outImage cv2.imshow("1",background) cv2.waitKey(0) ``` 最终结果: [](https://www.malaoshi.top/upload/0/0/1EF5RBw6cd7U.png) 原文出处:http://malaoshi.top/show_1EF5RFRqZqPr.html