likes
comments
collection
share

NPL的图片检测——成为24年的AI Native开发者!

作者站长头像
站长
· 阅读数 2

简言

作为一名前端的学习者,我们要记住编程效率永远是大厂程序员的追求,我们在进行html编码时要学会使用emet快速输入,并非逐个字符按部就班的去敲,有自己的风格特点和效率很重要!

Step1

既然是要检测出图片内容,势必要上传图片,我们可以构建一个简单的HTML表单,用于图片的上传

        <label for="file-upload" class="custom-file-upload">
            <!-- <input type="file" id="file-upload" accept="image/*"> -->
            <input type="file" accept="image/*" id="file-upload">
            上传图片
        </label>

class="custom-file-upload" 是一个自定义的CSS类,可用于样式定制,这是一个 <input> 元素,type 属性为 "file",表示这是一个文件上传输入框。accept="image/*" 属性指定了文件类型,限制用户只能选择图片文件进行上传。id 属性为 "file-upload",与上面的 <label> 元素的 for 属性对应,以便实现点击标签时触发文件上传的功能。

Step2

使用transformers来进行npl任务,

       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) {
            // console.log(e.target.files[0]);

            const file = e.target.files[0];
            
            const reader = new FileReader();
  1. import { pipeline, env } from "https://cdn.jsdelivr.net/npm/@xenova/transformers@2.6.0": 这是一个 ECMAScript 模块导入语句,它从指定的 CDN 地址导入了模块 @xenova/transformers 中的 pipelineenv 两个成员。

  2. env.allowLocalModels = false;: 设置了 env 对象的 allowLocalModels 属性为 false。这个属性可能是模块 @xenova/transformers 中的一个配置选项,用于控制是否允许使用本地模型。

  3. const fileUpload = document.getElementById('file-upload');const imageContainer = document.getElementById('image-container'): 分别获取了页面中 id 为 file-uploadimage-container 的两个元素,并将它们分别赋值给了变量 fileUploadimageContainer

  4. fileUpload.addEventListener('change', function (e) { ... }: 给 fileUpload 元素添加了一个事件监听器,监听 change 事件。当用户选择了文件并且文件选择完成后,将触发这个事件,执行事件处理函数。

  5. const file = e.target.files[0];: 在事件处理函数中,获取了用户选择的文件,并将其赋值给了变量 file。通常,用户选择的文件是一个 File 对象,通过 e.target.files[0] 来获取。

Step3

进行图片的加载和运行,启动ai任务 将功能模块化,封装出去

            const reader = new FileReader();
                reader.onload = function (e2) {
                // 读完了, 加载完成
                const image = document.createElement('img'); // 图片对象
                console.log(e2.target.result);
                image.src = e2.target.result;
                imageContainer.appendChild(image)
                detect(image) 
            }
  1. const reader = new FileReader();: 创建了一个 FileReader 对象,用于读取文件内容。
  2. reader.onload = function (e2) { ... }: 给 FileReader 对象的 onload 属性赋值了一个函数。这个函数将在文件加载完成后被调用。e2 是一个事件对象,它包含了文件加载的相关信息。
  3. const image = document.createElement('img');: 创建了一个 <img> 元素,用于在页面上显示加载的图片。
  4. console.log(e2.target.result);: 打印了 FileReader 对象的 result 属性,这个属性包含了读取到的文件内容。在这里,result 应该是图片的二进制数据或者是一个数据 URL。

Step4

进行图片的读取

       const status = document.getElementById('status');
        // 检测图片的AI任务
        const detect = async (image) => {
            status.textContent = "分析中..."
            const detector = await pipeline("object-detection",
                "Xenova/detr-resnet-50") // model 实例化了detector对象
            const output = await detector(image.src, {
                threshold: 0.1,
                percentage: true
            })
            // console.log(output);
            output.forEach(renderBox)
        }
  1. imageContainer.appendChild(image): 将创建的 <img> 元素添加到了页面中 id 为 image-container 的容器元素中,以显示加载的图片。
  2. detect(image): 调用了 detect 函数,并将加载的图片作为参数传递给了这个函数。这个函数是一个用于处理图像的功能,它接受一个图片对象作为输入,然后执行一些操作,是对图像进行处理、分析或其他操作。

Step4

创建读取边界框

         function renderBox({ box, label }) {
            console.log(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) + "%"
            })
  1. boxElement.className = "bounding-box": 将新创建的 <div> 元素的 className 属性设置为 "bounding-box",这样可以应用预定义的 CSS 样式来美化这个边界框。
  2. Object.assign(boxElement.style, { ... }): 使用 Object.assign 方法,将一个包含 CSS 样式属性和值的对象应用到 boxElement.style 上,从而设置边界框的样式。
  3. 在对象中设置了边界框的样式,包括边框颜色、边框宽度、边框样式以及边界框在父元素内的位置和大小,这些样式属性的值都是根据传入的 box 对象中的数据计算得到的,用于确定边界框的位置和大小。

Step5

最后用于显示标签

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

            boxElement.appendChild(labelElement);
            imageContainer.appendChild(boxElement);

        }
  1. boxElement.appendChild(labelElement);: 将标签元素 <span> 添加到之前创建的边界框元素 <div> 中。这样,标签将显示在边界框内部。
  2. imageContainer.appendChild(boxElement);: 将边界框元素 <div> 添加到页面中 id 为 image-container 的容器元素中。这样,整个边界框及其标签就被添加到了页面中。

Step6

展示效果图,

NPL的图片检测——成为24年的AI Native开发者!

NPL的图片检测——成为24年的AI Native开发者!

OK!读取成功!长安可能对代码的解读不是那么准确,希望大佬们多多指教。