Python对带光晕的任意纯色背景图像进行去背景色操作(保留透明效果、附源码)

昨天更新了一个去黑色背景的文章,今天发现可以再适用范围上推广一下,前提是知道背景色的RGB值。

Python对带光晕的图像进行去黑底黑色背景操作(附源码)

先上效果图

Python对带光晕的任意纯色背景图像进行去背景色操作(保留透明效果、附源码)_第1张图片

 除了纯白会导致透明度异常,纯红导致光晕颜色改变和范围减小(原图接近红色),其他效果都很好。这里重新描述下问题,目标函数比较复杂就不写出来了。

Python对带光晕的任意纯色背景图像进行去背景色操作(保留透明效果、附源码)_第2张图片

Python对带光晕的任意纯色背景图像进行去背景色操作(保留透明效果、附源码)_第3张图片

 这个问题我暂时找不到解析方法,但是通过观察目标函数的单调性,在部分情况下找到一组效果比较好的解,对于明度比较低的背景、明度比较高的图案适用性较好

Python对带光晕的任意纯色背景图像进行去背景色操作(保留透明效果、附源码)_第4张图片

 话不多说,源码奉上

import numpy as np
from PIL import Image
import os

def RemoveBackground(input_path:str,file_name:str,output_path:str,BG_color:np.array):
    #print(BG_color)
    target_im = Image.open(os.path.join(input_path,file_name))
    target_im = target_im.convert('RGBA')
    target_img_array = np.array(target_im)
    _BG_color = BG_color.reshape([-1,1,3])
    _BG_color = np.ones(target_img_array[:,:,:3].shape)*_BG_color
    
    #对背景色亮度高于前景色的区域进行反相
    pos = np.where(np.max((target_img_array[:,:,:3]-_BG_color),axis=2)<=0)
    _BG_color[pos] = 255 - _BG_color[pos]
    target_img_array[pos[0],pos[1],:3] = 255 - target_img_array[pos[0],pos[1],:3]

    #透明度
    target_img_Alpha = np.max((target_img_array[:,:,:3]-_BG_color)/(255+1e-7-_BG_color),axis=2)
    target_img_array[:,:,3] = target_img_Alpha*255
    target_img_Alpha = target_img_Alpha.reshape([target_img_array.shape[0],-1,1])
    

    target_img_array[:,:,:3] = np.minimum(_BG_color + (target_img_array[:,:,:3]-_BG_color)/target_img_Alpha,255)
    #恢复反相
    target_img_array[pos[0],pos[1],:3] = 255 - target_img_array[pos[0],pos[1],:3]

    res_img = Image.fromarray(target_img_array)
    #res_img.show()
    if not file_name.endswith(".png"):
        res_img.save(os.path.join(output_path,file_name[:-4]+".png"))
    else:
        res_img.save(os.path.join(output_path,file_name))

 

你可能感兴趣的:(python,图像处理)