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博文目录
  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
非常好的问题!我可以告诉你一些关于使用opencv-python进行图像处理的基本知识。 首先,确保你已经安装了opencv-python库。你可以使用以下命令在Python中安装它: ``` pip install opencv-python ``` 导入库后,你可以开始处理像。下面是一个简单的例子,展示了如何读取、显示和保存像: ```python import cv2 # 读取像 image = cv2.imread('image.jpg') # 显示像 cv2.imshow('Image', image) cv2.waitKey(0) # 保存像 cv2.imwrite('image_output.jpg', image) ``` 在这个例子中,`imread`函数用于从文件中读取像。`imshow`函数用于显示像,`waitKey`函数可以等待按键输入。最后,`imwrite`函数用于将像保存到文件中。 除了基本操作,opencv-python还提供了许多图像处理函数,如像缩放、旋转、裁剪、滤波、边缘检测等。下面是一个简单的例子,展示了如何进行像缩放和灰度转换: ```python import cv2 # 读取像 image = cv2.imread('image.jpg') # 缩放像 resized_image = cv2.resize(image, (800, 600)) # 灰度转换 gray_image = cv2.cvtColor(resized_image, cv2.COLOR_BGR2GRAY) # 显示像 cv2.imshow('Resized Image', resized_image) cv2.imshow('Gray Image', gray_image) cv2.waitKey(0) ``` 在这个例子中,`resize`函数用于缩放像,`cvtColor`函数用于将像转换为灰度像。 希望这些例子能帮助你入门opencv-python图像处理!如果你有更具体的问题,欢迎继续提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

LaoYuanPython

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值