前言 今天在群里看到小伙伴们需要批量对班级的同学进行照片换底色,目前市面上网页中存在在线换底色的网站,但是普遍需要收费或者七七八八的条件,搞得很繁琐,所以我就想写一个自动化换底色的程序来试试可不可以实现。
一看到照片换底,我首先想到的思路就是先想办法把照片的背景抠掉,类似于PS的抠图技巧,然后对目标像素点进行填充,重新生成新的图片保存就可以。
开发 照片抠图 一张证件照,可以简单的分为底色和人像,所以我搜索了一下,发现了一个库paddlehub
中有一个 deeplabv3p_xception65_humanseg
模型,是图像分割,已经训练完毕,我直接采用,然后试着对图像进行抠图,然后~,就出现了这种情况。
很尬尴,图像全部反了,我调试了半天没整出来,知道了大概的原理,我就试着找找有没有已经做的比较好的抠图模型让我直接用,于是乎,我发现了这个宝藏——在线抠图网站 ,很像,抠图的效果还不错,大概是这样,由于隐私问题我打了马赛克,他的背景图已经被抠掉了,有官方文档,直接使用,但是每个月只有50次免费机会,不过足够使用啦。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 def imageClipping (path ): try : old = './photo/' + path new = './temporary/' + path[:-4 ] + '.png' response = requests.post( 'https://api.remove.bg/v1.0/removebg' , files={'image_file' : open (old, 'rb' )}, data={'size' : 'auto' }, headers={'X-Api-Key' : 'D4kSvWb14svjr6xUHUA7m7po' }, ) if response.status_code == requests.codes.ok: with open (new, 'wb' ) as out: out.write(response.content) return 'success' else : print("Error:" , response.status_code, response.text) return 'error' except : return 'error
基于图片的灰度化处理及上色 抠好的图保存到自己指定的路径中,然后就可以给图片上色了,我们使用Pillow对图片上色,对于已经抠好的图,可以指定不同颜色进行上色。
1 2 3 4 5 6 7 8 9 color = 'red' no_bg_image = Image.open (no_bg_image_path) x, y = no_bg_image.size new_image = Image.new('RGBA' , no_bg_image.size, color=color) new_image.paste(no_bg_image, (0 , 0 , x, y), no_bg_image)
给他们打上浓浓的马赛克认不出来了吧,这是对已经抠像的图片进行的上色处理,颜色可以自己调整,非常方便。
运行程序 运行的程序部分截图,可以进行批量化的操作
完整的程序运行效果:
程序完整代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 import osfrom PIL import Imageimport requestsimport timeimport jsondef get_image (): global password_count password_count = 0 with open ('./config.json' ) as file_json: config=json.load(file_json) for item in os.listdir('./photo' ): print("----正在裁剪[%s]背景色----" %(item)) for items in config['data' ]: if (items['status' ] == 1 ): password_count += 1 else : break res=imageClipping(item,config['data' ][password_count]['password' ]) if res == 'success' : print("[%s]裁剪成功" %(item)) os.remove('./photo/' +item) else : print("[%s]裁剪失败" %(item)) time.sleep(1 ) def imageClipping (path,password ): try : old = './photo/' + path new = './temporary/' + path[:-4 ] + '.png' response = requests.post( 'https://api.remove.bg/v1.0/removebg' , files={'image_file' : open (old, 'rb' )}, data={'size' : 'auto' }, headers={'X-Api-Key' : password}, ) if response.status_code == requests.codes.ok: with open (new, 'wb' ) as out: out.write(response.content) return 'success' else : print("Error:" , response.status_code, response.text) return 'error' except : return 'error' def replaceImage (color = 'red' ): for item in os.listdir('./temporary' ): try : no_bg_image_path = './temporary/' +item no_bg_image = Image.open (no_bg_image_path) x, y = no_bg_image.size new_image = Image.new('RGBA' , no_bg_image.size, color=color) new_image.paste(no_bg_image, (0 , 0 , x, y), no_bg_image) new_image.save('./new_photo/' +item) print("[%s]换底成功,颜色变更为:[%s]" %(item,color)) except : print("[%s]换底失败" % (item)) continue print("--------------照片已完成转换---------" ) def main (color ): get_image() print("图像已裁剪完成,正在更换目标底色" ) replaceImage(color) if __name__ == '__main__' : with open ('./config.json' ) as file_json: config=json.load(file_json) print(config['data' ][0 ]) while (1 ): print(""" ------------------自动化证件照底色更换工具--------------------- ------------------ 作者:小健 ---------------------- ------------------ 注意事项 ---------------------- ------------请将需要更换的图片放置[photo]文件夹中--------------- ------------生成后的图片位置:[new_photo]文件夹中---------------- ------------抠图后的人像文件位于:[temporary]文件夹-------------- ------------如需需要,则保存,否则建议删除 --------------------- """ ) item = input ("1.照片底色更换 2.清空temporary\n" ) if (item == '1' ): while (1 ): color = input ("输入选项需要的底色:1.红色 2.蓝色 3.白色 4.上一级\n" ) if (color == '1' ): main('red' ) break elif (color == '2' ): main('blue' ) break elif (color == '3' ): main('white' ) break elif (color == '4' ): break else : print("输入有误,请重新选择" ) continue
结尾 写完运行的效果还不错,在几分钟内就可以完成近百张的图像底色更换,代码比较粗糙,可以继续优化、在线化、自动化及桌面化,所以我懒死了,后续有空在调整吧,得去刷网课了。
代码已上传Github:证件照、图像化的自动化换色
欢迎技术交流沟通!