Python 基于 OpenCV 视觉图像处理实战 之 OpenCV 简单人脸检测/识别实战案例 之七 简单进行人脸检测并添加面具特效实现

news2024/11/15 23:21:19

Python 基于 OpenCV 视觉图像处理实战 之 OpenCV 简单人脸检测/识别实战案例 之七 简单进行人脸检测并添加面具特效实现

目录

Python 基于 OpenCV 视觉图像处理实战 之 OpenCV 简单人脸检测/识别实战案例 之七 简单进行人脸检测并添加面具特效实现

一、简单介绍

二、简单进行人脸检测并添加面具特效实现原理方法

1. detect_faces(frame)

2. resize_mask(mask, face_width, face_height)

3. overlay_mask(mask, frame, face_x, face_y, face_width, face_height, offset_x=0, offset_y=0, angle=0)

三、简单进行人脸检测并添加面具特效实现案例实现简单步骤

四、注意事项


一、简单介绍

Python是一种跨平台的计算机程序设计语言。是一种面向对象的动态类型语言,最初被设计用于编写自动化脚本(shell),随着版本的不断更新和语言新功能的添加,越多被用于独立的、大型项目的开发。Python是一种解释型脚本语言,可以应用于以下领域: Web 和 Internet开发、科学计算和统计、人工智能、教育、桌面界面开发、软件开发、后端开发、网络爬虫。

这里使用 Python  基于 OpenCV 进行视觉图像处理,......

OpenCV 提供了一些已经训练好的级联分类器,这些级联分类器以XML文件的方式保存在以下路径中:

...\Python\Lib\site-packages\cv2\data\

OpenCV提供了一些经过预训练的人脸检测器模型文件,这些文件通常包含在OpenCV的安装包中。你也可以在OpenCV的官方GitHub页面或者OpenCV官方网站的下载页面找到这些模型文件的下载链接。

一般来说,你可以从以下位置获取OpenCV的预训练模型文件:

  •             OpenCV GitHub Release 页面:在 Releases · opencv/opencv · GitHub 找到你需要的版本,然后在下载的压缩包中找到位于 opencv\data 目录下的人脸检测器模型文件。
  •             OpenCV 官方网站下载页面:访问 OpenCV 官方网站 Releases - OpenCV ,下载你需要的版本,并在相应的压缩包中查找人脸检测器模型文件。

请确保下载与你使用的OpenCV版本兼容的模型文件。

该案例效果

二、简单进行人脸检测并添加面具特效实现原理方法

视频中检测人脸并添加特效是一种在视频流或视频文件中实时或离线检测人脸,并在检测到的人脸位置上添加各种视觉效果或特效的技术。这种技术通常用于视频编辑、增强现实、虚拟现实、社交媒体滤镜等应用中。

实现这种技术的一般步骤包括:

  1. 人脸检测: 首先,在每个视频帧中使用人脸检测算法检测人脸的位置和大小。常用的人脸检测算法包括Haar级联检测器、深度学习基于卷积神经网络的检测器等。

  2. 特效添加: 一旦检测到人脸,就可以在人脸位置上添加各种特效或效果。这些特效可以是图像、视频、动画等。例如,可以添加面具、滤镜、贴纸、变形等。

  3. 特效跟踪: 在视频中,人脸位置和姿态可能会随时间变化,因此需要在连续的视频帧之间跟踪人脸,并相应地调整添加的特效,以确保其与人脸保持一致。这可能需要使用跟踪算法,如光流法、卡尔曼滤波器等。

  4. 性能优化: 实时视频处理需要考虑性能问题,包括算法的速度、内存占用和电源消耗。因此,需要对算法进行优化,以实现快速和高效的视频处理。

  5. 用户交互: 对于一些应用,例如社交媒体滤镜,用户可能希望能够与添加的特效进行交互,例如调整特效的位置、大小、颜色等。因此,需要提供用户友好的界面来实现这种交互。

总的来说,视频中检测人脸并添加特效是一项复杂的技术,涉及多个步骤和算法,并需要综合考虑性能、用户体验和实时性等因素。

当我们运行此代码时,它首先打开视频文件。然后,它会逐帧读取视频,对每一帧进行以下处理:

  1. 人脸检测:

    • 使用OpenCV的Haar级联分类器来检测视频帧中的人脸。
    • 首先将视频帧转换为灰度图像,因为Haar级联分类器对灰度图像的效果更好。
    • 然后使用detectMultiScale方法在灰度图像中检测人脸,返回每个检测到的人脸的位置和尺寸。
  2. 面具叠加:

    • 对于每个检测到的人脸,计算人脸的中心坐标和尺寸。
    • 根据人脸的中心坐标和尺寸,在人脸的位置上叠加面具。
    • 面具的大小会根据人脸的尺寸进行调整,以确保与人脸尺寸匹配。
    • 如果检测到多个人脸,将为每个人脸叠加面具。
  3. 面具位置调整:

    • 通过按键控制面具在视频帧上的位置。
    • 按下键盘上的"W"、"A"、"S"、"D"键,分别向上、向左、向下、向右移动面具。
  4. 角度计算:

    • 尝试检测人脸区域中的眼睛位置。
    • 如果检测到两只眼睛,则计算两只眼睛的中心坐标,并根据它们的位置计算人脸的偏转角度。
    • 这个角度可以用来调整面具的旋转,使其与人脸的角度保持一致。
    • 角度计算是根据两只眼睛的位置确定的,因为眼睛通常是人脸的重要特征,角度计算的准确性取决于眼睛检测的准确性。

案例涉及到了以下关键函数:

  1. detect_faces(frame)
  2. resize_mask(mask, face_width, face_height)
  3. overlay_mask(mask, frame, face_x, face_y, face_width, face_height, offset_x=0, offset_y=0, angle=0)

下面对每个函数进行详细说明,包括参数、功能和返回值:

1. detect_faces(frame)

参数:

  • frame: 要检测人脸的视频帧,必须是BGR格式的图像。

功能:

  • 使用Haar级联分类器检测视频帧中的人脸。
  • 将视频帧转换为灰度图像,并在灰度图像中检测人脸。
  • 返回检测到的人脸区域的坐标和尺寸。

返回值:

  • faces: 检测到的人脸区域的列表,每个人脸由一个包含(x, y, w, h)四个元素的元组表示,分别表示人脸区域的左上角坐标和宽度、高度。

2. resize_mask(mask, face_width, face_height)

参数:

  • mask: 要调整大小的面具图像,必须是BGR格式的图像。
  • face_width: 人脸的宽度,即要调整的目标宽度。
  • face_height: 人脸的高度,即要调整的目标高度。

功能:

  • 调整面具的大小,使其与人脸尺寸匹配。

返回值:

  • 调整大小后的面具图像。

3. overlay_mask(mask, frame, face_x, face_y, face_width, face_height, offset_x=0, offset_y=0, angle=0)

参数:

  • mask: 要叠加到视频帧上的面具图像,必须是BGR格式的图像。
  • frame: 要叠加面具的视频帧,必须是BGR格式的图像。
  • face_x: 人脸的中心点的x坐标。
  • face_y: 人脸的中心点的y坐标。
  • face_width: 人脸的宽度。
  • face_height: 人脸的高度。
  • offset_x (可选): 面具在x方向上的偏移量,默认为0。
  • offset_y (可选): 面具在y方向上的偏移量,默认为0。
  • angle (可选): 面具的旋转角度,默认为0。

功能:

  • 将面具叠加到视频帧上,覆盖在人脸区域上。
  • 面具的位置会根据人脸中心点的位置和偏移量进行调整。
  • 可以通过旋转角度参数调整面具的旋转角度,使其与人脸的角度保持一致。

返回值:

  • 叠加面具后的视频帧。

在本例中,我们使用了基于人眼位置的简单方法来估计人脸的偏转方向,但是这种方法可能不够精确。如果需要更准确地估计人脸的旋转角度,可以考虑使用更高级的技术,比如基于人脸关键点的姿态估计算法,或者使用深度学习模型,例如人脸姿态估计的深度学习模型,比如3D人脸重建等。

人脸偏转角度的计算确实是一个比较复杂的问题,因为它涉及到人脸在三维空间中的旋转。常见的方法包括使用人脸关键点检测或者深度学习模型来获取人脸姿态。这些方法可以更准确地估计人脸的旋转角度,但是也更加复杂。

如果你希望更准确地估计人脸的旋转角度,可以尝试使用这些更高级的技术。

三、简单进行人脸检测并添加面具特效实现案例实现简单步骤

1、编写代码

2、运行效果

3、具体代码

"""
简单进行人脸检测并添加面具特效实现
    1、人脸检测:

        使用OpenCV的Haar级联分类器来检测视频帧中的人脸。
        首先将视频帧转换为灰度图像,因为Haar级联分类器对灰度图像的效果更好。
        然后使用detectMultiScale方法在灰度图像中检测人脸,返回每个检测到的人脸的位置和尺寸。

    2、面具叠加:

        对于每个检测到的人脸,计算人脸的中心坐标和尺寸。
        根据人脸的中心坐标和尺寸,在人脸的位置上叠加面具。
        面具的大小会根据人脸的尺寸进行调整,以确保与人脸尺寸匹配。
        如果检测到多个人脸,将为每个人脸叠加面具。

    3、面具位置调整:

        通过按键控制面具在视频帧上的位置。
        按下键盘上的"W"、"A"、"S"、"D"键,分别向上、向左、向下、向右移动面具。

    4、角度计算:

        尝试检测人脸区域中的眼睛位置。
        如果检测到两只眼睛,则计算两只眼睛的中心坐标,并根据它们的位置计算人脸的偏转角度。
        这个角度可以用来调整面具的旋转,使其与人脸的角度保持一致。
        角度计算是根据两只眼睛的位置确定的,因为眼睛通常是人脸的重要特征,角度计算的准确性取决于眼睛检测的准确性。
"""

import cv2
import numpy as np


def resize_mask(mask, face_width, face_height):
    """
    调整面具的大小以适应人脸的尺寸
    :param mask: numpy 数组,表示原始面具图像
    :param face_width: float,表示人脸的宽度
    :param face_height: float,表示人脸的高度
    :return: 调整后的面具图像
    """
    if mask is None or face_width <= 0 or face_height <= 0:
        return None

    mask_height, mask_width = mask.shape[:2]
    mask = cv2.resize(mask, (int(face_width), int(face_height)))
    return mask


def overlay_mask(mask, frame, face_x, face_y, face_width, face_height, offset_x=0, offset_y=0, angle=0):
    """
    将面具叠加到视频帧上
    :param mask: numpy 数组,表示面具图像
    :param frame: numpy 数组,表示视频帧图像
    :param face_x: float,表示人脸中心点的 x 坐标
    :param face_y: float,表示人脸中心点的 y 坐标
    :param face_width: float,表示人脸的宽度
    :param face_height: float,表示人脸的高度
    :param offset_x: 可选参数,表示在 x 方向上的偏移量,默认为0
    :param offset_y: 可选参数,表示在 y 方向上的偏移量,默认为0
    :param angle: 可选参数,表示旋转角度,默认为0
    :return: 叠加了面具的视频帧图像
    """
    if mask is None or frame is None or face_width <= 0 or face_height <= 0:
        return None

    # 获取面具的大小和位置
    mask_height, mask_width = mask.shape[:2]

    # 计算旋转后的面具图像
    mask_center = (mask_width // 2, mask_height // 2)
    mask_matrix = cv2.getRotationMatrix2D(mask_center, angle, 1)
    rotated_mask = cv2.warpAffine(mask, mask_matrix, (mask_width, mask_height))

    # 获取旋转后的面具覆盖的区域
    mask_y = int(face_y - face_height / 2 + offset_y)
    mask_y_end = int(mask_y + face_height)
    mask_x = int(face_x - face_width / 2 + offset_x)
    mask_x_end = int(mask_x + face_width)

    # 确保旋转后的面具图像在视频帧内
    mask_x_start = max(mask_x, 0)
    mask_x_end_clip = min(mask_x_end, frame.shape[1])
    mask_y_start = max(mask_y, 0)
    mask_y_end_clip = min(mask_y_end, frame.shape[0])

    mask_width_clip = mask_x_end_clip - mask_x_start
    mask_height_clip = mask_y_end_clip - mask_y_start

    mask_x_end_local = mask_width_clip + max(mask_x - mask_x_start, 0)
    mask_y_end_local = mask_height_clip + max(mask_y - mask_y_start, 0)

    mask_x_local = max(mask_x - mask_x_start, 0)
    mask_y_local = max(mask_y - mask_y_start, 0)

    # 调整面具大小
    resized_mask = resize_mask(rotated_mask, mask_width_clip, mask_height_clip)

    # 将面具叠加到视频帧上
    for c in range(0, 3):
        try:
            frame[mask_y_start:mask_y_end_clip, mask_x_start:mask_x_end_clip, c] = \
                resized_mask[mask_y_local:mask_y_end_local, mask_x_local:mask_x_end_local, c] * (
                            resized_mask[mask_y_local:mask_y_end_local, mask_x_local:mask_x_end_local, 3] / 255.0) + \
                frame[mask_y_start:mask_y_end_clip, mask_x_start:mask_x_end_clip, c] * (
                            1.0 - resized_mask[mask_y_local:mask_y_end_local, mask_x_local:mask_x_end_local, 3] / 255.0)
        except ValueError:
            pass

    return frame


def detect_faces(frame):
    """
    检测视频帧中的人脸
    :param frame: numpy 数组,表示视频帧图像
    :return: 包含检测到的人脸信息的列表
    """
    if frame is None:
        return []

    # 使用人脸检测器检测人脸
    face_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + 'haarcascade_frontalface_default.xml')
    eye_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + 'haarcascade_eye.xml')
    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
    faces = face_cascade.detectMultiScale(gray, scaleFactor=1.1, minNeighbors=5, minSize=(30, 30))

    # 获取人脸区域中的眼睛位置
    for (x, y, w, h) in faces:
        roi_gray = gray[y:y+h, x:x+w]
        eyes = eye_cascade.detectMultiScale(roi_gray)
        if len(eyes) >= 2:
            # 计算人脸的偏转角度
            eye_centers = np.array([(x + ex + ew // 2, y + ey + eh // 2) for (ex, ey, ew, eh) in eyes])
            angle = np.arctan2(eye_centers[1][1] - eye_centers[0][1], eye_centers[1][0] - eye_centers[0][0]) * 180 / np.pi

            angle = np.clip(angle, -45, 45)  # 将角度限制在[-45, 45]范围内
            print("angle = " + str(angle))
            return faces, angle
    return faces, 0


def main():
    # 加载面具图像
    mask = cv2.imread('Images/Cat_FaceMask.png', cv2.IMREAD_UNCHANGED)

    # 打开视频文件
    cap = cv2.VideoCapture('Videos/GirlFace.mp4')

    # 初始化面具位置偏移
    offset_x = 0
    offset_y = -65

    while True:
        # 读取一帧视频
        ret, frame = cap.read()
        if not ret:
            break

        # 检测人脸和角度
        faces, angle = detect_faces(frame)

        # 对每张人脸应用面具
        for (x, y, w, h) in faces:
            # 将面具叠加到人脸上
            # frame = overlay_mask(mask, frame, x + w // 2, y + h // 2, w, h, offset_x, offset_y, angle) # 这里变化太大,与视频不太符合,暂时不用
            frame = overlay_mask(mask, frame, x + w // 2, y + h // 2, w, h, offset_x, offset_y)

        # 显示结果
        cv2.imshow('Masked Faces', frame)

        # 检测按键输入
        key = cv2.waitKey(1)
        if key == ord('q'):  # 按 'q' 键退出
            break
        elif key == ord('w'):  # 上移面具
            offset_y -= 5
        elif key == ord('s'):  # 下移面具
            offset_y += 5
        elif key == ord('a'):  # 左移面具
            offset_x -= 5
        elif key == ord('d'):  # 右移面具
            offset_x += 5

    # 释放视频捕获对象
    cap.release()
    cv2.destroyAllWindows()


if __name__ == "__main__":
    main()

四、注意事项

  1. 参数安全校验:
    1. 对于函数的输入参数进行了必要的安全校验,确保输入参数的有效性和合理性,以避免程序崩溃或出现意外错误。
  2. 面具位置调整:
    1. 面具的位置可以通过按键进行调整,但需要确保面具不会超出视频帧的范围,否则会出现图像溢出或越界的情况。
  3. 角度计算:
    • 在计算人脸的偏转角度时,需要确保眼睛的检测是准确的,否则可能导致角度计算不准确。
    • 此外,还对计算得到的角度进行了限制,确保角度范围在[-45, 45]内,以避免面具旋转过度。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1630759.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

ChatGPT记忆功能终于上线了, OpenAI 官方:用得越久越聪明!

原文 ChatGPT记忆功能终于上线了, OpenAI 官方&#xff1a;用得越久越聪明&#xff01; Aitrainee | 公众号&#xff1a;AI进修生 &#x1f31f; 记得今年2月份OpenAI发布过ChatGPT上线记忆功能的消息&#xff0c;我记得当时还弹出过这个窗口给我&#xff0c;但是仅仅体验了几…

centos7 openresty lua 自适应webp和缩放图片

目录 背景效果图准备安装cwebp等命令&#xff0c;转换文件格式安装ImageMagick&#xff0c;压缩文件下载Lua API 操控ImageMagick的依赖包 代码参考 背景 缩小图片体积&#xff0c;提升加载速度&#xff0c;节省流量。 效果图 参数格式 &#xff1a; ?image_processformat,…

C语言之详细讲解文件操作

什么是文件 与普通文件载体不同&#xff0c;文件是以硬盘为载体存储在计算机上的信息集合&#xff0c;文件可以是文本文档、图片、程序等等。文件通常具有点三个字母的文件扩展名&#xff0c;用于指示文件类型&#xff08;例如&#xff0c;图片文件常常以KPEG格式保存并且文件…

idea创建完项目如何隐藏不重要的文件

如果您不打算直接使用这些脚本&#xff0c;而是更倾向于通过IDEA的内置工具来运行Maven命令&#xff0c;那么您可以选择隐藏这些文件。但是&#xff0c;隐藏这些文件并不会影响它们的功能&#xff0c;只是在项目视图中不再显示它们。 1.转到 File > Settings&#xff08;Wi…

信息系统项目管理师——第7章项目立项管理

本章考选择题2-3分&#xff0c;案例和论文均有可能作为领域考试。 项目建议与立项申请♥♥♥♥♥ 立项申请的概念 立项申请又称为项目建议书&#xff0c;是项目建设单位向上级主管部门提交项目申请时所必须的文 件&#xff0c;是该项目建设筹建单位根据国民经济的发展、国家…

Spark高可用模式和Spark分布式Yarn环境安装

Spark分布式HA环境安装 图-12 高可用模式原理 因为在目前情况下&#xff0c;集群中只有一个Master&#xff0c;如果master挂掉&#xff0c;便无法对外提供新的服务&#xff0c;显然有单点故障问题&#xff0c;解决方法就是master的ha。 有两种方式解决单点故障&#xff0c;一…

无脑入单向无头链表的实现| ArrayList和LinkedList的区别

1. ArrayList的缺陷 上节课已经熟悉了ArrayList的使用&#xff0c;并且进行了简单模拟实现。通过源码知道&#xff0c;ArrayList底层使用数组来存储元素。 由于其底层是一段连续空间&#xff0c;当 在 ArrayList 任意位置插入或者删除元素时&#xff0c;就需要将后序元素整体往…

如何使用docker部署前端项目

账号&#xff1a;root 密码&#xff1a;*** 主机&#xff1a;ip地址 登录后&#xff1a; 初级名词&#xff1a; sudo 是Linux和类Unix操作系统中的一个命令&#xff0c;全称为“super user do”&#xff0c;用于允许普通用户以超级用户(root)的身份执行某些或全部命令 需要下…

【python】简单实现遍历文件夹和子文件夹重命名

个人简介 &#x1f468;&#x1f3fb;‍&#x1f4bb;个人主页&#xff1a;九黎aj &#x1f3c3;&#x1f3fb;‍♂️幸福源自奋斗,平凡造就不凡 &#x1f31f;如果文章对你有用&#xff0c;麻烦关注点赞收藏走一波&#xff0c;感谢支持&#xff01; &#x1f331;欢迎订阅我的…

sql注入漏洞及其sqlmap工具的使用

一、sql注入的原理 sql注入概念&#xff1a; sql注入主要是将sql语句&#xff0c;插入到web表单提交或者输入域名或者页面请求的查询字符串&#xff0c;最 终 达到一个欺骗服务器执行sql语句的效果。 sql注入的原理&#xff1a;主要分为平台层注入和代码层注入两种原因 …

TechTool Pro for mac中文激活版:硬件监测和系统维护工具

TechTool Pro mac帮助用户实现系统硬件监测&#xff08;CPU、内存、硬盘、网络、USB等&#xff09;、内存测试、S.M.A.R.T检测、磁盘宗卷扫描、宗卷重建和优化、数据恢复和粉碎等等&#xff0c;定期使用&#xff0c;可以确保您的Mac保持优化和无故障。 TechTool Pro for mac v1…

(学习日记)2024.04.19:UCOSIII第四十七节:各文件夹功能介绍

之前的章节都是针对某个或某些知识点进行的专项讲解&#xff0c;重点在功能和代码解释。 回到最初开始学μC/OS-III系统时&#xff0c;当时就定下了一个目标&#xff0c;不仅要读懂&#xff0c;还要读透&#xff0c;改造成更适合中国宝宝体质的使用方式。在学完野火的教程后&a…

JavaScript操作DOM实现页面元素更改

DOM是什么 DOM&#xff08;文档对象模型&#xff09;是一种用于表示和操作HTML、XML文档的标准编程接口。它将文档中的每个元素、属性、文本和事件都表示为对象&#xff0c;从而可以使用JavaScript等脚本语言来操作和修改文档的结构、样式和内容。 DOM 将文档表示为一个树状结…

AI绘画的算法原理:从生成模型到Diffusion

近年来&#xff0c;AI绘画技术引起了广泛关注&#xff0c;让我们深入探讨其背后的技术原理和发展历程。本文将以通俗易懂的方式&#xff0c;介绍AI绘画的核心算法&#xff0c;从生成模型到Diffusion。 1. 计算机如何生成图画&#xff1f; AI绘画的核心在于生成模型&#xff08…

【平台开发】MTK6833 实现lk下CQE接口移植 - cmdq request

1.函数调用图 对应协议上结构为&#xff1a; 2.函数拆解 cmdq_request: 1)配置task_desc和tran_desc参数 2)EN_CQHCI_IRQ 3)write CQTDBR cmdq_prep_task_desc: 设置task_desc参数 cmdq_set_tran_desc: 设置tran_desc参数

Elasticsearch下载

1 最新版下载地址 Download Elasticsearch | Elastic https://www.elastic.co/cn/downloads/elasticsearch 2 其他版本下载地址 https://www.elastic.co/cn/downloads/past-releases#elasticsearch 7.9.2:https://artifacts.elastic.co/downloads/elasticsearch/elasticsear…

github two-factor authentication是个啥?

最近在逛github时&#xff0c;总是时不时会弹出一下界面&#xff0c;很烦 看到红框里的文字&#xff0c;这明显是强制要求做这个认证&#xff0c;如果不认证4天后账号将不可访问&#xff0c;所以今天花点时间看看怎么做这个认证&#xff0c;点“Enable 2FA now”进入这个界面&a…

LVGL移植

Lvgl介绍 LVGL是一个开源的图形库&#xff0c;专为嵌入式系统设计。它提供了丰富的图形元素和功能&#xff0c;可以帮助开发者快速构建现代化的用户界面。LVGL具有跨平台的特性&#xff0c;支持多种操作系统和硬件平台&#xff0c;包括ARM Cortex-M&#xff0c;ESP32&#xff…

【Protobuf】protobuf详细介绍

protobuf详细介绍 一、前言二、Protobuf简介2.1、核心思想2.2、Protobuf是如何工作的&#xff1f;2.3、如何使用 Protoc 生成代码&#xff1f;2.4 入门命令 一、前言 在以往的项目中进行网络通信和数据交换的应用场景中&#xff0c;最经常使用的技术便是json或xml。随着JSON的…

flac转wav怎么转?4种简单又快速的方法~

FLAC&#xff08;Free Lossless Audio Codec&#xff09;是一种无损音频编解码器&#xff0c;它可以将音频压缩成较小的文件大小而不损失任何音频质量。因此&#xff0c;将FLAC文件转换为WAV&#xff08;Waveform Audio File Format&#xff09;格式不会损失音频质量&#xff0…