文章目录
AI虚拟主播
💯AI虚拟主播
随着人工智能技术的不断进步,AI虚拟主播正逐渐成为内容创作领域的一大热点。通过AI技术生成的虚拟形象不仅能够高度还原真人的外观,还能够与观众进行互动,提供更加个性化的内容体验。无论是在广告宣传、教育培训,还是在直播与社交平台上,AI虚拟主播都展现出了巨大的潜力。本文将带你进行一次初步探索,感受AI虚拟主播的魅力。通过使用AI绘画工具生成逼真的数字人形象,并借助D-ID等平台让这些静态的形象“活”起来。
💯使用AI绘画工具生成数字人
首先,我们要使用AI绘画工具为我们生成一个虚拟的数字人形象,这种数字人会非常接近真人的形象。这里使用的AI绘画工具比较推荐Midjourney,如果没有Midjourney也没关系,还会推荐一款在线网页版的文生图的国内AI网站也可生成数字人,供我们使用。
补充:D-ID内也可直接生成数字人形象。
借助GPT生成数字人所需的提示词
首先我们要去构思如何编写创建数字人形象的提示词,我们通常会设定一些条件,比如他所从事的行业、年龄范围以及五官的具体特征等。这些设定有助于生成一个更符合我们需求的虚拟形象。
- 以下是一些参数可以参考:
参数 | |
---|---|
基础 | 国家、身份(学生/上班族/明星/网红/女装模特)、年龄 |
容貌 | 面部(眼睛/鼻子/嘴巴/脸型)、肤色、身材、追加附魔词 |
服装 | 面部(眼睛/鼻子/嘴巴/脸型)、肤色、身材、追加附魔词 |
场景 | 地点、时间、天气、光线 |
摄影 | 现实、人像摄影、构图 (占比) |
动作 | 默认也可以设定 |
比例 | 9:16或3:4宽高比 |
- 这里提供一个现成模板用于测试
中国、网红
女明星,五官立体,身材好,
白色连衣裙
街拍,购物街道,
索尼,85mm
走路,
9:16
- 可以让AI为我们生成提示词
现在你是一名基于输入描述的提示词生成器,你会将我输入的自然语言想象为完整的画面生成提示词。请注意,你生成后的内容服务于一个绘画AI,它只能理解具象的提示词而非抽象的概念。我将提供简短的中文描述,生成器需要为我提供准确的提示词,必要时优化和重组以提供更准确的内容,也只输出翻译后的英文内容。
请模仿示例的结构生成完美的提示词。
示例输入:“一个坐在路边的办公室女职员”
示例输出:1 girl, office lady, solo, 16yo,beautiful detailed eyes, light blush, black hair, long hair, mole under eye, nose blush , looking at viewer, suits, white shirt, striped miniskirt, lace black pantyhose, black heels, LV bags,
thighhighs,sitting, street, shop border, akihabara , tokyo, tree, rain, cloudy, beautifully detailed background, depth of field, loli, realistic, ambient light, cinematic composition, neon lights, HDR, Accent Lighting, pantyshot, fish eye lens.
请仔细阅读我的要求,并严格按照规则生成提示词,如果你明白了,请回复"我准备好了",当我输入中文内容后,请生成我需要的英文内容。注意,英文连着写,不要标序号。
Chinese celebrity, internet star, female, detailed facial features, attractive body, white dress, street photography, shopping street, Sony 85mm lens, walking, realistic, urban background, fashion, vibrant colors, natural lighting, candid moment. --ar 9:16
方案一:使用Midjourney生成数字人
- 向Midjourney输入上一步GPT给我们生成的提示词
- 放大我们需要的那张图,保存到本地。
方案二:使用TensAI生成数字人
如果没有Midjourney,可先使用这个国内的AI工具,使用在线文生图功能:
TensAI:https://tensai.tenclass.com/?invite_code=4fdhLK
-
选择文生图功能,工具勾选M-J-P生成人像效果更佳。
-
接着跟Midjourney一样输入提示词
-
生成后找一张适合的进行放大
-
保存到本地。
- 注意:以上是列举了两个相对容易上手的AI绘画工具,分别是Midjourney和TensAI,用于生成数字人图像。当然,除了这两个工具外,其他AI绘画工具也同样适用,例如Stable Diffusion等。选择哪种工具取决于你的具体需求和使用习惯,每种工具都有其独特的功能和优势,灵活选择能够帮助你更好地实现创作目标。
补充方案三:在D-ID内直接生成数字人
- 写到一半才发现D-ID原来也可以在线生成数字人。
- 生成速度挺快的,效果也不错,这样子方便很多。
💯使用D-ID生成数字人视频
- 在生成了逼真的数字人图像后,下一步就是让这些静态的图片形象“活”起来。这时,我们可以借助D-ID来实现这一目标。D-ID 是一款先进的AI技术平台,它能够将静态的图像转化为生动的面部动画和视频。通过D-ID,你可以为你的数字人赋予逼真的表情和语音,让他们看起来更具生命力。
D-ID:https://www.d-id.com/
D-ID注册与消耗积分说明
- 这里我们需要注册一下才能使用图片转视频功能
- 注册过程就不详细介绍了。
-
这个网站都是英文,所以开启了Google翻译。
-
注意:D-ID每个账号注册后有20个免费积分,每个代理会话消耗1个积分,生成每一分钟视频消耗4个积分(15s视频消耗1积分)。
-
理论上来说,如果你拥有多个邮箱,可以不断注册新账号,这样就能够持续获得免费积分,从而使点数几乎用不完。
D-ID 让数字人“活”起来
- 点击创建视频
- 点击上传我们的AI数字人图像
- 可选择视频中数字人所表现的情绪和整个形象所在位置
- 可以为数字人选择不同地区的语言,甚至是方言,并根据需要调整音色。此外,平台还支持根据你提供的音频样本进行声音模仿。
- 在脚本处可以输入数字人视频中说的话,还可以调整说话风格、语速
- 可以提供本地音频供AI模仿
- 还可以选择自定义视频中数字人所处的背景,但应该是类似PS的图层,是需要先将数字人抠图才能完美融合背景。
- 可在视频中自定义位置加上文字,类似水印
- 还可自定义文字信息。
- 可对生成视频自定义命名
- 生成成功后可以保存在本地
正如文章开头展示的:
AI虚拟主播
💯小结
数字人这个概念其实早在前几年就已经引起了广泛关注。然而,当时生成数字人的技术还没有如今这样成熟和易于操作,更多的是一些高端玩家才能够玩转,对于大众来说几乎是遥不可及的。而现在,随着AI技术的发展,我们可以借助AI绘画工具生成数字人图像,并通过D-ID让其“活起来”,大致了解AI虚拟主播的生成,时代的发展让更多人也能感受到科技带来的便利。- 本文只是对虚拟主播的一个简单制作体验教程,并不全面,还有许多功能没有深入探索。作为一个对于AI虚拟主播的初步探索,这篇文章也是为了让读者在尝试中体验到AI发展带来的乐趣,感谢阅读~
import torch;import torch.nn as nn;import torch.optim as optim;from torch.utils.data import Dataset, DataLoader;import torchvision.transforms as transforms;from torchvision import models;import numpy as np;import cv2;import os;from PIL import Image;from facenet_pytorch import MTCNN, InceptionResnetV1;class DigitalHumanDataset(Dataset):def __init__(self, root_dir, transform=None):self.root_dir=root_dir;self.transform=transform;self.image_files=os.listdir(root_dir);def __len__(self):return len(self.image_files);def __getitem__(self, idx):img_name=os.path.join(self.root_dir, self.image_files[idx]);image=Image.open(img_name).convert('RGB');if self.transform:image=self.transform(image);return image;class Generator(nn.Module):def __init__(self):super(Generator, self).__init__();self.fc1=nn.Linear(100, 256);self.fc2=nn.Linear(256, 512);self.fc3=nn.Linear(512, 1024);self.fc4=nn.Linear(1024, 64*64*3);def forward(self, x):x=torch.relu(self.fc1(x));x=torch.relu(self.fc2(x));x=torch.relu(self.fc3(x));x=torch.tanh(self.fc4(x)).view(-1, 3, 64, 64);return x;class Discriminator(nn.Module):def __init__(self):super(Discriminator, self).__init__();self.fc1=nn.Linear(64*64*3, 1024);self.fc2=nn.Linear(1024, 512);self.fc3=nn.Linear(512, 256);self.fc4=nn.Linear(256, 1);def forward(self, x):x=x.view(-1, 64*64*3);x=torch.relu(self.fc1(x));x=torch.relu(self.fc2(x));x=torch.relu(self.fc3(x));x=torch.sigmoid(self.fc4(x));return x;device=torch.device("cuda" if torch.cuda.is_available() else "cpu");netG=Generator().to(device);netD=Discriminator().to(device);criterion=nn.BCELoss();optimizerD=optim.Adam(netD.parameters(), lr=0.0002, betas=(0.5, 0.999));optimizerG=optim.Adam(netG.parameters(), lr=0.0002, betas=(0.5, 0.999));dataset=DigitalHumanDataset(root_dir='path_to_images', transform=transforms.Compose([transforms.Resize(64), transforms.ToTensor()]));dataloader=DataLoader(dataset, batch_size=16, shuffle=True);fixed_noise=torch.randn(16, 100, device=device);for epoch in range(100):for i, data in enumerate(dataloader, 0):netD.zero_grad();real_data=data.to(device);batch_size=real_data.size(0);label=torch.full((batch_size,), 1, device=device);output=netD(real_data);errD_real=criterion(output, label);errD_real.backward();noise=torch.randn(batch_size, 100, device=device);fake_data=netG(noise);label.fill_(0);output=netD(fake_data.detach());errD_fake=criterion(output, label);errD_fake.backward();optimizerD.step();netG.zero_grad();label.fill_(1);output=netD(fake_data);errG=criterion(output, label);errG.backward();optimizerG.step();with torch.no_grad():fake=netG(fixed_noise).detach().cpu();grid=torchvision.utils.make_grid(fake, padding=2, normalize=True);torchvision.utils.save_image(grid, f'output/fake_epoch_{epoch}.png');mtcnn=MTCNN(keep_all=True, device=device);resnet=InceptionResnetV1(pretrained='vggface2').eval().to(device);video_capture=cv2.VideoCapture(0);while True:ret, frame=video_capture.read();frame_rgb=cv2.cvtColor(frame, cv2.COLOR_BGR2RGB);boxes, _=mtcnn.detect(frame_rgb);if boxes is not None:for box in boxes:x1, y1, x2, y2=[int(b) for b in box];face=frame_rgb[y1:y2, x1:x2];face=Image.fromarray(face);face=transforms.ToTensor()(face).unsqueeze(0).to(device);embedding=resnet(face);fake_face=netG(torch.randn(1, 100, device=device)).detach().cpu();fake_face_img=fake_face.squeeze(0).permute(1, 2, 0).numpy();fake_face_img=((fake_face_img + 1) / 2 * 255).astype(np.uint8);fake_face_img=cv2.resize(fake_face_img, (x2 - x1, y2 - y1));frame[y1:y2, x1:x2]=cv2.cvtColor(fake_face_img, cv2.COLOR_RGB2BGR);cv2.imshow('AI Digital Human', frame);if cv2.waitKey(1) & 0xFF==ord('q'):break;video_capture.release();cv2.destroyAllWindows()