当前位置:

首页 > 编程开发 > 如何用Python编写视觉桌上冰球小游戏

如何用Python编写视觉桌上冰球小游戏

介绍规则如下:左手控制白色球拍;右手控制紫色球拍;球拍只能上下移动;红色圆形就是冰球;球碰撞到上下两侧的蓝色边框,和两侧的球拍就会反弹;如果球进入了黄色区域,游戏结束;下面的粉色计数板,记录左右两侧各击球多少次。1.文件配置1.1导入工具包pipinstallopencv_python==4.2.0.34#安装opencvpipinstallmediapipe#安装mediapipe#pipinstallmediapipe--user#有user报错的话试试这个pipinstallcvzone#安装cvz

本文目录

    介绍

    规则如下:左手控制白色球拍;右手控制紫色球拍;球拍只能上下移动;红色圆形就是冰球;球碰撞到上下两侧的蓝色边框,和两侧的球拍就会反弹;如果球进入了黄色区域,游戏结束;下面的粉色计数板,记录左右两侧各击球多少次。

    如何用Python编写视觉桌上冰球小游戏

    1. 文件配置

    1.1 导入工具包

    pip install opencv_python==4.2.0.34  # 安装opencv
    pip install mediapipe  # 安装mediapipe
    # pip install mediapipe --user  #有user报错的话试试这个
    pip install cvzone  # 安装cvzone
     
    # 导入工具包
    import cv2
    import cvzone
    from cvzone.HandTrackingModule import HandDetector  # 导入手部检测模块

    21个手部关键点坐标如下:

    如何用Python编写视觉桌上冰球小游戏

    1.2 素材图片准备

    开始之前,先准备球桌的图片,球的图片,球拍的图片。我是用PPT画的图,球和球拍的图片一定要保存成 .png 格式的。放在同一个文件夹中以备读取。

    如何用Python编写视觉桌上冰球小游戏

    2. 手部关键点检测、素材导入

    2.1 方法介绍

    (1) cvzone.HandTrackingModule.HandDetector()手部关键点检测方法

    参数:

    mode: 默认为 False,将输入图像视为视频流。它将尝试在第一个输入图像中检测手,并在成功检测后进一步定位手的坐标。在随后的图像中,一旦检测到所有 maxHands 手并定位了相应的手的坐标,它就会跟踪这些坐标,而不会调用另一个检测,直到它失去对任何一只手的跟踪。这减少了延迟,非常适合处理视频帧。如果设置为 True,则在每个输入图像上运行手部检测,用于处理一批静态的、可能不相关的图像。

    maxHands: 最多检测几只手,默认为 2

    detectionCon: 手部检测模型的最小置信值(0-1之间),超过阈值则检测成功。默认为 0.5

    minTrackingCon: 坐标跟踪模型的最小置信值 (0-1之间),用于将手部坐标视为成功跟踪,不成功则在下一个输入图像上自动调用手部检测。将其设置为更高的值可以提高解决方案的稳健性,但代价是更高的延迟。如果 mode 为 True,则忽略这个参数,手部检测将在每个图像上运行。默认为 0.5

    它的参数和返回值类似于官方函数 mediapipe.solutions.hands.Hands()

    MULTI_HAND_LANDMARKS: 被检测/跟踪的手的集合,其中每只手被表示为21个手部地标的列表,每个地标由x, y, z组成。

    MULTI_HANDEDNESS: 被检测/追踪的手是左手还是右手的集合。每只手由label(标签)和score(分数)组成。 label 是 'Left' 或 'Right' 值的字符串。 score 是预测左右手的估计概率。

    (2)cvzone.HandTrackingModule.HandDetector.findHands() 找到手部关键点并绘图

    参数:

    img: 需要检测关键点的帧图像,格式为BGR

    draw: 是否需要在原图像上绘制关键点及识别框

    flipType: 图像是否需要翻转,当视频图像和我们自己不是镜像关系时,设为True就可以了

    返回值:

    hands: 检测到的手部信息,由0或1或2个字典组成的列表。如果检测到两只手就是由两个字典组成的列表。字典中包含:21个关键点坐标(x,y,z),检测框左上坐标及其宽高,检测框中心点坐标,检测出是哪一只手。

    img: 返回绘制了关键点及连线后的图像

    (3)cv2.addWeighted()图像融合

    将两张图像按一定比例融合在一起,需要两张图像的size和通道数相同

    两张图像按一定比例融合: cv2.addWeighted(图像1, 权重1, 图像2, 权重2, 亮度偏置)

    相当于 y = a x1 + b x2 + c,其中 a、b 代表权重,c 代表亮度上提亮多少

    2.2 代码展示

    首先 cv2.imread() 中的参数 cv2.IMREAD_UNCHANGED 是指用图片的原来格式打开,包含Alpha通道。即以不改变图片的方式打开,图片是彩色那么读进来就是彩色,图片是灰度图那么读进来就是灰度图,读进来的图片的shape如下:

    如何用Python编写视觉桌上冰球小游戏

    该部分代码主要负责手部关键点检测,融合背景图像和视频帧图像

    import cv2
    import cvzone
    from cvzone.HandTrackingModule import HandDetector  # 导入手部检测模块
     
    #(1)捕获摄像头
    cap = cv2.VideoCapture(0)  # 0代表电脑自带的摄像头
    cap.set(3, 1280)  # 读入的图像的宽
    cap.set(4, 720)   # 读入的图像的高
     
     
    #(2)文件配置
    # 导入所有需要对图片文件
    imgDesk = cv2.imread('games/desk.jpg')  # 球桌的图片
    imgBall = cv2.imread('games/ball.png', cv2.IMREAD_UNCHANGED)  # 球的图片
    imgBlock1 = cv2.imread('games/block1', cv2.IMREAD_UNCHANGED)  # 球拍的图片
    imgBlock2 = cv2.imread('games/block2', cv2.IMREAD_UNCHANGED)  # 球拍的图片
    # 调整球桌图片的size
    imgDesk = cv2.resize(imgDesk, dsize=(1280,720))
     
     
    #(3)参数设置
    # 接收手部关键点识别的方法,最小手部检测模块置信度0.8,最多检测2只手
    detector = HandDetector(detectionCon=0.8, maxHands=2)
     
     
    #(4)处理帧图像
    while True:
     
        # 返回是否读取成功,以及读取后的帧图像
        success, img = cap.read()  # 每次执行读取一帧
        
        # 图片翻转呈镜像关系,1代表左右翻转,0代表上下翻转
        img = cv2.flip(img, flipCode=1)
        
        # 手部关键点检测,返回每个只手的信息和绘制后的图像
        hands, img = detector.findHands(img, flipType=False)  # 上面翻转过了这里就不用翻转了
     
        # 将球桌图片和视频帧图像融合在一起, 两张图的shape要相同
        # 给出每张图片的融合权重, 亮度偏置为0,这样就变成了半透明的显示形式
        img = cv2.addWeighted(img, 0.3, imgDesk, 0.7, 0)
     
        
        #(5)添加桌球的图片,将imgBall放在球桌img的指定坐标位置
        img = cvzone.overlayPNG(img, imgBall, (100,100))
        
        # 图像展示
        cv2.imshow('img', img)
        # 每帧滞留1ms后消失
        k = cv2.waitKey(1)
        # ESC键退出程序
        if k & 0XFF==27:
            break
     
    # 释放视频资源
    cap.release()
    cv2.destroyAllWindows()

    效果图如下:

    如何用Python编写视觉桌上冰球小游戏

    3. 关键点处理、球拍移动

    3.1 方法介绍

    这部分主要完成两项工作,第一是左右手分别控制左侧和右侧的球拍,第二个是球以一定的速度移动。

    (1)控制球拍

    hand['bbox'] 中包含了手部检测框的左上角坐标和检测框的宽高,使用手掌中心点的 y 坐标来控制球拍的上下移动。由于两个球拍的shape是相同的,因此只要获取一个球拍的高度 h2 即可。使用掌心中点 y 坐标控制球拍中点的 y1 坐标,公式为:y1 = (y + h) // 2 - h2 // 2

    接着使用 cvzone.overlayPNG() 就可以将球拍图片覆盖在原图片的指定区域,其中坐标参数是指覆盖区域的左上角坐标。固定横坐标,只上下移动。

    (2)球移动

    首先要规定球的移动速度 speedx, speedy = 10, 10 代表球每一帧沿x轴正方向移动10个像素,沿y轴正方向移动10个像素,那么球的初始合速度方向是沿图片的正右下角移动

    如果球碰撞到了球桌的上下边框,就反弹。speedy = -speedy。代表x方向每帧移动的步长不变,y方向每帧移动的方向反转,即入射角等于出射角。

    3.2 代码展示

    在上述代码中补充

    import cv2
    import cvzone
    import numpy as np
    from cvzone.HandTrackingModule import HandDetector  # 导入手部检测模块
     
    #(1)捕获摄像头
    cap = cv2.VideoCapture(0)  # 0代表电脑自带的摄像头
    cap.set(3, 1280)  # 读入的图像的宽
    cap.set(4, 720)   # 读入的图像的高
     
     
    #(2)文件配置
    # 导入所有需要对图片文件
    imgDesk = cv2.imread('games/desk.jpg')  # 球桌的图片
    imgBall = cv2.imread('games/ball.png', cv2.IMREAD_UNCHANGED)  # 球的图片
    imgBlock1 = cv2.imread('games/block1.png', cv2.IMREAD_UNCHANGED)  # 球拍的图片
    imgBlock2 = cv2.imread('games/block2.png', cv2.IMREAD_UNCHANGED)  # 球拍的图片
    # 调整球桌图片的size
    imgDesk = cv2.resize(imgDesk, dsize=(1280,720))
    # 调整球拍的size
    imgBlock1 = cv2.resize(imgBlock1, dsize=(50,200))
    imgBlock2 = cv2.resize(imgBlock2, dsize=(50,200))
     
     
    #(3)参数设置
    # 接收手部关键点识别的方法,最小手部检测模块置信度0.8,最多检测2只手
    detector = HandDetector(detectionCon=0.8, maxHands=2)
     
    # 球的默认位置
    ballpos = [100, 100]
     
    # 球的移动速度,每帧15个像素
    speedx, speedy = 10, 10
     
     
    #(4)处理帧图像
    while True:
     
        # 返回是否读取成功,以及读取后的帧图像
        success, img = cap.read()  # 每次执行读取一帧
        
        # 图片翻转呈镜像关系,1代表左右翻转,0代表上下翻转
        img = cv2.flip(img, flipCode=1)
        
        # 手部关键点检测,返回每个只手的信息和绘制后的图像
        hands, img = detector.findHands(img, flipType=False)  # 上面翻转过了这里就不用翻转了
     
        # 将球桌图片和视频帧图像融合在一起, 两张图的shape要相同
        # 给出每张图片的融合权重, 亮度偏置为0,这样就变成了半透明的显示形式
        img = cv2.addWeighted(img, 0.4, imgDesk, 0.6, 0)
        
        
        #(5)处理手部关键点,如果检测到手了就进行下一步
        if hands:
            
            # 遍历每检测的2只手,获取每一只手的坐标
            for hand in hands:
                
                # 获取手部检测框的左上坐标xy,宽高wh
                x, y, w, h = hand['bbox']
                
                # 获取球拍的宽高
                h2, w1 = imgBlock1.shape[0:2]
                
                # 球拍的中心y坐标,随着掌心移动
                y1 = (y + h) // 2 - h2 // 2
     
                # 如果检测到了左手
                if hand['type'] == 'Left':
                    
                    # 左侧的球拍x轴固定,y坐标随左手掌间中点移动
                    img = cvzone.overlayPNG(img, imgBlock1, (55,y1))
                    
                # 如果检测到了右手
                if hand['type'] == 'Right':
                    
                    # 右侧的球拍x轴固定,y坐标随右手掌间中点移动
                    img = cvzone.overlayPNG(img, imgBlock2, (1280-55,y1))
                          
        #(6)改变球的位置
        # 如果球的y坐标在超出了桌面的上或下边框范围,调整移动方向
        if ballpos[1] >= 600 or ballpos[1] <= 50:
            
            # y方向的速度调整为反方向,那么x方向和y方向的合速度方向调整了
            speedy = -speedy
     
        ballpos[0] = ballpos[0] + speedx  # 调整球的x坐标
        ballpos[1] = ballpos[1] + speedy  # 调整球的y坐标
     
        
        #(5)添加桌球的图片,将imgBall放在球桌img的指定坐标位置
        img = cvzone.overlayPNG(img, imgBall, ballpos)
        
        # 图像展示
        cv2.imshow('img', img)
        # 每帧滞留1ms后消失
        k = cv2.waitKey(1)
        # ESC键退出程序
        if k & 0XFF==27:
            break
     
    # 释放视频资源
    cap.release()
    cv2.destroyAllWindows()

    效果图如下:

    如何用Python编写视觉桌上冰球小游戏

    4. 球拍击球、游戏完善

    4.1 方法介绍

    这一部分主要完成三项工作,第一是球拍击打到球,球需要反弹;第二是如果球进入黄色区域,游戏结束;第三是左右侧击球得分计数器。

    (1)球拍击球

    看到代码中的第(5)步,ballpos 代表球的左上角坐标(x,y),100 < ballpos[0] < 100+w1 代表球到了球拍横坐标区域范围内部了,y1 < ballpos[1] < y1+h2 代表球的y坐标在球拍y坐标内部,这时表明击球成功,speedx = -speedx 只改变沿x轴的速度方向,不改变沿y轴的速度方向。

    (2)球进黄区,游戏结束

    if ballpos[0] < 50 or ballpos[0] > 1150,如果球图片的左上坐标的 x 坐标,在黄区边缘,整个程序退出。当然也可以做一个游戏结束界面,我之前的博文里也有介绍,我偷个懒不写了。

    (3)计数器

    首先定义个变量初始化记录左右侧的击球次数 score = [0, 0],如果有一侧的球拍击中球,那么对应该侧计数加一。

    4.2 代码展示

    上面代码是掌心控制球拍,这里改成食指指尖控制球拍中点移动。

    import cv2
    import cvzone
    from cvzone.HandTrackingModule import HandDetector  # 导入手部检测模块
     
    #(1)捕获摄像头
    cap = cv2.VideoCapture(0)  # 0代表电脑自带的摄像头
    cap.set(3, 1280)  # 读入的图像的宽
    cap.set(4, 720)   # 读入的图像的高
     
     
    #(2)文件配置
    # 导入所有需要对图片文件
    imgDesk = cv2.imread('games/desk.jpg')  # 球桌的图片
    imgBall = cv2.imread('games/ball.png', cv2.IMREAD_UNCHANGED)  # 球的图片
    imgBlock1 = cv2.imread('games/block1.png', cv2.IMREAD_UNCHANGED)  # 球拍的图片
    imgBlock2 = cv2.imread('games/block2.png', cv2.IMREAD_UNCHANGED)  # 球拍的图片
    # 调整球桌图片的size
    imgDesk = cv2.resize(imgDesk, dsize=(1280,720))
    # 调整球拍的size
    imgBlock1 = cv2.resize(imgBlock1, dsize=(50,200))
    imgBlock2 = cv2.resize(imgBlock2, dsize=(50,200))
     
     
    #(3)参数设置
    # 接收手部关键点识别的方法,最小手部检测模块置信度0.8,最多检测2只手
    detector = HandDetector(detectionCon=0.8, maxHands=2)
     
    # 球的默认位置
    ballpos = [100, 100]
     
    # 球的移动速度,每帧15个像素
    speedx, speedy = 10, 10
     
    # 记录是否游戏结束
    gameover = False
     
    # 记录左右的击球数
    score = [0, 0]
     
     
    #(4)处理帧图像
    while True:
     
        # 返回是否读取成功,以及读取后的帧图像
        success, img = cap.read()  # 每次执行读取一帧
        
        # 图片翻转呈镜像关系,1代表左右翻转,0代表上下翻转
        img = cv2.flip(img, flipCode=1)
        
        # 手部关键点检测,返回每个只手的信息和绘制后的图像
        hands, img = detector.findHands(img, flipType=False)  # 上面翻转过了这里就不用翻转了
     
        # 将球桌图片和视频帧图像融合在一起, 两张图的shape要相同
        # 给出每张图片的融合权重, 亮度偏置为0,这样就变成了半透明的显示形式
        img = cv2.addWeighted(img, 0.4, imgDesk, 0.6, 0)
        
        
        #(5)处理手部关键点,如果检测到手了就进行下一步
        if hands:
            
            # 遍历每检测的2只手,获取每一只手的坐标
            for hand in hands:
                
                # 获取食指坐标(x,y,z)
                x, y, z = hand['lmList'][8]
                
                # 获取球拍的宽高
                h2, w1 = imgBlock1.shape[0:2]
                
                # 球拍的中心y坐标,随着掌心移动
                y1 = y - h2 // 2
     
                # 如果检测到了左手
                if hand['type'] == 'Left':
                    
                    # 左侧的球拍x轴固定,y坐标随左手掌间中点移动
                    img = cvzone.overlayPNG(img, imgBlock1, (100,y1))
                    
                    # 检查球是否被左球拍击中, 球的xy坐标是否在球拍xy坐标附近
                    if 100 < ballpos[0] < 100+w1 and y1 < ballpos[1] < y1+h2:
                        
                        # 满足条件代表球拍击中了,改变球的移动方向
                        speedx = -speedx  # x方向设为反方向
                        
                        # 得分加一
                        score[0] += 1
                    
                    
                # 如果检测到了右手
                if hand['type'] == 'Right':
                    
                    # 右侧的球拍x轴固定,y坐标随右手掌间中点移动
                    img = cvzone.overlayPNG(img, imgBlock2, (1150,y1))
                    
                    # 检查球是否被右球拍击中
                    if 1050 < ballpos[0] < 1050+w1 and y1 < ballpos[1] < y1+h2:
                        
                        # 满足条件代表球拍击中了,改变球的移动方向
                        speedx = -speedx  # x方向设为反方向
                        
                        # 得分加一
                        score[1] += 1
     
     
        #(6)检查球是否没接到,那么游戏结束
        if ballpos[0] < 50 or ballpos[0] > 1150:
            gameover = True
        
        # 游戏结束,画面就不动了
        if gameover is True:
            break
         
        # 游戏没结束就接下去执行
        else:
             #(7)调整球的坐标
             # 如果球的y坐标在超出了桌面的上或下边框范围,调整移动方向
             if ballpos[1] >= 600 or ballpos[1] <= 50:
                 
                 # y方向的速度调整为反方向,那么x方向和y方向的合速度方向调整了
                 speedy = -speedy
             
             # 每一整都调整xy坐标
             ballpos[0] = ballpos[0] + speedx  # 调整球的x坐标
             ballpos[1] = ballpos[1] + speedy  # 调整球的y坐标
        
             #(8)添加桌球的图片,将imgBall放在球桌img的指定坐标位置
             img = cvzone.overlayPNG(img, imgBall, ballpos)
        
        
        #(9)显示记分板
        cvzone.putTextRect(img, f'Left:{score[0]} and Right:{score[1]}', (400,710))
     
        #(10)图像展示
        cv2.imshow('img', img)
        # 每帧滞留1ms后消失
        k = cv2.waitKey(1)
        # ESC键退出程序
        if k & 0XFF==27:
            break
     
    # 释放视频资源
    cap.release()
    cv2.destroyAllWindows()

    效果图如下:

    如何用Python编写视觉桌上冰球小游戏

    本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系bd@zhengruan.com
    作者最新文章
    编程开发 Python
    相关文章 更多
    python删除一个列表里的重复元素的方法与代码示例
    python删除一个列表里的重复元素的方法与代码示例

    学习如何使用Python高效删除列表中的重复元素。本文提供5种常见方法的代码示例,涵盖保持顺序与不保持顺序的场景,适合初学者和进阶开发者参考。

    Python写接口的步骤及完整代码示例
    Python写接口的步骤及完整代码示例

    详细讲解使用Python编写Web接口的核心步骤与完整代码示例,涵盖环境准备、路由定义、数据校验、服务启动及调试测试方法。

    codex怎么读取word文档及docx文件操作教程
    codex怎么读取word文档及docx文件操作教程

    介绍如何利用编程工具读取和解析Word文档(docx格式),涵盖基础文本提取代码示例、结构化数据处理逻辑,以及处理复杂排版时的技术局限与替代方案。

    怎么在Python中调用C语言代码提升性能
    怎么在Python中调用C语言代码提升性能

    详细讲解在Python中调用C语言代码提升性能的完整实践指南,包含原理分析、编译步骤、ctypes与CFFI具体实现、性能对比及常见陷阱。

    Python与C语言的性能差异及底层原理
    Python与C语言的性能差异及底层原理

    深入解析Python与C语言在执行效率上的数量级差异,从编译机制、变量内存布局、动态类型推断到GIL锁,系统阐明底层核心原理。

    Python和C语言哪个更适合编程入门
    Python和C语言哪个更适合编程入门

    客观对比Python与C语言在心智负担、底层机制与学习反馈上的核心差异,提供清晰有据的选择标准与切实的入门学习路径。

    selenium上传文件教程本地文件路径设置方法
    selenium上传文件教程本地文件路径设置方法

    深入解析Selenium处理文件上传的技术细节,涵盖标准HTML控件的路径直接注入法与非标准控件的系统级模拟方案,提供Windows与Linux环境下的路径设置最佳实践及常见异常排查。

    大数据开发语言选型:Java对比Scala与Python的优缺点及适用场景
    大数据开发语言选型:Java对比Scala与Python的优缺点及适用场景

    针对大数据工程场景,系统对比Java、Scala与Python在执行性能、生态结合、开发效率和维护成本上的核心差异,给出清晰的架构选型依据与落地方案。

    langgraph python guide中文入门教程详解
    langgraph python guide中文入门教程详解

    本篇LangGraph Python中文入门教程详解,系统梳理StateGraph状态机定义、节点编写、边与条件路由、检查点持久化(MemorySaver)等核心机制,提供从环境安装到完整循环智能体构建的代码示例与实操指导。

    Windows 安装 Python:从官方入口到虚拟环境的可复现实践
    Windows 安装 Python:从官方入口到虚拟环境的可复现实践

    面向后端开发者,基于 Python 官方文档说明如何在 Windows 上安装 Python、创建 venv 虚拟环境及使用 pip 管理依赖。包含可复制命令、验证方法及工具选择边界,避免常见配置误区。

    查看更多
    精品专题 更多
    装机必备
    装机必备

    正软商城装机必备专区,精选办公、浏览器、安全防护、影音播放、压缩解压、设计创作和系统工具等电脑常用正版软件,帮助用户快速完成新电脑软件配置。

    Windows
    Windows

    正软商城Windows软件专区,汇集适用于Windows电脑的办公、设计、安全防护、影音播放、开发工具和系统优化软件,提供软件介绍、系统要求、正版授权及购买下载服务。

    PDF教程
    PDF教程

    正软商城PDF教程频道提供PDF编辑、转换、合并、拆分、压缩及格式处理方法,同时介绍常用PDF软件和工具的使用技巧。

    Mac软件 更多
    讯飞智作 网页版
    讯飞智作 网页版
    Windows/ macOS/ Linux

    讯飞智作是一款基于语音合成技术、虚拟人驱动技术与数字人形象声音构建能力的 AI 数字人音视频创作平台。

    火山引擎 网页版
    火山引擎 网页版
    Windows/ macOS/ Linux

    火山引擎是字节跳动旗下企业级云与AI服务平台。聚焦大模型核心能力,依托字节自研豆包多模态大模型,凭借火山方舟一站式平台,提供模型精调、推理部署、智能应用搭建等全链路服务,结合高性能AI算力,助力各行业快速落地大模型数字化与智能化应用。

    Aperty macOS版
    Aperty macOS版
    macOS

    Aperty 是 Skylum 推出的 AI 人像修图软件,支持自然肤质修饰、瑕疵处理、面部与身体调整、预设及批量同步。

    WINDOWS 更多
    讯飞智作 网页版
    讯飞智作 网页版
    Windows/ macOS/ Linux

    讯飞智作是一款基于语音合成技术、虚拟人驱动技术与数字人形象声音构建能力的 AI 数字人音视频创作平台。

    火山引擎 网页版
    火山引擎 网页版
    Windows/ macOS/ Linux

    火山引擎是字节跳动旗下企业级云与AI服务平台。聚焦大模型核心能力,依托字节自研豆包多模态大模型,凭借火山方舟一站式平台,提供模型精调、推理部署、智能应用搭建等全链路服务,结合高性能AI算力,助力各行业快速落地大模型数字化与智能化应用。

    PixTV 网页版
    PixTV 网页版
    Windows

    PixTV 是一款在浏览器中使用的 AI 视觉内容创作平台,提供图片、视频、音频、文字生成、AI 分镜、局部重绘、提示词反推和无限画布等工具,适合短剧、漫剧、广告及社交媒体内容制作。