AI之眼:图像识别的新篇章与创新应用

91 阅读5分钟

前言

在数字化时代,人工智能的发展正以前所未有的速度改变着我们的生活方式和工作方式。其中,图像识别技术作为人工智能的重要组成部分,正逐渐走进我们日常生活的方方面面。本文将介绍一个简单的Web端AI图像识别应用,旨在帮助读者了解和体验这一令人惊叹的技术。 在这个Web应用中,我们将介绍如何利用人工智能模型来识别上传的图像中的物体、场景或人物。我们将探讨使用的技术、工具和资源,并演示如何构建一个简单而强大的图像识别系统。通过这个例子,读者将了解到图像识别技术的基本原理和实际应用,并有机会自己动手尝试构建和部署一个AI图像识别应用。 无论您是对人工智能技术感兴趣的新手,还是希望了解如何将其应用于实际项目的开发者,本文都将为您提供一个简单而实用的入门指南。让我们一起探索这个充满潜力的领域,体验人工智能为我们带来的惊喜与便利。

HTML结构

部分包含了一些页面的元数据,比如字符集、视口设置和标题。 部分定义了页面的样式,包括上传按钮的样式、图片容器的样式以及边界框的样式等。 <body> 部分包含了页面的主体内容,其中<main>元素定义了页面中的主要内容,并指定了类名为container,用于样式控制。 <label> 元素定义了一个文件上传按钮,并指定了对应的文件上传控件的id为file-upload。当用户点击上传按钮时,会触发文件上传控件的点击事件。 <div id="image-container"> 定义了一个图片容器,用于显示上传的图片以及识别出的物体边界框。 在HTML文件的头部,设置了页面的基本信息,包括标题和字符编码,以及视口的设置。 定义了一些CSS样式,包括容器的布局、文件上传按钮的样式、图片容器的样式以及检测框和标签的样式。 在页面主体内容中,创建了一个容器(class为"container"),包含一个文件上传的标签和一个空的图片容器(id为"image-container"),以及一个用于显示状态信息的段落(id为"status")。

JS部分

'renderBox'函数

根据识别结果的边界框信息,创建一个

元素,并设置其样式以及边界框的位置和大小。 创建一个元素用于显示物体标签,并设置其样式。 将边界框和物体标签添加到图片容器中,从而在页面上显示出识别结果的边界框和标签。
1. JavaScript代码部分使用了ES6模块化语法。首先,通过import语句引入了一个用于NLP任务的模型管道和环境对象。然后,设置了环境对象envallowLocalModels属性为false,以确保不会使用本地模型。

  1. 通过document.getElementById获取了文件上传和图片容器的DOM元素。
  2. 添加了文件上传的change事件监听器。当用户选择文件后,会读取文件,并将其转换成数据URL形式的图片,并创建一个img元素,将图片显示在页面上,并调用detect函数对图片进行对象检测。
  3. detect函数使用异步操作,首先更新状态信息为"分析中...",然后通过模型管道创建一个对象检测器,指定了检测器的模型为"Xenova/detr-resnet-50"。之后,调用检测器对图片进行对象检测,并设置了阈值为0.1,返回结果以百分比形式。最后,对每个检测到的对象调用renderBox函数进行渲染。

代码展示

    * @func 文件上传和对象检测功能
    * @desc 实现了图片上传功能,并利用Transformer模型进行对象检测,并在图片上标记检测到的对象
    * @author [Your Name]
    * @data 2024-04-17
-->
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>nlp之图片识别,两种语言</title>
  <!-- CSS 样式 -->
  <style>
    .container {
      margin: 40px auto;
      width: max(50vw, 400px);
      display: flex;
      flex-direction: column;
      align-items: center;
    }

    .custom-file-upload {
      display: flex;
      align-items: center;
      cursor: pointer;
      gap: 10px;
      border: 2px solid black;
      padding: 8px 16px;
      border-radius: 6px;
    }

    #file-upload {
      display: none;
    }

    #image-container {
      width: 100%;
      margin-top: 20px;
      position: relative;
    }

    #image-container>img {
      width: 100%;
    }

    .bounding-box {
      position: absolute;
      box-sizing: border-box;
    }

    .bounding-box-label {
      position: absolute;
      color: white;
      font-size: 12px;
    }
  </style>
</head>

<body>
  <!-- 页面主体内容 -->
  <main class="container">
    <label for="file-upload" class="custom-file-upload">
      <input type="file" accept="image/*" id="file-upload">
      上传图片
    </label>
    <div id="image-container"></div>
    <p id="status"></p>
  </main>

  <!-- JavaScript 代码 -->
  <script type="module">
    // 导入transformers nlp任务的pipeline和env对象
    import { pipeline, env } from "https://cdn.jsdelivr.net/npm/@xenova/transformers@2.6.0"
    // 允许本地模型
    env.allowLocalModels = false;

    // 获取文件上传和图片容器元素
    const fileUpload = document.getElementById('file-upload');
    const imageContainer = document.getElementById('image-container')

    // 监听文件上传事件
    fileUpload.addEventListener('change', function (e) {
      const file = e.target.files[0];
      const reader = new FileReader();
      reader.onload = function (e2) {
        const image = document.createElement('img');
        image.src = e2.target.result;
        imageContainer.appendChild(image)
        detect(image)
      }
      reader.readAsDataURL(file)
    })

    // 获取状态信息元素
    const status = document.getElementById('status');

    // 检测图片的AI任务
    const detect = async (image) => {
      status.textContent = "分析中..."
      const detector = await pipeline("object-detection", "Xenova/detr-resnet-50")
      const output = await detector(image.src, {
        threshold: 0.1,
        percentage: true
      })
      output.forEach(renderBox)
    }

    // 渲染检测框函数
    function renderBox({ box, label }) {
      const { xmax, xmin, ymax, ymin } = box
      const boxElement = document.createElement("div");
      boxElement.className = "bounding-box"
      Object.assign(boxElement.style, {
        borderColor: '#123123',
        borderWidth: '1px',
        borderStyle: 'solid',
        left: 100 * xmin + '%',
        top: 100 * ymin + '%',
        width: 100 * (xmax - xmin) + "%",
        height: 100 * (ymax - ymin) + "%"
      })

      const labelElement = document.createElement('span');
      labelElement.textContent = label;
      labelElement.className = "bounding-box-label"
      labelElement.style.backgroundColor = '#000000'

      boxElement.appendChild(labelElement);
      imageContainer.appendChild(boxElement);
    }
  </script>
</body>

</html>

结果展示

image.png