昨天更新了一个去黑色背景的文章,今天发现可以再适用范围上推广一下,前提是知道背景色的RGB值。
Python对带光晕的图像进行去黑底黑色背景操作(附源码)
先上效果图
除了纯白会导致透明度异常,纯红导致光晕颜色改变和范围减小(原图接近红色),其他效果都很好。这里重新描述下问题,目标函数比较复杂就不写出来了。
这个问题我暂时找不到解析方法,但是通过观察目标函数的单调性,在部分情况下找到一组效果比较好的解,对于明度比较低的背景、明度比较高的图案适用性较好
话不多说,源码奉上
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))