OpenCV-Python图像处理:区分前景背景权重的图像融合案例

☞ ░ 前往老猿Python博客 https://blog.csdn.net/LaoYuanPython

一、引言

在《https://blog.csdn.net/LaoYuanPython/article/details/109143281 OpenCV-Python图像融合cv2.addWeighted权重加法函数详解》介绍了两幅图像按不同权重的融合,但当两幅图中有一幅的背景色为黑色,希望融合时背景色为黑色的部分不能遮挡另一幅图,而没有黑色背景的则按比重融合时,addWeighted已经不能满足要求。为适应这种场景,我们来实现一个这样融合的函数。

二、思路

假设图像A和B融合,B为黑色背景,为了实现黑色背景的图像背景不遮挡图像A,实现类似透明的效果,采用如下思路:

  1. 将黑色背景图像B对应的图像掩码求出,并得到该图像掩码求反的掩码反码;
  2. 按照B图像的掩码和反码,将图像A分成两部分,分别与B图像的前景和背景范围对应,得到A1(对应B前景)和A2(对应B背景);
  3. 让A1和B前景部分按对应权重融合,将A2部分和B背景部分按另外的权重融合,两融合结果图像相加,即得到最终的结果图像。

三、实现

具体的代码实现遵循上述思路,但编码的细节比较复杂一些,具体参考注释:

def addWeightedDistinguishBLK(img1, alpha, img2, beta, sigma, gamma=0.0):
    """
    图像img1和img2权重相加,但图像img2中像素为黑色的部分取img1的像素权重为sigma
    参数img1, alpha, img2, beta, gamma与addWeighted的参数相同,sigma为img1中对应img2黑色部分范围的权重
    """
    l = len(img2.shape)
    if l == 3:#是彩色图
        row, col, channel = img2.shape
        if channel == 3:
            img2Gray = cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY)
        else:
            img2Gray = cv2.cvtColor(img2, cv2.COLOR_BGRA2GRAY)
    else:#是灰度图
        img2Gray = img2
    retval, img2Inv = cv2.threshold(img2Gray, 43, 255, cv2.THRESH_BINARY_INV) #将灰度小于43的像素作为黑色,img2Inv为img2黑色部分设为255,非黑色部分设为0的img2图像掩码反码
   
    #为了对img2图像前景进行平滑,对img2图像掩码反码进行开、闭、膨胀运算,
    kernal = cv2.getStructuringElement(cv2.MORPH_RECT,(3,3))
    img2Inv = cv2.morphologyEx(img2Inv, cv2.MORPH_OPEN, kernal)
    img2Inv = cv2.morphologyEx(img2Inv,cv2.MORPH_CLOSE,kernal)
    img2Inv = cv2.morphologyEx(img2Inv, cv2.MORPH_DILATE, kernal)
    
    retval, img2Mask = cv2.threshold(img2Inv, 0, 255, cv2.THRESH_BINARY_INV) #求img2的掩码
    
    img1Transparent = cv2.bitwise_and(img1, img1, mask=img2Inv) #获得img1中与img2背景范围对应的部分
    img1NotTransparent = cv2.bitwise_and(img1, img1, mask=img2Mask)#获得img1中与img2前景范围对应的部分
    img2NotTransparent = cv2.bitwise_and(img2, img2, mask=img2Mask) #获得img2中前景部分

    imgTmp = cv2.addWeighted(img1NotTransparent, alpha, img2NotTransparent, beta, gamma) #img1中与img2前景范围对应的部分与img2前景部分融合
    dest = cv2.addWeighted(imgTmp, 1, img1Transparent, sigma, gamma) #将融合前景部分与img1对应img2背景部分融合
    return dest

def addWeightedSmallImgToLargeImgDstgshBLK(largeImg,alpha,smallImg,beta,sigma,gamma=0.0,regionTopLeftPos=(0,0)):
    "将小图像与大图像指定位置的内容融合,但对小图像透明部分单独处理,取大图像sigma的权重部分"
    srcW, srcH = largeImg.shape[1::-1]
    refW, refH = smallImg.shape[1::-1]
    x,y =  regionTopLeftPos
    if (refW>srcW) or (refH>srcH):
        #raise ValueError("img2's size must less than or equal to img1")
        raise ValueError(f"img2's size {smallImg.shape[1::-1]} must less than or equal to img1's size {largeImg.shape[1::-1]}")
    else:
        if (x+refW)>srcW:
            x = srcW-refW
        if (y+refH)>srcH:
            y = srcH-refH
        destImg = np.array(largeImg)
        tmpSrcImg = destImg[y:y+refH,x:x+refW]
        tmpImg = addWeightedDistinguishBLK(tmpSrcImg, alpha, smallImg, beta,sigma,gamma)
        destImg[y:y + refH, x:x + refW] = tmpImg
        return destImg

四、应用案例

4.1、两幅图像

大图像seaside.jpg:
在这里插入图片描述
小图像Lotus.JPG:

在这里插入图片描述

4.2、实现代码

addWeightedSmallImgToLargeImgDstgshBLK在opencvPublic模块中提供:

from opencvPublic import addWeightedSmallImgToLargeImgDstgshBLK,readImgFile
def main(largeImg,smallImg):
    information = "老猿Python博客文章目录:https://blog.csdn.net/LaoYuanPython/article/details/109160152,敬请关注同名微信公众号"

    img1 = readImgFile(largeImg, False) #自定义读入图片文件的函数,具体功能请参考:https://blog.csdn.net/LaoYuanPython/article/details/111351901
    img2 = readImgFile(smallImg, False)
    img = addWeightedSmallImgToLargeImgDstgshBLK(img1,1,img2,0.5,1)
    cv2.imwrite(r'f:\pic\addWeightedBlk.jpg',img)
    cv2.imshow('img',img)
    print(f"\n更多学习资料请参考:\n    {information}")
    cv2.waitKey(0)

main(r'f:\pic\seaside.JPG',r'f:\pic\lotus.JPG')

4.3、输出图像和程序运行信息

在这里插入图片描述

五、小结

本文介绍了一种区分前景、背景按不同权重进行图像融合的思路、具体实现及应用案例,这种模式对于需要融合图像中存在黑色背景的图像时能实现将黑色作为透明处理,达到将带黑色背景的前景部分融合到另外的图像,使得融合后的图像更自然。

更多OpenCV-Python的介绍请参考专栏《OpenCV-Python图形图像处理》相关文章。

关于老猿的付费专栏

老猿的付费专栏《使用PyQt开发图形界面Python应用》专门介绍基于Python的PyQt图形界面开发基础教程,付费专栏《moviepy音视频开发专栏》详细介绍moviepy音视频剪辑合成处理的类相关方法及使用相关方法进行相关剪辑合成场景的处理,两个专栏都适合有一定Python基础但无相关知识的小白读者学习。

付费专栏文章目录:《moviepy音视频开发专栏文章目录》、《使用PyQt开发图形界面Python应用专栏目录》。

对于缺乏Python基础的同仁,可以通过老猿的免费专栏《专栏:Python基础教程目录》从零开始学习Python。

如果有兴趣也愿意支持老猿的读者,欢迎购买付费专栏。

跟老猿学Python、学OpenCV!

☞ ░ 前往老猿Python博文目录

LaoYuanPython CSDN认证博客专家 Python专家 CSDN博客专家 博客之星季军
侥幸获得CSDN 2020博客之星季军,博客主要聚焦Python相关知识,包括Python、爬虫、PyQt图形界面开发、Moviepy音视频剪辑、OpenCV图形图像处理等方向,内容都是老猿零基础学习相关知识的总结,许多内容是深入研究、测试甚至源码分析后的成果,在官网和网上都没有。有独特之见的专栏主要包括PyQt、Moviepy、Python、OpenCV相关专栏,特别是PyQt、Moviepy以及OpenCV疑难问题相关的付费专栏。另外博客内容还涉及5G、区块链和人工智能数学基础等非Python领域。欢迎大家批评指正!

如有疑问,请在 老猿Python 微信公号提问。谢谢!
已标记关键词 清除标记
<p> <span style="color:#424242;font-size:14px;background-color:#FFFFFF;">基于</span><span style="color:#424242;">OpenCV</span><span style="color:#424242;font-size:14px;background-color:#FFFFFF;">最新版本</span><span style="color:#424242;">OpenCV4</span><span style="color:#424242;font-size:14px;background-color:#FFFFFF;">开始,从基础开始,详解</span><span style="color:#424242;">OpenCV</span><span style="color:#424242;font-size:14px;background-color:#FFFFFF;">核心模块</span><span style="color:#424242;">Core</span><span style="color:#424242;font-size:14px;background-color:#FFFFFF;">、</span><span style="color:#424242;">Imgproc</span><span style="color:#424242;font-size:14px;background-color:#FFFFFF;">、</span><span style="color:#424242;">video analysis</span><span style="color:#424242;font-size:14px;background-color:#FFFFFF;">核心</span><span style="color:#424242;">API</span><span style="color:#424242;font-size:14px;background-color:#FFFFFF;">与相关知识点,讲解从图像组成,像素操作开始,一步一步教你如何写代码,如何用</span><span style="color:#424242;">API</span><span style="color:#424242;font-size:14px;background-color:#FFFFFF;">解决实际问题,从图像处理到视频分析,涵盖了计算机视觉与</span><span style="color:#424242;">OpenCV4</span><span style="color:#424242;font-size:14px;background-color:#FFFFFF;">中主要模块的相关知识点,穿插大量工程编程技巧与知识点与案例,全部课程的</span><span style="color:#424242;">PPT</span><span style="color:#424242;font-size:14px;background-color:#FFFFFF;">课件与源码均可以下载。部分课程内容运行截图:</span> </p> <p> <span style="color:#424242;font-size:14px;background-color:#FFFFFF;"><img src="https://img-bss.csdn.net/201905270151327319.png" alt="" /><br /></span> </p> <p> <span style="color:#424242;font-size:14px;background-color:#FFFFFF;"><img src="https://img-bss.csdn.net/201905270151199926.png" alt="" /><br /></span> </p> <p> <span style="color:#424242;font-size:14px;background-color:#FFFFFF;"><img src="https://img-bss.csdn.net/201905270143028023.png" alt="" /><br /></span> </p> <p> <span style="color:#424242;font-size:14px;background-color:#FFFFFF;"><img src="https://img-bss.csdn.net/201905270143153426.png" alt="" /><br /></span> </p> <p> <span style="color:#424242;font-size:14px;background-color:#FFFFFF;"><img src="https://img-bss.csdn.net/201905270143373800.png" alt="" /><br /></span> </p> <p> <span style="color:#424242;font-size:14px;background-color:#FFFFFF;"><img src="https://img-bss.csdn.net/201905270143508281.png" alt="" /><br /></span> </p> <p> <span style="color:#424242;font-size:14px;background-color:#FFFFFF;"><img src="https://img-bss.csdn.net/201905270147189339.png" alt="" /><br /></span> </p> <p> <span style="color:#424242;font-size:14px;background-color:#FFFFFF;"><img src="https://img-bss.csdn.net/201905270147595785.png" alt="" /><br /></span> </p>
相关推荐
©️2020 CSDN 皮肤主题: 酷酷鲨 设计师:CSDN官方博客 返回首页
实付 9.90元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值