1. 项目说明

图像视频处理在计算机视觉中是一个基本但具有挑战性的任务。它旨在提供详细的人脸关键点定位,相当于为每个人脸进行关键点描点。该技术目前被广泛应用于短视频媒体平台、直播等系统领域。以我们选用的“人脸关键点识别”数据集为例,该项目的挑战在于:

1.1 人脸光照条件的不确定性:

不同的场景会有不同的光照等因素,光照的来 源方向、光照强度的不同都影响人脸图像的灰度布局。

1.2 人脸受遮挡的不确定性:

定位出人脸面部的关键区域位置,包括眉毛、眼睛、鼻子、嘴巴、脸部轮廓等和人脸检测类似,由于受到姿态和遮挡等因素的影响。

1.3 人脸关键点算法的设计:

要实现对视频和图像中的人脸的追踪并分析面部表情,来检测畸形面部体征以进行我们图像视频处理。

2. 安装说明

2.1 环境要求

·paddlepaddle >= 2.0.0rc1
·Python >= 3.7
·dlib库的安装(适配于python版本,本文提供3.8版本Python的dlib安装文件)

强烈建议您安装/使用 GPU 版本的 PaddlePaddle。因为人脸关键点定位模型开销很大,当模型运行在 CPU 时可能会出现内存不足。更详细的安装教程请参考 PaddlePaddle 官网

2.2 dlib库安装

1.首先下载文件dlib-19.19.0-cp38-cp38-win_amd64.whl
该文件在文件浏览器下,可以直接下载。

2.将下载的whl文件放到任意的路径下,然后通过命令行进入到该目录下,
然后运行代码:

pip install dlib-19.19.0-cp38-cp38-win_amd64.whl
之后回车安装即可。

2.3 解压数据

项目部分代码在 dingwei.zip 文件中,数据集在 data.zip 文件中,解压到合适路径即可使用。除了压缩包文件中的程序,也可以在在aistudio项目中可以直接查阅作品中对于帽子和嘴巴特效定位处理的代码:

#嘴巴特效:

import cv2  # 图像处理的opencv库
import argparse  # 加载解析模块
import os
def hat_face(opt):
    # 加载dlib的人脸检测模型
    detector = dlib.get_frontal_face_detector()
    # 使用opencv中的imread函数,读取需要添加特效的图片
    landmark_predictor = dlib.shape_predictor(opt.landmarks_model_path)
    # 使用opencv中的imread函数,读取嘴巴的图片
    img_hat = cv2.imread(opt.hat_path)
    # img_hat = img_hat[:]
    # 对图片进行dlib人脸检测,得到检测后的人脸框信息faceRects
    # faceRects = detector(img, 0)
    # 图片中可能存在多张人脸,依次遍历输出每张人脸的位置信息,并在特定位置,添加嘴巴特效
    cap = cv2.VideoCapture(opt.video_path)
    force= cv2.VideoWriter_fourcc("X","V","I","D")
    out1 = cv2.VideoWriter("output.avi",force,20,(640,480))
    frame_id = 0
    while cap.isOpened():
        try:
            # 因为视频采集,每秒可能会采集N帧图片,因此使用read函数,逐帧读取图片
            # ret 返回True或Fasle,表示是否读取到图片
            # frame 返回读取的图片信息
            ret, frame = cap.read()
            # 如果ok为false,则采集结束
            if not ret:
                # 打印输出,提示信息
                print("Camera cap over!")
                continue
            # frame_id加1,便于跳帧
            frame_id += 1
            if not int(frame_id) % 2 == 0: continue
            faceRects = detector(frame)
            if len(faceRects) > 0:
                for box_info in faceRects:
                    # dlib检测出的人脸位置信息,为rectangle类型,所以可以通过left()、top()、right()、bottom()提取人脸框左上角的x0,y0,右下角的x1,y1。
                    x0, y0, width_face, height_face = box_info.left(), box_info.top(), box_info.right() - box_info.left(), box_info.bottom() - box_info.top()
                    landmarks = landmark_predictor(frame, box_info)
                    # 获得嘴巴图片的高height_hat,宽width_hat,便于后面控制嘴巴显示的大小
                    height_hat, width_hat = img_hat.shape[0], img_hat.shape[1]
                    # 将嘴巴的高度变成,适合检测到的脸型的大小
                    imgComposeSizeH = int(height_hat / width_hat * width_face)
                    # 因为嘴巴在脸部上方,当脸部靠近视频顶部,为了保证嘴巴能显示出来,嘴巴的高度默认为脸部到视频上方的距离
                    if imgComposeSizeH > (y0 + 220):
                        imgComposeSizeH = (y0 + 220)
                    # 将嘴巴的图片归一化到适合的宽和高大小,宽度为人脸的宽度,高度为上面调整后的嘴巴高度
                    imgComposeSize = cv2.resize(img_hat, (width_face, imgComposeSizeH), interpolation=cv2.INTER_NEAREST)
                    # 为了实现在人脸上方的额头,添加嘴巴特效,只需要将嘴巴贴到额头处即可
                    # 注意:y0是人脸检测框左上方顶点的y坐标,y0-20,则差不多定位到额头处,再减去imgComposeSizeH,调整后嘴巴的高度
                    #      即从这个位置开始贴合嘴巴,可以实现人脸嘴巴特效
                    top = (y0 + 220 - imgComposeSizeH )
                    # 当人脸太靠近图片上方,通过前一行的计算,有可能为负数,所以当出现这样的情况时,top设置为0
                    if top <= 0:
                        top = 0
                    # 获得调整尺寸后,嘴巴新的高height_hat_new,新的宽width_hat_new
                    height_hat_new, width_hat_new = imgComposeSize.shape[0], imgComposeSize.shape[1]
                    small_img_hat = frame[top:top + height_hat_new, x0:x0 + width_hat_new]
                    # 如需查看,上一行的效果,可将cv2.imwrite前面的#取消,运行后,保存到本目录查看
                    #cv2.imwrite("small_img_hat.jpg",small_img_hat)
                    # 将嘴巴图像,从RGB彩色图像转换为灰度图像
                    small_img_hat_gray = cv2.cvtColor(imgComposeSize, cv2.COLOR_RGB2GRAY)
                    # 如需查看,上一行的效果,可将cv2.imwrite前面的#取消,运行后,保存到本目录查看
                    #cv2.imwrite("small_img_hat_gray.jpg", small_img_hat_gray)
                    # 阈值化处理,将10<像素<255区间的图像抠出来
                    # 因为背景为黑色,所以阈值设置10到255,即可将嘴巴区域提取出来
                    ret, mask_hat = cv2.threshold(small_img_hat_gray, 10, 255, cv2.THRESH_BINARY)
                    # 如需查看,上一行的效果,可将cv2.imwrite前面的#取消,运行后,保存到本目录查看
                    #cv2.imwrite("mask_hat.jpg", mask_hat)
                    # 使用取反操作,将嘴巴的图像从黑色0变为白色255,将白色255变成黑色0
                    mask_hat_inv = cv2.bitwise_not(mask_hat)
                    # 如需查看,上一行的效果,可将cv2.imwrite前面的#取消,运行后,保存到本目录查看
                    #cv2.imwrite("mask_hat_inv.jpg", mask_hat_inv)
                    # 使用按位与操作,将抠出的嘴巴区域和取反后的嘴巴图像相加
                    img1_bg = cv2.bitwise_and(small_img_hat, small_img_hat, mask=mask_hat_inv)
                    # 如需查看,上一行的效果,可将cv2.imwrite前面的#取消,运行后,保存到本目录查看
                    #cv2.imwrite("img1_bg.jpg", img1_bg)
                    # 使用按位与操作,将像素值在[10,255]之间的帽子RGB区域抠取出来
                    img2_fg = cv2.bitwise_and(imgComposeSize, imgComposeSize, mask=mask_hat)
                    dst = cv2.add(img1_bg, img2_fg)
                    # img_bg = cv2.bitwise_and(roi_face, roi_face, mask=mask_eyeglass_inv)
                    # 如需查看,上一行的效果,可将cv2.imwrite前面的#取消,运行后,保存到本目录查看
                    #cv2.imwrite("dst.jpg", dst)
                    # 将带了嘴巴的局部区域,贴合到原始图像上
                    frame[top:top + height_hat_new, x0:x0 + width_hat_new] = dst
                    out1.write(frame)
            img = cv2.resize(frame, (800, 600))
        # 显示图片
            cv2.imshow("image", img)
        # 显示图片停顿的时间,如果是0,则一直显示。如果是100,则显示100ms
            if cv2.waitKey(1) & 0xFF == ord('q'):
                break
            # 按‘q’退出
        except:pass


### 函数主入口
# if __name__ == '__main__':
    # 新建一个解析器
def zuibab5():
    parser = argparse.ArgumentParser()
    # 为解析器添加选项,比如image_path,添加图片地址,可以更换其他图片尝试。(在default后面,添加需要读取的图片路径)
    # 注意:不同的图片,宽高大小可能不同,大家可以根据自己的图片比例,调试前面的的cv2.resize中的数值,修改显示窗口的大小。
    parser.add_argument('--video_path', default=0, help='path of cap video')
    # apath = os.path.abspath("mao1.png")
    # print(apath)
    # 为解析器添加选项,比如hat_path,添加嘴巴图片地址。(在default后面,添加需要读取的嘴巴图片路径)
    parser.add_argument('--hat_path', default="./image/zui5.1.png", help='path of hat image')
    parser.add_argument('--landmarks_model_path', default="shape_predictor_68_face_landmarks.dat", help='path of model')
    # 解析选项的参数
    opt = parser.parse_args()
    # 调用hat_face函数,对人脸进行检测,添加嘴巴特效
    hat_face(opt)
#帽子特效:

import cv2  # 图像处理的opencv库
import argparse  # 加载解析模块
import os
def hat_face(opt):
    # 加载dlib的人脸检测模型
    detector = dlib.get_frontal_face_detector()
    # 使用opencv中的imread函数,读取需要添加特效的图片
    landmark_predictor = dlib.shape_predictor(opt.landmarks_model_path)
    # 使用opencv中的imread函数,读取兔子帽子的图片
    img_hat = cv2.imread(opt.hat_path)
    # img_hat = img_hat[:]
    # 对图片进行dlib人脸检测,得到检测后的人脸框信息faceRects
    # faceRects = detector(img, 0)
    # 图片中可能存在多张人脸,依次遍历输出每张人脸的位置信息,并在特定位置,添加兔子帽子特效
    cap = cv2.VideoCapture(opt.video_path)
    frame_id = 0
    while cap.isOpened():
        # 因为视频采集,每秒可能会采集N帧图片,因此使用read函数,逐帧读取图片
        # ret 返回True或Fasle,表示是否读取到图片
        # frame 返回读取的图片信息
        ret, frame = cap.read()
        # 如果ok为false,则采集结束
        if not ret:
            # 打印输出,提示信息
            print("Camera cap over!")
            continue
        # frame_id加1,便于跳帧
        frame_id += 1
        if not int(frame_id) % 2 == 0: continue
        faceRects = detector(frame)
        if len(faceRects) > 0:
            for box_info in faceRects:
                # dlib检测出的人脸位置信息,为rectangle类型,所以可以通过left()、top()、right()、bottom()提取人脸框左上角的x0,y0,右下角的x1,y1。
                x0, y0, width_face, height_face = box_info.left(), box_info.top(), box_info.right() - box_info.left(), box_info.bottom() - box_info.top()
                landmarks = landmark_predictor(frame, box_info)
                # 获得帽子图片的高height_hat,宽width_hat,便于后面控制帽子显示的大小
                height_hat, width_hat = img_hat.shape[0], img_hat.shape[1]
                # 将帽子的高度变成,适合检测到的脸型的大小
                imgComposeSizeH = int(height_hat / width_hat * width_face)
                # 因为帽子在脸部上方,当脸部靠近视频顶部,为了保证帽子能显示出来,帽子的高度默认为脸部到视频上方的距离
                if imgComposeSizeH > (y0 - 20):
                    imgComposeSizeH = (y0 - 20)
                # 将帽子的图片归一化到适合的宽和高大小,宽度为人脸的宽度,高度为上面调整后的帽子高度
                imgComposeSize = cv2.resize(img_hat, (width_face, imgComposeSizeH), interpolation=cv2.INTER_NEAREST)
                top = (y0 - 20 - imgComposeSizeH )
                # 当人脸太靠近图片上方,通过前一行的计算,有可能为负数,所以当出现这样的情况时,top设置为0
                if top <= 0:
                    top = 0
                height_hat_new, width_hat_new = imgComposeSize.shape[0], imgComposeSize.shape[1]
                small_img_hat = frame[top:top + height_hat_new, x0:x0 + width_hat_new]
                # 如需查看,上一行的效果,可将cv2.imwrite前面的#取消,运行后,保存到本目录查看
                #cv2.imwrite("small_img_hat.jpg",small_img_hat)
                # 将帽子图像,从RGB彩色图像转换为灰度图像
                small_img_hat_gray = cv2.cvtColor(imgComposeSize, cv2.COLOR_RGB2GRAY)
                # 如需查看,上一行的效果,可将cv2.imwrite前面的#取消,运行后,保存到本目录查看
                ret, mask_hat = cv2.threshold(small_img_hat_gray, 10, 255, cv2.THRESH_BINARY)
                # 如需查看,上一行的效果,可将cv2.imwrite前面的#取消,运行后,保存到本目录查看
                #cv2.imwrite("mask_hat.jpg", mask_hat)
                # 使用取反操作,将帽子的图像从黑色0变为白色255,将白色255变成黑色0
                mask_hat_inv = cv2.bitwise_not(mask_hat)
                # 如需查看,上一行的效果,可将cv2.imwrite前面的#取消,运行后,保存到本目录查看
                #cv2.imwrite("mask_hat_inv.jpg", mask_hat_inv)
                # 使用按位与操作,将抠出的帽子区域和取反后的帽子图像相加
                img1_bg = cv2.bitwise_and(small_img_hat, small_img_hat, mask=mask_hat_inv)
                # 如需查看,上一行的效果,可将cv2.imwrite前面的#取消,运行后,保存到本目录查看
                #cv2.imwrite("img1_bg.jpg", img1_bg)
                # 使用按位与操作,将像素值在[10,255]之间的帽子RGB区域抠取出来
                img2_fg = cv2.bitwise_and(imgComposeSize, imgComposeSize, mask=mask_hat)
                # 将img1_bg和img2_fg相加,等于戴了帽子的区域图像
                dst = cv2.add(img1_bg, img2_fg)
                frame[top:top + height_hat_new, x0:x0 + width_hat_new] = dst
        img = cv2.resize(frame, (800, 600))
    # 显示图片
        cv2.imshow("image", img)
    # 显示图片停顿的时间,如果是0,则一直显示。如果是100,则显示100ms
        if cv2.waitKey(2) & 0xFF == ord('q'):
            break
        # 按‘q’退出


### 函数主入口
# if __name__ == '__main__':
    # 新建一个解析器
def maoc1():
    parser = argparse.ArgumentParser()
    # 为解析器添加选项,比如image_path,添加图片地址,可以更换其他图片尝试。(在default后面,添加需要读取的图片路径)
    # 注意:不同的图片,宽高大小可能不同,大家可以根据自己的图片比例,调试前面的的cv2.resize中的数值,修改显示窗口的大小。
    parser.add_argument('--video_path', default=0, help='path of cap video')
    # apath = os.path.abspath("mao1.png")
    # print(apath)
    # 为解析器添加选项,比如hat_path,添加帽子图片地址。(在default后面,添加需要读取的帽子图片路径)
    parser.add_argument('--hat_path', default="./image/m8.png", help='path of hat image')
    parser.add_argument('--landmarks_model_path', default="shape_predictor_68_face_landmarks.dat", help='path of model')
    # 解析选项的参数
    opt = parser.parse_args()
    # 调用hat_face函数,对人脸进行检测,添加兔子帽子特效
    hat_face(opt)

3. 系统关键技术

本作品是使用python语言进行开发设计,主要使用到pyqt5、opencv、dlib、math、requests、bs4等第三方库来实现。作品在读取图片和视频数据的功能上是使用opencv库来实现,除了对图像数据的读取外,还有一关键功能,就是为识别的人像进行68点关键点描点;dlib库是我们作品实现的关键技术,它是基于opencv对人像的描点进行检测,使人脸关键点定位更加精准,为我们后续的特效添加起到了重要的作用;并且通过dlib来进行调参算法对paddlehub框架进行优化;pyqt5模块支撑着我们作品的“排面”,界面设计简约,极易理解,非常容易上手。顺应时下流行的短视频媒体平台的潮流和广大用户的需要,以飞桨平台的模型调用便捷性,结合python开发技术,将图像视频处理工具进行打包,将一个具备免费、免安装、免网络的全民使用工具呈现给大家。

3.1 图像与视频数据读取的实现

图像与视频的读取是我们工具必备的功能,图像和视频的读取不仅可以选择本地已有素材,在借助python的opencv模块功能下实现了可以实时进行拍摄、录制素材。在获取实时素材这一部分,我们加入了异常判断指令,使得获取的图像可以清晰、无延迟地显示到客户端,从而较好地实现了拍摄的实时效果,为后续对图片和视频进行处理奠定了基础。
这里提供简单的内容展示:

def Jietu(self):
        try:
            import time
            import win32com.client 
            speak = win32com.client.Dispatch("SAPI.SpVoice")
            # speak.Speak("正在获取图片")
            self.da = []
            times = str(round(time.time()))
            cap = cv2.VideoCapture(0)
            ret, frame = cap.read()  # cao.read()返回两个值,第一个存储一个bool值,表示拍摄成功与否。第二个是当前截取的图片帧。
            cv2.imwrite(f"./capture1_{times}.jpg", frame)  # 写入图片
            cap.release()  # 释放
            self.da.append(f"./capture1_{times}.jpg")
            time.sleep(0.2)
            self.labbeltu.setPixmap(QPixmap(self.da[0]))
            self.path_files1 = [1]
            self.path_files1[0] = self.da[0]
            speak.Speak("正在识别图片")
        except:
            pass

3.2 人脸关键点定位的调参优化

在图像处理中,关键点本质上是一种特征。它是对一个固定区域或者空间物理关系的抽象描述,描述的是一定邻域范围内的组合或上下文关系。它不仅仅是一个点信息,或代表一个位置,更代表着上下文与周围邻域的组合关系。关键点检测的目标就是通过计算机从图像中找出这些点的坐标,作为计算机视觉领域的一个基础任务,关键点的检测对于高级别任务,例如识别和分类具有至关重要的意义。
关键点检测方法总体上可以分成两个类型,一个种是用坐标回归的方式来解决,另一种是将关键点建模成热力图,通过像素分类任务,回归热力图分布得到关键点位置。这两个方法,都是一种手段或者是途径,解决的问题就是要找出这个点在图像当中的位置与关系。其中人脸关键点检测是关键点检测方法的一个成功实践。我们作品也将人脸关键点定位的功能完美应用其中。
这里提供 瘦脸优化 和 美白优化 的代码实例:

def thin_face(image, face_landmark):
    """
    实现自动人像瘦脸
    image: 人像图片
    face_landmark: 人脸关键点
    """
    end_point = face_landmark[30]
 # 瘦左脸,3号点到5号点的距离作为瘦脸距离
    dist_left = np.linalg.norm(face_landmark[3] - face_landmark[5])
    image = local_traslation_warp(image, face_landmark[3], end_point, dist_left)

    # 瘦右脸,13号点到15号点的距离作为瘦脸距离
    dist_right = np.linalg.norm(face_landmark[13] - face_landmark[15])
    image = local_traslation_warp(image, face_landmark[13], end_point, dist_right)
    return image
def whitening(img, face_landmark):
	"""
	美白
	"""
	# 简单估计额头所在区域
	# 根据0号、16号点画出额头(以0号、16号点所在线段为直径的半圆)
	radius=(np.linalg.norm(face_landmark[0] - face_landmark[16]) / 2).astype('int32')
	center_abs=tuple(((face_landmark[0] + face_landmark[16]) / 2).astype('int32'))
	angle=np.degrees(np.arctan((lambda l:l[1]/l[0])(face_landmark[16]-face_landmark[0]))).astype('int32')
	face = np.zeros_like(img)
	cv2.ellipse(face,center_abs,(radius,radius),angle,180,360,(255,255,255),2)
	# cv2.ellipse(face, center_abs, (radius, radius), angle, 180, 360, (0,0,0), 2)
	points=face_landmark[0:17]
	hull = cv2.convexHull(points)
	cv2.polylines(face, [hull], True, (255,255,255), 2)
	# cv2.polylines(face, [hull], True, (0,0,0), 2)

3.3 界面的设计与制作

本功能是使用Pyqt5模块来进行工具GUI界面设计与制作。Pyqt5是基于图形程序框架Qt5的Python语言实现,由一组Python模块构成,是目前最主流的Python GUI框架。功能资源强大的同时又方便快捷。通过使用pyqt5模块可以很容易的对工具界面进行精美的设计和制作。并且在python打包的qt工具中,pyqt5库支持跨平台使用。

4. 功能介绍

我们的工具主要对图片、视频进行处理,包括人像美颜、视频制作、等功能,具有方便、免安装、免费的优势。分为两大功能,分别是图片处理工具和视频处理工具,并且支持现场拍摄和现场录制视频来进行处理。

4.1 图像处理工具

图片处理工具是本作品中的一种功能工具,它对于图片的风格化处理、图像质量的提升等功能有着很全面的实现,下面是图片处理工具的功能介绍图:

在这里插入图片描述

下面是我们的图片处理工具的界面图展示图:
可以通过选取本地图片或者现场拍摄的图片来选择瘦脸处理、眼睛处理、美白以及黑白图片上色等功能。

在这里插入图片描述

实时拍摄图片来进行处理,更是我们图像视频工具的一大特点:

在这里插入图片描述

操作流程:
Step1 选择需要处理的照片
可以选择本地已有的照片或者现场拍摄的照片

Step2 选择需要处理的功能
使用图片风格美化和图片质量提升等功能

Step3 进行美化处理
使用人像处理、人像美颜、图片上色,抠图等来对图片进行美化

Step4 检查图片
检查处理后的图片是否符合自己的要求

Step5 保存图片
将处理后的图片用原图进行保存

4.2 视频处理工具

视频处理工具在本作品中,主要体现的是特效的添加。对于人脸的定位来进行精准的特效添加。
在这里插入图片描述

下面是我们作品的视频处理工具的界面展示图
可以选择不同的特效来进行实时的录像。

在这里插入图片描述

效果展示图:

在这里插入图片描述

效果展示图:

在这里插入图片描述

操作流程:
Step 1 选择需要做处理的视频
可以直接添加本地视频或者现场实时录制视频

Step 2 选择需要的功能
工具中带有视频风格化处理、AI换脸、视频剪辑等功能

Step 3 进行调试
可以随意播放处理后视频,观看是否满足要求并进行调整

Step 4 保存视频
将处理后的视频保存到与原视频相同的路径下,并且不覆盖原视频

4.3 工具操作流程

由于本作品是一款面向大众的功能性工具,而流程图是流经一个系统的信息流、观点流或部件流的图形代表,可以让用户更加直观的了解和使用我们的工具。下面是本工具的操作流程图:
在这里插入图片描述

用户可以根据我们的流程图通过简单的操作来实现图像视频处理。

5. 总结

经过几个月的设计和编码,作品《咔秀》基本开发完毕。基本实现了预定完成的功能。本文阐述了该工具的基础理论、实现过程和关键技术。由于篇幅的原因,不可能把整个系统中的每一项技术,每一个细节具体地讲出来,因此,我们只是有选择地对系统中的一些内容进行了介绍。不足之处,还望各位指教。
通过使用python语言中dilib人像关键点定位、opencv库等各种技巧,通过opencv库对图片和视频进行处理,使用photoshop工具设计图片。并且结合dlib库,利用设备摄像头进行人脸捕捉。从而定位人脸关键点,对人脸所在位置添加特效。
在作品设计期间,学习了python语言编程,用到的主要技术有pyqt5(界面设计)、opencv(读取摄像头)、dlib(人脸关键点定位)、、match(模块算法)、requests(数据获取)、bs4等主要技术,并查看学习了许多资料。在系统的研发过程中,我们也遇到许多困难,因为以前没有项目经验,起步很难,不过通过各种知识的补充学习,并且查找各种资料,团队慢慢进入状态,并且从中找到很多乐趣。
本系统经过测试,效果良好,但是由于时间有限,技术上存在许多需要改进之处。在功能上还有许多待完善的地方,比如可以增加特效种类,对特效进行动态处理在视频中增加互动,这些设想我们都在进一步的研究与实现。希望通过我们今后的不断努力,我们的作品不断扩大应用范围,真正服务于图片、视频特效这个领域。

此文仅为搬运,原作链接:https://aistudio.baidu.com/aistudio/projectdetail/4264449?channelType=0&channel=0

Logo

学大模型,用大模型上飞桨星河社区!每天8点V100G算力免费领!免费领取ERNIE 4.0 100w Token >>>

更多推荐