使用OpenCV实现抠图

        在图像处理中,抠图(也称为图像分割或前景提取)是一项非常重要的技术,它允许我们从复杂背景中提取出感兴趣的对象。OpenCV(Open Source Computer Vision Library)是一个强大的计算机视觉库,提供了丰富的工具来实现这一目标。本文将详细介绍如何使用OpenCV来实现简单的抠图功能。

1.最终效果展示:

2.实现思路:

1.加载logo图片
2.找出轮廓
    - 将原图(RGB)转换为灰度图logo_gray
    - 将灰度图转换为二值图logo_binary
    - 通过二值图查找轮廓,使用cv2.findContours()函数找出轮廓
3.绘制轮廓
    - 背景选择 原图 灰度图
    - 背景是黑色填充白色
4.将颜色对应位置进行替换

1. 加载logo图片

首先,我们需要加载包含logo的原始图片。这通常是一个RGB图像,包含了丰富的颜色信息。

2. 找出轮廓

为了从背景中分离出logo,我们需要找到logo的轮廓。这通常涉及以下几个步骤:

  • 将原图(RGB)转换为灰度图:这一步是为了减少图像中的颜色信息,使其更易于处理。
  • 将灰度图转换为二值图:通过设定一个阈值,将灰度图像转换为仅包含黑白两种颜色的二值图像。这一步有助于更清晰地定义前景和背景。
  • 通过二值图查找轮廓:使用cv2.findContours()函数在二值图像上查找轮廓。这个函数会返回图像中所有轮廓的坐标点集。

3. 绘制轮廓

找到轮廓后,我们可以选择在不同的背景上绘制它们。但在这个抠图的上下文中,绘制轮廓更多是为了验证轮廓的准确性,而不是最终的目的。不过,为了展示效果,我们可以:

  • 在原图或灰度图上绘制轮廓:这有助于我们直观地看到哪些部分被识别为前景。
  • 在黑色背景上填充白色轮廓:这实际上并不是抠图的直接步骤,但它可以模拟抠图后的效果,即前景对象被单独提取出来。

4. 将颜色对应位置进行替换

真正的抠图步骤涉及到将原图中属于前景对象的像素颜色保留,而将背景像素替换为透明或特定颜色。然而,OpenCV标准库直接处理图像透明度(alpha通道)的能力有限。因此,通常的做法是创建一个与原图大小相同的遮罩(mask),其中前景对象区域为白色(或特定值),背景区域为黑色。然后,可以使用这个遮罩与原图进行位运算(如按位与操作),从而得到抠图后的结果。但这里为了简化说明,我们主要关注轮廓的提取和绘制。

3.项目完整代码:

import cv2
import numpy as np

def get_mask():
    # 读取logo
    logo = cv2.imread("logo.jpg")
    # 将原图(RGB)转换为灰度图logo_gray
    logo_gray = cv2.cvtColor(logo, cv2.COLOR_BGR2GRAY)
    # 将灰度图转换为二值图logo_binary
    # 实现思路:大于大于某个阈值就是255,反之小于阈值就是0
    # 参数1:被转换为图像(灰度图)
    # 参数2:阈值
    # 参数3:大于阈值就是255,反之小于阈值就是0
    # 参数4:阈值类型cv2.THRESH_BINARY
    # 参数5:cv2.THRESH_OTSU
    retval, logo_binary = cv2.threshold(logo_gray, 100, 255, cv2.THRESH_BINARY+cv2.THRESH_OTSU)
    # 查找轮廓
    # 参数1:被查找的图像
    # 参数2:轮廓存放的层级关系
    # 参数3:CHAIN_APPROX_NONE:轮廓逼近方法
    contours, hierarchy = cv2.findContours(logo_binary, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)
    # 生产背景为黑色的图像
    mask = np.zeros_like(logo_binary)
    # 方式1:使用循环
    # 方式2:使用切片
    # 绘制轮廓
    cv2.drawContours(mask, contours, 1, color=255, thickness=-1)
    print(f"retval:{retval}")
    return mask
def img_original(img, mask, logo):
    m_h, m_w = mask.shape
    for h in range(m_h):
        for w in range(m_w):
            if(mask[h, w] == 255):
                img[h, w+50] = logo[h, w]
    return img

if __name__ == '__main__':
    # 读取图像
    logo = cv2.imread("logo.jpg")
    img1 = cv2.imread("img1.jpg")
    # 显示图像
    mask = get_mask()
    img = img_original(img1, mask, logo)
    cv2.imshow("image", img)
    cv2.waitKey(0)
    cv2.destroyAllWindows()

4.总结:

        本文介绍了使用OpenCV实现抠图的基本思路,包括加载图片、找出轮廓、绘制轮廓以及模拟抠图效果。然而,真正的抠图可能需要更复杂的处理,如使用图像分割算法、深度学习模型等,以更准确地从背景中分离出前景对象。此外,处理透明度和alpha通道通常需要借助专门的图像处理软件或库。希望本文能为初学者提供一个入门级的抠图实现示例。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值