Python实现Labelme的Json标注文件与YOLO格式的TXT标注文件相互转换

news2024/11/26 3:42:57

Python实现Labelme的Json标注文件与YOLO格式的TXT标注文件相互转换

  • 前言
  • 前提条件
  • 相关介绍
  • 实验环境
  • Labelme的Json标注文件与YOLO格式的TXT标注文件相互转换
    • convert_labelme_json_to_txt
      • jsons/000000000009.json
      • 代码实现
      • 输出结果
      • labels/000000000009.txt
    • convert_txt_to_labelme_json
      • labels/000000000009.txt
      • 代码实现
      • 输出结果
      • jsons/000000000009.json
  • 参考

在这里插入图片描述

前言

  • 由于本人水平有限,难免出现错漏,敬请批评改正。
  • 更多精彩内容,可点击进入Python日常小操作专栏、OpenCV-Python小应用专栏、YOLO系列专栏、自然语言处理专栏或我的个人主页查看
  • 基于DETR的人脸伪装检测
  • YOLOv7训练自己的数据集(口罩检测)
  • YOLOv8训练自己的数据集(足球检测)
  • YOLOv5:TensorRT加速YOLOv5模型推理
  • YOLOv5:IoU、GIoU、DIoU、CIoU、EIoU
  • 玩转Jetson Nano(五):TensorRT加速YOLOv5目标检测
  • YOLOv5:添加SE、CBAM、CoordAtt、ECA注意力机制
  • YOLOv5:yolov5s.yaml配置文件解读、增加小目标检测层
  • Python将COCO格式实例分割数据集转换为YOLO格式实例分割数据集
  • YOLOv5:使用7.0版本训练自己的实例分割模型(车辆、行人、路标、车道线等实例分割)
  • 使用Kaggle GPU资源免费体验Stable Diffusion开源项目

前提条件

  • 熟悉Python

相关介绍

  • Python是一种跨平台的计算机程序设计语言。是一个高层次的结合了解释性、编译性、互动性和面向对象的脚本语言。最初被设计用于编写自动化脚本(shell),随着版本的不断更新和语言新功能的添加,越多被用于独立的、大型项目的开发。
  • PyTorch 是一个深度学习框架,封装好了很多网络和深度学习相关的工具方便我们调用,而不用我们一个个去单独写了。它分为 CPU 和 GPU 版本,其他框架还有 TensorFlow、Caffe 等。PyTorch 是由 Facebook 人工智能研究院(FAIR)基于 Torch 推出的,它是一个基于 Python 的可续计算包,提供两个高级功能:1、具有强大的 GPU 加速的张量计算(如 NumPy);2、构建深度神经网络时的自动微分机制。
  • YOLOv5是一种单阶段目标检测算法,该算法在YOLOv4的基础上添加了一些新的改进思路,使其速度与精度都得到了极大的性能提升。它是一个在COCO数据集上预训练的物体检测架构和模型系列,代表了Ultralytics对未来视觉AI方法的开源研究,其中包含了经过数千小时的研究和开发而形成的经验教训和最佳实践。
  • YOLO格式标签是目标检测任务中常用的标注格式之一。YOLO格式标注文件由目标框的中心点坐标、宽度和高度组成。具体来说,YOLO格式标注文件的每一行都包含了一个目标的标注信息,其中第一个数字表示目标的类别,后面四个数字分别表示目标框的中心点坐标(x_center, y_center)和宽度w以及高度h,这些值都是相对于图像宽度和高度的比例
  • 例如,下面是一个YOLO格式标注文件的示例:
    在这里插入图片描述
  • 其中,第一行表示一个类别为45的目标,其中心点坐标为图像宽度的0.749891和0.255612,宽度和高度分别为图像宽度和高度的0.477249和0.511224;第二行表示一个类别为50的目标,其中心点坐标为图像宽度的0.64458和0.722577,宽度和高度分别为图像宽度和高度的0.492199和0.513077。
  • Labelme是一款图像标注工具,由麻省理工(MIT)的计算机科学和人工智能实验室(CSAIL)研发。它是用Python和PyQT编写的,开源且免费。Labelme支持Windows、Linux和Mac等操作系统。
  • 这款工具提供了直观的图形界面,允许用户在图像上标注多种类型的目标,例如矩形框、多边形、线条等,甚至包括更复杂的形状。标注结果以JSON格式保存,便于后续处理和分析。这些标注信息可以用于目标检测、图像分割、图像分类等任务。
  • 总的来说,Labelme是一款强大且易用的图像标注工具,可以满足不同的图像处理需求。

实验环境

  • Python 3.x (面向对象的高级语言)

Labelme的Json标注文件与YOLO格式的TXT标注文件相互转换

  • 背景:Labelme仍市面上是一款主流的免费图像标注工具,比如可以用其来进行目标检测、图像分割等的标注,目前,还是有很多数据集标注文件是Labelme格式,因此,实现Labelme的Json标注文件与YOLO格式的TXT标注文件相互转换,是非常有必要的。
  • 目录结构
    在这里插入图片描述

convert_labelme_json_to_txt

在这里插入图片描述

jsons/000000000009.json

{
    "version": "4.5.7",
    "flags": {},
    "shapes": [
        {
            "label": "45",
            "score": 0.99,
            "group_id": null,
            "shape_type": "rectangle",
            "flags": {},
            "points": [
                [
                    1.0799999999999699,
                    187.69008
                ],
                [
                    612.66976,
                    473.53008
                ]
            ]
        },
        {
            "label": "45",
            "score": 0.99,
            "group_id": null,
            "shape_type": "rectangle",
            "flags": {},
            "points": [
                [
                    311.73024,
                    4.310160000000001
                ],
                [
                    631.01024,
                    232.99032
                ]
            ]
        },
        {
            "label": "50",
            "score": 0.99,
            "group_id": null,
            "shape_type": "rectangle",
            "flags": {},
            "points": [
                [
                    249.60032000000007,
                    229.27032
                ],
                [
                    565.84032,
                    474.35016
                ]
            ]
        },
        {
            "label": "45",
            "score": 0.99,
            "group_id": null,
            "shape_type": "rectangle",
            "flags": {},
            "points": [
                [
                    0.0003200000000092018,
                    13.510080000000002
                ],
                [
                    434.48032,
                    388.63007999999996
                ]
            ]
        },
        {
            "label": "49",
            "score": 0.99,
            "group_id": null,
            "shape_type": "rectangle",
            "flags": {},
            "points": [
                [
                    376.2,
                    40.35996
                ],
                [
                    451.75007999999997,
                    86.88996
                ]
            ]
        },
        {
            "label": "49",
            "score": 0.99,
            "group_id": null,
            "shape_type": "rectangle",
            "flags": {},
            "points": [
                [
                    465.7797119999999,
                    38.969952
                ],
                [
                    523.849728,
                    85.63996800000001
                ]
            ]
        },
        {
            "label": "49",
            "score": 0.99,
            "group_id": null,
            "shape_type": "rectangle",
            "flags": {},
            "points": [
                [
                    385.70016000000004,
                    73.65983999999999
                ],
                [
                    469.72,
                    144.16992
                ]
            ]
        },
        {
            "label": "49",
            "score": 0.99,
            "group_id": null,
            "shape_type": "rectangle",
            "flags": {},
            "points": [
                [
                    364.04959999999994,
                    2.4900960000000016
                ],
                [
                    458.80992,
                    73.559856
                ]
            ]
        }
    ],
    "imagePath": "000000000009.jpg",
    "imageData": null,
    "imageHeight": 480,
    "imageWidth": 640
}

代码实现

import json
import os
import glob
from tqdm import tqdm


def convert_poly_to_rect(coordinateList):
    X = [int(coordinateList[2 * i]) for i in range(int(len(coordinateList) / 2))]
    Y = [int(coordinateList[2 * i + 1]) for i in range(int(len(coordinateList) / 2))]

    Xmax = max(X)
    Xmin = min(X)
    Ymax = max(Y)
    Ymin = min(Y)
    flag = False
    if (Xmax - Xmin) == 0 or (Ymax - Ymin) == 0:
        flag = True
    return [Xmin, Ymin, Xmax - Xmin, Ymax - Ymin], flag

def convert_labelme_json_to_txt(json_path,img_path,out_txt_path):
    json_list = glob.glob(json_path + '/*.json')
    num = len(json_list)
    for json_path in tqdm(json_list):
        with open(json_path, "r")as f_json:
            json_data = json.loads(f_json.read())
        infos = json_data['shapes']
        if len(infos) ==0:
            continue
        img_w = json_data['imageWidth']
        img_h = json_data['imageHeight']
        image_name = json_data['imagePath']
        image_path = os.path.join(img_path, image_name)
        if not os.path.exists(img_path):
            print(img_path, 'is None!')
            continue
        txt_name = os.path.basename(json_path).split('.')[0] + '.txt'
        txt_path = os.path.join(out_txt_path, txt_name)
        f = open(txt_path, 'w')
        for label in infos:
            points = label['points']
            if len(points) < 2:
                continue

            if len(points) == 2:
                x1 = points[0][0]
                y1 = points[0][1]
                x2 = points[1][0]
                y2 = points[1][1]
                points = [[x1, y1], [x2, y1], [x2, y2], [x1, y2]]
            else:
                if len(points) < 4:
                    continue

            segmentation = []
            for p in points:
                segmentation.append(int(p[0]))
                segmentation.append(int(p[1]))

            bbox, flag = convert_poly_to_rect(list(segmentation))
            x1, y1, w, h = bbox

            if flag:
                continue

            x_center = x1 + w/2
            y_center = y1 + h/2
            norm_x = x_center / img_w
            norm_y = y_center / img_h
            norm_w = w / img_w
            norm_h = h / img_h
            obj_cls = label['label']
            line = [obj_cls, norm_x, norm_y, norm_w, norm_h]
            line = [str(ll) for ll in line]
            line = ' '.join(line) + '\n'
            f.write(line)
        f.close()

if __name__ == "__main__":
    img_path = 'images'
    json_path = 'jsons'
    out_txt_path = 'labels'

    if not os.path.exists(out_txt_path):
        os.makedirs(out_txt_path)
    
    convert_labelme_json_to_txt(json_path,img_path,out_txt_path)

输出结果

在这里插入图片描述

labels/000000000009.txt

45 0.47890625 0.6875 0.9546875 0.5958333333333333
45 0.7359375 0.24583333333333332 0.5 0.475
50 0.6359375 0.7322916666666667 0.49375 0.5104166666666666
45 0.3390625 0.41770833333333335 0.678125 0.78125
49 0.64609375 0.13125 0.1171875 0.09583333333333334
49 0.771875 0.128125 0.090625 0.09791666666666667
49 0.6671875 0.22604166666666667 0.13125 0.14791666666666667
49 0.6421875 0.078125 0.146875 0.14791666666666667

convert_txt_to_labelme_json

在这里插入图片描述

labels/000000000009.txt

45 0.47890625 0.6875 0.9546875 0.595833
45 0.7359375 0.24583333333333332 0.5 0.475
50 0.6359375 0.7322916666666667 0.49375 0.5104166
45 0.3390625 0.41770833333333335 0.678125 0.78125
49 0.64609375 0.13125 0.1171875 0.095833
49 0.771875 0.128125 0.090625 0.0979166
49 0.6671875 0.22604166666666667 0.13125 0.1479166
49 0.6421875 0.078125 0.146875 0.1479166

代码实现

import os
import cv2
import json
import glob
import numpy as np

def convert_txt_to_labelme_json(txt_path, image_path, output_dir, image_fmt='.jpg'):
    # txt 转labelme json
    # 将yolo的txt转labelme json
    txts = glob.glob(os.path.join(txt_path, "*.txt"))
    for txt in txts:
        labelme_json = {
            'version': '4.5.7',
            'flags': {},
            'shapes': [],
            'imagePath': None,
            'imageData': None,
            'imageHeight': None,
            'imageWidth': None,
        }
        txt_name = os.path.basename(txt)
        image_name = txt_name.split(".")[0] + image_fmt
        labelme_json['imagePath'] = image_name
        image_name = os.path.join(image_path, image_name)
        if not os.path.exists(image_name):
            raise Exception('txt 文件={},找不到对应的图像={}'.format(txt, image_name))
        image = cv2.imdecode(np.fromfile(image_name, dtype=np.uint8), cv2.IMREAD_COLOR)
        h, w = image.shape[:2]
        labelme_json['imageHeight'] = h
        labelme_json['imageWidth'] = w
        with open(txt, 'r') as t:
            lines = t.readlines()
            for line in lines:
                content = line.split(' ')
                label = content[0]
                object_width = float(content[3])
                object_height = float(content[4])
                top_left_x = (float(content[1]) - object_width / 2) * w
                top_left_y = (float(content[2]) - object_height / 2) * h
                bottom_right_x = (float(content[1]) + object_width / 2) * w
                bottom_right_y = (float(content[2]) + object_height / 2) * h
                try:
                    shape = {
                        'label': str(label),
                        'score':float(content[5]),
                        'group_id': None,
                        'shape_type': 'rectangle',
                        'flags': {},
                        'points': [
                            [float(top_left_x), float(top_left_y)],
                            [float(bottom_right_x), float(bottom_right_y)]
                        ]
                    }
                except Exception as e:
                    # print(e)
                    shape = {
                        'label': str(label),
                        'score':float(0.99),
                        'group_id': None,
                        'shape_type': 'rectangle',
                        'flags': {},
                        'points': [
                            [float(top_left_x), float(top_left_y)],
                            [float(bottom_right_x), float(bottom_right_y)]
                        ]
                    }
                labelme_json['shapes'].append(shape)
            json_name = txt_name.split('.')[0] + '.json'
            json_name_path = os.path.join(output_dir, json_name)
            fd = open(json_name_path, 'w')
            json.dump(labelme_json, fd, indent=4)
            fd.close()
            print("save json={}".format(json_name_path))


if __name__=="__main__":
    in_imgs_dir = 'images'
    in_label_txt_dir = 'labels'
    out_labelme_json_dir = 'jsons'

    if not os.path.exists(out_labelme_json_dir):
        os.mkdir(out_labelme_json_dir)
    convert_txt_to_labelme_json(in_label_txt_dir,in_imgs_dir,out_labelme_json_dir,image_fmt='.jpg')

输出结果

在这里插入图片描述

jsons/000000000009.json

{
    "version": "4.5.7",
    "flags": {},
    "shapes": [
        {
            "label": "45",
            "score": 0.99,
            "group_id": null,
            "shape_type": "rectangle",
            "flags": {},
            "points": [
                [
                    1.0799999999999699,
                    187.69008
                ],
                [
                    612.66976,
                    473.53008
                ]
            ]
        },
        {
            "label": "45",
            "score": 0.99,
            "group_id": null,
            "shape_type": "rectangle",
            "flags": {},
            "points": [
                [
                    311.73024,
                    4.310160000000001
                ],
                [
                    631.01024,
                    232.99032
                ]
            ]
        },
        {
            "label": "50",
            "score": 0.99,
            "group_id": null,
            "shape_type": "rectangle",
            "flags": {},
            "points": [
                [
                    249.60032000000007,
                    229.27032
                ],
                [
                    565.84032,
                    474.35016
                ]
            ]
        },
        {
            "label": "45",
            "score": 0.99,
            "group_id": null,
            "shape_type": "rectangle",
            "flags": {},
            "points": [
                [
                    0.0003200000000092018,
                    13.510080000000002
                ],
                [
                    434.48032,
                    388.63007999999996
                ]
            ]
        },
        {
            "label": "49",
            "score": 0.99,
            "group_id": null,
            "shape_type": "rectangle",
            "flags": {},
            "points": [
                [
                    376.2,
                    40.35996
                ],
                [
                    451.75007999999997,
                    86.88996
                ]
            ]
        },
        {
            "label": "49",
            "score": 0.99,
            "group_id": null,
            "shape_type": "rectangle",
            "flags": {},
            "points": [
                [
                    465.7797119999999,
                    38.969952
                ],
                [
                    523.849728,
                    85.63996800000001
                ]
            ]
        },
        {
            "label": "49",
            "score": 0.99,
            "group_id": null,
            "shape_type": "rectangle",
            "flags": {},
            "points": [
                [
                    385.70016000000004,
                    73.65983999999999
                ],
                [
                    469.72,
                    144.16992
                ]
            ]
        },
        {
            "label": "49",
            "score": 0.99,
            "group_id": null,
            "shape_type": "rectangle",
            "flags": {},
            "points": [
                [
                    364.04959999999994,
                    2.4900960000000016
                ],
                [
                    458.80992,
                    73.559856
                ]
            ]
        }
    ],
    "imagePath": "000000000009.jpg",
    "imageData": null,
    "imageHeight": 480,
    "imageWidth": 640
}

参考

[1] https://blog.csdn.net/lucky404/article/details/132156805
[2] https://blog.csdn.net/h609232722/article/details/130710032

  • 由于本人水平有限,难免出现错漏,敬请批评改正。
  • 更多精彩内容,可点击进入Python日常小操作专栏、OpenCV-Python小应用专栏、YOLO系列专栏、自然语言处理专栏或我的个人主页查看
  • 基于DETR的人脸伪装检测
  • YOLOv7训练自己的数据集(口罩检测)
  • YOLOv8训练自己的数据集(足球检测)
  • YOLOv5:TensorRT加速YOLOv5模型推理
  • YOLOv5:IoU、GIoU、DIoU、CIoU、EIoU
  • 玩转Jetson Nano(五):TensorRT加速YOLOv5目标检测
  • YOLOv5:添加SE、CBAM、CoordAtt、ECA注意力机制
  • YOLOv5:yolov5s.yaml配置文件解读、增加小目标检测层
  • Python将COCO格式实例分割数据集转换为YOLO格式实例分割数据集
  • YOLOv5:使用7.0版本训练自己的实例分割模型(车辆、行人、路标、车道线等实例分割)
  • 使用Kaggle GPU资源免费体验Stable Diffusion开源项目

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

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

相关文章

Flink(一)【WordCount 快速入门】

前言 学完了 Hadoop、Spark&#xff0c;本想着先把 Kafka、Flume 这些工具先学完的&#xff0c;但想了想还是把核心的技术先学完最后再去把那些工具学学。 最近心有点累哈哈哈&#xff0c;偷偷立个 flag&#xff0c;反正也没人看&#xff0c;明年的今天来这里还愿哈&#xff0c…

C语言100~200中不能整除3的数

#define _CRT_SECURE_NO_WARNINGS 1#include <stdio.h> int main() {int n;for (n 100; n < 200; n){if (n%3 0){continue;}printf("%d\n",n);}}

RFC使用与WebService

RFC连接 CSDN RFC中引用类型组 http://t.csdnimg.cn/wQWAYhttp://t.csdnimg.cn/wQWAY 远程目标系统维护SM59 这里的类型指的是目标系统的系统类型(目标系统即rfc函数存在的系统). 类型2&#xff08;R/2连接&#xff09;&#xff0c;只需给出主机名&#xff0c;所有通信信息…

软件系统设计方法和工具介绍

软件系统设计方法和工具介绍 在构建系统时&#xff0c;尤其是一些大项目实施的过程中&#xff0c;可以接触和学习一些高阶层面分析问题和系统架构的方法论&#xff0c; 如麦肯锡的解决问题7步法&#xff1a;定义问题、分解问题、排定优先级、制定工作计划、分析问题、综合分析…

比SAM小60倍的分割一切模型:MobileSAM

1 MobileSAM SAM就是一类处理图像分割任务的通用模型。与以往只能处理某种特定类型图片的图像分割模型不同&#xff0c;SAM可以处理所有类型的图像。 在SAM出现前&#xff0c;基本上所有的图像分割模型都是专有模型。比如&#xff0c;在医学领域&#xff0c;有专门分割核磁图…

Python批量下载ERA5数据

1. ERA5数据简介 ERA5是第五代ECMWF大气再分析全球气候数据(ECMWF)&#xff0c;该数据集的第一部分现在可以公开使用(1979年到3个月内)。ERA5数据提供每小时的大气、陆地和海洋气候变量的估计值&#xff0c;地球数据精确到了30km网格&#xff0c;包括了137层的大气数据。 网址…

【教3妹学编程-算法题】最大单词长度乘积

3妹&#xff1a;哇&#xff0c;今天好冷啊&#xff0c; 不想上班。 2哥&#xff1a;今天气温比昨天低8度&#xff0c;3妹要空厚一点啊。 3妹 : 嗯&#xff0c; 赶紧把我的羽绒服找出来穿上&#xff01; 2哥&#xff1a;哈哈&#xff0c;那倒还不至于&#xff0c; 不过气温骤降&…

使用Anaconda安装TensorFlow环境以及没有搜到的报错的解决方法

1.在官网下载Anaconda 这一步几乎不会有人报错 下稳定的版本 或者最新的版本都可以 2.TensorFlow分两个版本 一个是用cpu跑 另一个是用gpu跑 显而易见 cpu的计算性能已经比不上现在主流的显卡了 所以有独显的电脑尽量安装gpu版本 CPU版本: 先给出cpu版本的安装方法: 打开A…

体坛巨星商业价值完美呈现,B体育等超巨品牌堪称经典案例

近几年&#xff0c;伴随着互联网的发展&#xff0c;我们惊喜的发现体坛巨星的商业代言越来越多&#xff0c;他们代言的广告已经融入到我们的生活之中&#xff0c;陪伴很多人度过了美妙的时刻。越来越多的品牌也意识到&#xff0c;比起娱乐明星&#xff0c;体坛巨星的全球属性对…

EMS员工管理系统 python

python基础练习&#xff0c;简单的增删改查&#xff0c;涉及python基础语法&#xff0c;逻辑、分支结构以及一些基础数据格式的操作&#xff0c;文件操作&#xff0c;思路理解等等 部分代码如下 print(""*20,"欢迎使用员工管理系统",""*20)# em…

浏览器自动播放音视频-前端实现方案

目录 前言 浏览器自动播放策略 策略详情&#xff1a; 实现方案 方案1&#xff1a; 互动后播放 方案2&#xff1a; 互动后出声 总结 前言 在开发中可能有遇到这样的需求&#xff0c;当用户打开页面后&#xff0c;需要自动播放视频或音频&#xff0c;按理说那就打开页面…

Vue2和Vue3生命周期映射关系及异同

生命周期映射关系表 beforeCreate -> 使用 setup() created -> 使用 use setup() beforeMount ->onBeforeMount mounted -> onMounted beforeUpdate -> onBeforeUpdate updated -> onUpdated beforeDestroy-> onBeforeUnmount destroyed ->onUnmounted…

800*A. Domino piling(规律数学)

Problem - 50A - Codeforces #include<bits/stdc.h> using namespace std; const int N1e55; int n,m,res; signed main(){scanf("%d%d",&n,&m);if(n>1){resn/2*m;n%2; }if(n1) resm/2;cout<<res;return 0; }

WPS表格无法粘贴信息,原因是复制区域与粘贴区域形状不同

WPS表格无法粘贴信息&#xff0c;原因是复制区域与粘贴区域形状不同 问题描述 我是选中了一整列&#xff0c;复制&#xff0c;但是无法粘贴到另一个EXCEL表格中 原因 首先我的数据量很大&#xff0c;有20万行&#xff0c;然后需要复制的EXCEL是.xls格式的&#xff0c;.xls格…

缓解缓存击穿的大杀器之---singleflight深入浅出

singleflight简单介绍 singlefight直译“单飞”&#xff0c;那顾名思义就是有一堆鸟&#xff0c;但是咱只让一只鸟单飞。。。&#x1f604; singleflight 提供了重复函数调用抑制机制&#xff0c;使用它可以避免同时进行相同的函数调用。第一个调用未完成时后续的重复调用会等…

20231106_抽象类abstract

抽象类abstract 关键字 abstract运用抽象类抽象方法:修饰抽象类中的某个方法,强制子类重写该方法 归纳 关键字 abstract 对于子类必须要实现特定方法,当时父类无法明确时,可定义为抽象类及抽象方法 不合理: 动物吃东西是基础,在这里写吃的方法过于简单,信息没有实际意义; 怎…

FSDiffReg:心脏图像的特征和分数扩散引导无监督形变图像配准

论文标题&#xff1a; FSDiffReg: Feature-wise and Score-wise Diffusion-guided Unsupervised Deformable Image Registration for Cardiac Images 翻译&#xff1a; FSDiffReg&#xff1a;心脏图像的特征和分数扩散引导无监督形变图像配准 摘要 无监督可变形图像配准是医学…

人工智能:技术进步与未来趋势

人工智能&#xff1a;技术进步与未来趋势 随着科技的快速发展&#xff0c;人工智能(AI)已经深入影响到我们生活的方方面面。从智能手机、自动驾驶汽车&#xff0c;到医疗诊断、工业自动化&#xff0c;AI的应用越来越广泛。这篇文章将探讨人工智能的技术发展、现状以及未来趋势。…

Webpack 中 Plugin 的作用是什么?常用 plugin 有哪些?

说说webpack中常见的Plugin&#xff1f;解决了什么问题&#xff1f;- 题目详情 - 前端面试题宝典 1、plugin 的作用 Plugin 是一种计算机应用程序&#xff0c;它和主应用程序互相交互&#xff0c;以提供特定的功能。 是一种遵循一定规范的应用程序接口编写出来的程序&#…