修改图片背景+抠图+合成banner

========================================================================================
官网介绍(飞桨)paddlehub
https://www.paddlepaddle.org.cn/
https://www.paddlepaddle.org.cn/tutorials/projectdetail/520792

前置条件

在使用PaddleHub之前,用户需要完成如下任务:

  1. 安装Python:对于Linux或MAC操作系统请安装3.5或3.5以上版本;对于Windows系统,请安装3.6或3.6以上版本。
  2. 安装飞桨1.8版本,具体安装方法请参见快速安装
  3. 安装PaddleHub 1.7或以上版本。
---------------
python -m pip install paddlepaddle-gpu -i https://mirror.baidu.com/pypi/simple
----------------
安装方式 by lin
C:\Python27\Scripts>pip install paddlepaddle-gpu -i https://mirror.baidu.com/pypi/simple
C:\Python27\Scripts>pip install --upgrade paddlepaddle -i https://mirror.baidu.com/pypi/simple
C:\Python27\Scripts>pip install --upgrade paddlehub -i https://mirror.baidu.com/pypi/simple
========================================================================================

from PIL import Image
im = Image.open('11.png')
print im.format, im.size, im.mode
#输出 PNG (203, 193) RGBA
#更改分辨率大小
im = im.resize((960,448),Image.ANTIALIAS)
im.save('out/12.png',dpi=(200.0,200.0))

========================================================================================

利用百度 PaddlePaddle 平台的 PaddleHub 工具实现一键抠图,结合 opencv 等工具进行视频合成创作。
本视频为2.0版本,相比于第一版,自认为还是有所提升的。。。。。
1.0版本链接如下: AI人像抠图及视频合成:让你体验复仇者联盟的终局之战
全套代码:
# 首先安装所需的包
# pip install paddlehub==1.6.0 -i https://pypi.tuna.tsinghua.edu.cn/simple
# pip install moviepy -i https://pypi.tuna.tsinghua.edu.cn/simple
# 这里指定从清华源下载,速度快


import cv2
from PIL import Image
import numpy as np
import os
import paddlehub as hub
from moviepy.editor import *

# 从视频提取图片
def video2img(video_path, out_path):
cap = cv2.VideoCapture(video_path)
i=1
while True:
ret, frame = cap.read()
if frame is None:
break
else:
cv2.imwrite(out_path + str(i) + ".jpg", frame)
i+=1
return

# 抠图
def img2seg(img_path, out_path):
# load model
module = hub.Module(name="deeplabv3p_xception65_humanseg")
# config
test_img_path = [os.path.join(img_path, f_name) for f_name in os.listdir(img_path)]
input_dict = {"image": test_img_path}

results = module.segmentation(data=input_dict, output_dir=out_path)

# 合成图片
def blend_images(fore_image, base_image, out_path, img_num):
# def blend_images(fore_image, base_image):
"""
将抠出的人物图像换背景
fore_image: 前景图片,抠出的人物图片
base_image: 背景图片
"""
# 读入图片
base_image = Image.open(base_image).convert('RGB')
fore_image = Image.open(fore_image).resize(base_image.size)

# 图片加权合成
scope_map = np.array(fore_image)[:, :, -1] / 255
scope_map = scope_map[:, :, np.newaxis]
scope_map = np.repeat(scope_map, repeats=3, axis=2)
res_image = np.multiply(scope_map, np.array(fore_image)[:, :, :3]) + np.multiply((1 - scope_map),
np.array(base_image))

# 保存图片
res_image = Image.fromarray(np.uint8(res_image))
f_name = str(img_num) + ".jpg"
res_image.save(os.path.join(out_path, f_name))

# 把图片合成视频
def img2video(img_path, org_video_path, out_path):
# 查看原始视频的参数
cap = cv2.VideoCapture(org_video_path)
ret, frame = cap.read()
height = frame.shape[0]
width = frame.shape[1]
fps = cap.get(cv2.CAP_PROP_FPS) # 返回视频的fps--帧率

# 把参数用到我们要创建的视频上
video = cv2.VideoWriter(out_path, cv2.VideoWriter_fourcc('m', 'p', '4', 'v'), fps, (width, height)) # 创建视频流对象
"""
参数1 即将保存的文件路径
参数2 VideoWriter_fourcc为视频编解码器 cv2.VideoWriter_fourcc('m', 'p', '4', 'v') 文件名后缀为.mp4
参数3 为帧播放速率
参数4 (width,height)为视频帧大小
"""

# 获取图片总数
file_list = os.listdir(img_path)
img_num = len(file_list)

for i in range(img_num):
f_name = str(i + 1) + '.jpg'
item = os.path.join(img_path, f_name)
img = cv2.imread(item) # 使用opencv读取图像,直接返回numpy.ndarray 对象,通道顺序为BGR ,注意是BGR,通道值默认范围0-255。
video.write(img) # 把图片写进视频
video.release() # 释放

# 从原始视频上提取声音合成到新生成的视频上
def sound2video(org_video_path, new_video_path, out_video_path):
# 读取原始视频
video_o = VideoFileClip(org_video_path)
# 获取原始视频的音频部分
audio_o = video_o.audio

# 读取新生成视频
video_clip = VideoFileClip(new_video_path)
# 指向新生成视频的音频部分
video_clip2 = video_clip.set_audio(audio_o)
# 修改音频部分并输出最终视频
video_clip2.write_videofile(out_video_path)

# Config
# 人物视频地址
human_video_path = './a.mp4'
# 背景视频地址
back_video_path = './b.mp4'
# 提取人物视频图像的存放地址
human_video_img_path = './human_video_img/'
# 提取背景视频图片的存放地址
back_video_img_path = './back_video_img/'
# 抠图后存放地址
human_img_seg_path = './human_img_seg/'
# 人物和背景合成后图片存放地址
blend_img_path = './blend_img/'
# 合成视频存放地址
img2video_path = './c.mp4'
# 添加声音后的视频最终输出地址
out_video_path = './d.mp4'

if __name__ == "__main__":

# 第一步:人物视频->人物图像
if not os.path.exists(human_video_img_path):
os.mkdir(human_video_img_path)
video2img(video_path=human_video_path, out_path=human_video_img_path)

# 第二步:抠图
if not os.path.exists(human_img_seg_path):
os.mkdir(human_img_seg_path)
img2seg(img_path=human_video_img_path, out_path=human_img_seg_path)

# 第三步:背景视频->背景图片
if not os.path.exists(back_video_img_path):
os.mkdir(back_video_img_path)
video2img(video_path=back_video_path, out_path=back_video_img_path)

# 第四步:抠图+背景图片->合成
if not os.path.exists(blend_img_path):
os.mkdir(blend_img_path)
# 由于人物视频长度和背景视频长度可能不同,所以要以短的为准
if len(os.listdir(human_img_seg_path)) < len(os.listdir(back_video_img_path)):
img_num = len(os.listdir(human_img_seg_path))
else:
img_num = len(os.listdir(back_video_img_path))
# 对所有图片按顺序合成
for i in range(img_num):
blend_images(base_image=back_video_img_path+str(i+1)+'.jpg', fore_image=human_img_seg_path+str(i+1)+'.png',
out_path=blend_img_path, img_num=i+1)

# 第五步:合成视频
if not os.path.exists(img2video_path):
img2video(img_path=blend_img_path, org_video_path=human_video_path, out_path=img2video_path)
else:
print('视频已存在,请查看输出路径')

# 第六步:加上音频
if not os.path.exists(out_video_path):
sound2video(org_video_path=human_video_path, new_video_path=img2video_path, out_video_path=out_video_path)
else:
print('最终视频已存在,请查看输出路径')
————————————————
版权声明:本文为CSDN博主「AItrust」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_42067550/article/details/105457679

=================================== API 抠图 开始 =======================================
# -*- coding:utf-8 -*-

from PIL import Image, ImageDraw, ImageFont

# https://blog.csdn.net/qq_42067550/article/details/105457679
# 底图添加字体文本

from removebg import RemoveBg
#lin_268.foxmail q4
rmbg=RemoveBg('VCgq72M9jATsj1sKcRwdZk1y','error.log')
# rmbg.remove_background_from_img_file('3.jpg')

#changebg: 调用PIL添加背景颜色
def changebg(img,color):
#option = input("pls input your taget img type, A:red B:bule C:white D:justremovebg: \n")
color_dict = {"A":(255,0,0),"B":(67,142,219),"C":(255,255,255)}
im = Image.open(img)
x,y =im.size
try:
p = Image.new('RGBA', im.size,color=color_dict.get(color))
p.paste(im,(0, 0, x, y), im)
p.save('3_new.png')
# p.save('{}.png'.format('new'+color))
except:
print('changebg err')
pass

changebg('3.jpg_no_bg.png','C')
==========================================================================

OSError: cannot write mode RGBA as JPEG

原因:RGBA意思是红色,绿色,蓝色,Alpha的色彩空间,Alpha指透明度。而JPG不支持透明度,所以要么丢弃Alpha,要么保存为.png文件
  •  改变图片尺寸及分辨率(dpi):
from PIL import Image
#调整大小和分辨率(dpi)
im = Image.open('2.1.bmp')
im = im.resize((18897,9448),Image.ANTIALIAS)
im.save('2.1.jpg',dpi=(200.0,200.0))

代码中的尺寸单位为像素,分辨率为dpi,即一英寸内有多少像素点

 

下载的图标背景为透明的,想把它变为白底图片

from PIL import Image
im = Image.open('question.png')
#im = im.resize((40, 40),Image.ANTIALIAS) 
x,y = im.size
try:
    # 使用白色来填充背景 from:www.outofmemory.cn
    # (alpha band as paste mask).
    p = Image.new('RGBA', im.size, (240,240,240))
    p.paste(im, (0, 0, x, y), im)
    p.save('question.bmp')
except:
    pass
posted @ 2021-09-14 23:10  也许明天  阅读(411)  评论(0编辑  收藏  举报