02-更换证件背景

发布于:2025-07-03 ⋅ 阅读:(26) ⋅ 点赞:(0)

一、背景

生活中,有的时候我们需要不同颜色的背景图片,电子档或者打印出的图片。当我们手上正好有某一种背景颜色的图片,却又不想花钱去打印店拍摄照片时,我们就会通过ps等工具进行颜色背景的替换,然而对于手残党的我们却始终无法很好的抠图。此时,我们就会希望有一个好的工具替我们来完成背景替换操作,于是乎,小妖就来教大家一个怎么完成颜色背景和前景融合的方法。

二、说明

2.1. 接口调用说明

我们引入的是removebg的api接口,所以每月会有次数限制(remove.bg官网上写的是一个月50次,基本够我们使用),嫌麻烦的话可以直接去removebg的官网进行抠图替换背景,这里只是帮助大家一起了解一下如何通过python+opencv的程序来实现。
在这里插入图片描述

2.2 API key获取位置

在这里插入图片描述

三、实现代码

import os
import numpy as np
import cv2
from typing import List
from removebg import RemoveBg as RmBg

"""
移除图片背景,并替换成纯色背景
"""


class RemoveImgBg:
    # 换成自己的api key,每月有50次调用机会
    API_KEY = "xxxxx"

    def __init__(self, file_name, error_log_file="error.log"):
        # 传入的图片名
        self.src_img = file_name
        # 生成的图片名
        self.des_img = ""
        # 移除背景时,调用api报错
        self.error_log_file = error_log_file

    def rm_bg(self):
        """
        移除图片的背景
        :return:
        """
        rmbg = RmBg(self.API_KEY, self.error_log_file)
        rmbg.remove_background_from_img_file(self.src_img)

    def rename_no_bg_img(self):
        """
        重命名接口返回的图片名
        :return:
        """
        src_img_name = f"{self.src_img}_no_bg.png"
        dest_img_name = f"{self.src_img.split('.')[0]}_no_bg.png"
        if os.path.exists(src_img_name):
            os.rename(src_img_name, dest_img_name)
            self.des_img = dest_img_name
        else:
            if os.path.exists(dest_img_name):
                self.des_img = dest_img_name

    def change_bg_color(self, color: List[int], file_name: str):
        """
        给图片的添加上纯色
        :param color:
        :param file_name:
        :return:
        """
        # 读取png图片, -1代表获取alpha通道
        fore_image = cv2.imread(self.des_img, -1)
        # 拆分png的4个通道
        b, g, r, a = cv2.split(fore_image)
        # 图片的高, 宽
        rows = fore_image.shape[0]
        cols = fore_image.shape[1]
        # 得到PNG图像前景部分,在这个图片中就是除去 Alpha通道的部分
        foreground = cv2.merge((b, g, r))
        # 得到PNG图像的alpha通道,即alpha掩模
        alpha = cv2.merge((a, a, a))
        img = np.ones((rows, cols), dtype=np.uint8)
        # 新建一个图层,默认为单通道图层
        background = cv2.cvtColor(img, cv2.COLOR_GRAY2BGR)  # 将单通道转化成3通道Mat
        # 设置背景图层的颜色
        background[:, :, 0] = color[0]
        background[:, :, 1] = color[1]
        background[:, :, 2] = color[2]
        # 因为下面要进行乘法运算故将数据类型设为float,防止溢出
        foreground = foreground.astype(float)
        background = background.astype(float)
        # 将alpha的值归一化在0-1之间,作为加权系数
        alpha = alpha.astype(float) / 255
        # 将前景和背景进行加权,每个像素的加权系数即为alpha掩模对应位置像素的值,前景部分为1,背景部分为0
        # 采用了正片叠底的方法 即 任何像素与黑色相乘为黑色,与白色相乘不变
        # 公式: 混合色 * 基色 / 255
        foreground = cv2.multiply(alpha, foreground)  # 此时即相当于原图的png,黑色背景,混合色为(0~1)
        background = cv2.multiply(1 - alpha, background)  # 背景图去除前景的部分为黑色,其它部分为背景色偏暗
        out_image = foreground + background
        # """测试时, opencv的imshow函数在显示double,对其认为是0~1,而大于1的地方都为白色,所以需要除以255"""
        # cv2.imshow("outImage", out_image / 255)
        # cv2.waitKey(0)
        cv2.imwrite(file_name, out_image)

    def run(self):
        # self.rm_bg()
        self.rename_no_bg_img()
        # [255, 255, 255]为替换的纯色(rgb,每一个颜色值为0-255)
        # xxxx.jpg 为生成的图片名
        self.change_bg_color([0, 124, 255], "xxxx.jpg")


if __name__ == '__main__':
    # 需要移除背景的图片
    remove_bg = RemoveImgBg("xxx.jpg")
    remove_bg.run()



四、生成的结果(动漫)

4.1 原图:

在这里插入图片描述

4.2 移除背景图

在这里插入图片描述

4.3 填充纯色图片

在这里插入图片描述

四、生成的结果(人像)

4.1 原图

在这里插入图片描述

4.2 移除背景图

在这里插入图片描述

4.3 填充纯色图片

在这里插入图片描述

五、补充说明

纯色填充的值为rgb,具体想要替换颜色值小伙伴们可以自行搜索,或者通过颜色提取工具提取


网站公告

今日签到

点亮在社区的每一天
去签到