[前端面包]别动我的摄像头!Tensorflow下的图像分类识别

06-01 1612阅读

"嘀——检测到人类,危险系数:996加班脸"

        深度学习一直是个很热的话题,作为一个前端程序员,我开始思考如何在Web中集成图像识别的技术,通过网页判断摄像头前方的是人还是鬼,对物体进行分类;

   首先是根据需求选择适合的技术方案:

  • 轻量级任务(如颜色检测、边缘识别):使用传统计算机视觉库(如OpenCV.js)

  • 复杂任务(如物体分类、人脸识别):使用深度学习框架(如TensorFlow.js)或预训练模型

  • 高精度需求:调用云服务API(如Google Cloud Vision)

    对于前端网页的集成,我们可以使用Google的TensorFlow进行深度学习的模型推理;他内置了WebGL的后端,可以使运算和识别的速度更快,我们先从初始的MobileNet开始讲起

    MobileNet


    MobileNets 是一个小型、低延迟、低功耗的模型,其参数可满足各种使用情况下的资源限制;它们可用于分类、检测、嵌入和分割,与其他流行的大规模模型(如 Inception)的使用方式类似

    计算延迟度

    [前端面包]别动我的摄像头!Tensorflow下的图像分类识别

    参数数量比较图

    [前端面包]别动我的摄像头!Tensorflow下的图像分类识别

    运用


    我们可以用两种方法引入MobileNet库:

    script标签引入:

     
    
     
    
    [前端面包]别动我的摄像头!Tensorflow下的图像分类识别
    
    
      //这里不需要导入语句
      const img = document.getElementById('img');
      //加载模型
      mobilenet.load().then(model => {
        //分辨图片
        model.classify(img).then(predictions => {
          console.log('Predictions: ');
          console.log(predictions);
        });
      });
    

    NPM包引入:

    npm install @tensorflow/tfjs
    npm install @tensorflow-models/mobilenet

    API


    加载模型

    mobilenet是module的name,所以ES6语法中引入script时不需要加上type="module"

    mobilenet.load({
        version: 1,//版本信息
        alpha?: 0.25 | .50 | .75 | 1.0,//模型参数,数字越大分辨能力越强
        modelUrl?: string//模型地址
        inputRange?: [number, number]//输入范围(可选)
      }
    )

    开始识别

    在MobileNet中你可以使用classify识别方法识别五种对象:

    • Tensor3D
    • ImageData
    • HTMLImageElement
    • HTMLCanvasElement
    • HTMLVideoElement
      model.classify(
        img: tf.Tensor3D | ImageData | HTMLImageElement |
            HTMLCanvasElement | HTMLVideoElement,
        topk?: number
      )

      识别出来的结果为Promise数组:

      [{

      className:"  ",//预测对象

      probability:"   "//置信度

      }] 

      迁移学习 

      你可以使用infer函数来获取图像的嵌入式来进行迁移学习,嵌入的大小取决于模型的alpha参数

      model.infer(
        img: tf.Tensor3D | ImageData | HTMLImageElement |
            HTMLCanvasElement | HTMLVideoElement,
        embedding = false
      )

      使用示例


      基于图像的识别 

      [前端面包]别动我的摄像头!Tensorflow下的图像分类识别

      
      
          
          
          Document
          
          
      
      
          

      TensorFlow.js MobileNet

      [前端面包]别动我的摄像头!Tensorflow下的图像分类识别
      import '@tensorflow/tfjs-backend-cpu';
      import '@tensorflow/tfjs-backend-webgl';
      import * as mobilenet from '@tensorflow-models/mobilenet';
      //定义初始信息
      const img = document.getElementById('img')
      const result = document.getElementById('result')
      const version=2//版本信息
      const alpha=0.5//模型大小
      //异步加载模型
      async function run(){
          const model=await mobilenet.load({version,alpha})//加载模型
          //预测图片
          const predictions = await model.classify(img)
          console.log(predictions)
          //解构数组
          const [prediction1,prediction2,prediction3] = predictions
          result.innerHTML = `
          

      预测结果:${prediction1.className}

      预测概率:${(prediction1.probability*100).toFixed(2)}%

      预测结果:${prediction2.className}

      预测概率:${(prediction2.probability*100).toFixed(2)}%

      预测结果:${prediction3.className}

      预测概率:${(prediction3.probability*100).toFixed(2)}%

      ` //获取预测概率 const logits = model.infer(img) console.log(logits) logits.print(true) //获取特征值 const embeddings =model.infer(img,true) console.log(embeddings) embeddings.print(true) } run()

      基于摄像头的识别

      对于网页端摄像头,我们需要编写初始化摄像头组件,通过getUserMedia获取摄像头信息

      [前端面包]别动我的摄像头!Tensorflow下的图像分类识别

      
      
          浏览器端MobileNet识别
          
          
      
      
          
          
          
              let net;
              let webcamElement = document.getElementById('webcam');
              let predictionsElement = document.getElementById('predictions');
              async function setupWebcam() {
                  const stream = await navigator.mediaDevices.getUserMedia({ video: true });
                  webcamElement.srcObject = stream;
                  return new Promise((resolve) => {
                      webcamElement.onloadedmetadata = () => resolve();
                  });
              }
              async function loadModel() {
                  net = await mobilenet.load({ version: 2, alpha: 1.0 });
                  console.log('MobileNet模型加载完成');
              }
              async function predict() {
                  const predictions = await net.classify(webcamElement);
                  predictionsElement.innerHTML = predictions
                      .map(p => `${p.className} (${Math.round(p.probability * 100)}%)`)
                      .join('
      '); requestAnimationFrame(predict); } (async () => { await setupWebcam(); await loadModel(); predict(); })();

      MobileNet已经可以满足基础的使用,但是却有几个缺点:

      1. 识别精准度不高,只能识别物体
      2. 返回对象只有预测对象和置信度,无法获取具体轮廓

      所以为了深化学习,我们可以使用其他模型进行运算:YOLO、COCO-SSD ,下面我以COCO-SSD作为举例

      COCO-SSD 


      COCOSSD通过轻量级卷积神经网络作为基础网络,用特征图实现锚框,NMS去除重复检测,具有高效性,适用性广的特点

      运用


      我们同样可以使用两种方法使用COCOSSD

      script标签引入:

       
      
       
      
      [前端面包]别动我的摄像头!Tensorflow下的图像分类识别
      
      
        const img = document.getElementById('img');
        //加载模型
        cocoSsd.load().then(model => {
          //检测图片上的对象
          model.detect(img).then(predictions => {
            console.log('Predictions: ', predictions);
          });
        });
      

      NPM包引入:

      //我们需要WebGL作为后端,并将其添加到package.json作为前置依赖项
      require('@tensorflow/tfjs-backend-cpu');
      require('@tensorflow/tfjs-backend-webgl');
      const cocoSsd = require('@tensorflow-models/coco-ssd');
      (async () => {
        const img = document.getElementById('img');
        const model = await cocoSsd.load();
        const predictions = await model.detect(img);
        console.log('Predictions: ');
        console.log(predictions);
      })();

      API


      加载模型

      跟MobileNet的使用方式相同,在使用ES6语法后coco-ssd是module语法

      export interface ModelConfig {
        base?: ObjectDetectionBaseModel;
      //原始模型,可以为'mobilenet_v1','mobilenet_v2'或者'lite_mobilenet_v2'
      //默认是lite_mobilenet_v2
      //lite_mobilenet_v2加载速度最快,体量最轻,mobilenet_v2识别最准
        modelUrl?: string;//模型路径
      }
      cocoSsd.load(config: ModelConfig = {});

      开始识别

      于MobileNet不同的是,COCOSSD多了两个参数

      1. maxNumBoxes: 画面上识别的最大对象框数
      2. minScore:展示对象框的最小置信度,值为0~1,默认为0.5
      model.detect(
        img: tf.Tensor3D | ImageData | HTMLImageElement |
            HTMLCanvasElement | HTMLVideoElement, maxNumBoxes: number, minScore: number
      )

      识别的对象为Promise对象数组:

      [{
        bbox: [x, y, width, height],//坐标起点,对象框的宽和高
        class: "person",//预测对象
        score: 0.8380282521247864//置信度
      }, {
        bbox: [x, y, width, height],
        class: "kite",
        score: 0.74644153267145157
      }]

       高阶用法

      该模型是基于Tensorflow的对象检测API,你可以从这里下载原始模型;Cocossd在此基础上进行了下列优化以提高浏览器的执行性能

      1. 删除原始模型的后处理图
      2. 使用单类NMS而不是原始的多类NMS
      3. 在CPU后端执行NMS操作,避免纹理下载延迟

       tensorflowjs_converter --input_format=tf_frozen_model \

                             --output_format=tfjs_graph_model \

                             --output_node_names='Postprocessor/ExpandDims_1,Postprocessor/Slice' \

                             ./frozen_inference_graph.pb \

                             ./web_model

      使用示例


      基于图片的识别

      import '@tensorflow/tfjs-backend-cpu';
      import '@tensorflow/tfjs-backend-webgl';
      import * as cocoSsd from '@tensorflow-models/coco-ssd';
      import imageURL from './image1.jpg';
      import image2URL from './image2.jpg';
      let modelPromise;
      window.onload = () => modelPromise = cocoSsd.load();
      const button = document.getElementById('toggle');
      button.onclick = () => {
        image.src = image.src.endsWith(imageURL) ? image2URL : imageURL;
      };
      const select = document.getElementById('base_model');
      select.onchange = async (event) => {
        const model = await modelPromise;
        model.dispose();
        modelPromise = cocoSsd.load(
            {base: event.srcElement.options[event.srcElement.selectedIndex].value});
      };
      const image = document.getElementById('image');
      image.src = imageURL;
      const runButton = document.getElementById('run');
      runButton.onclick = async () => {
        const model = await modelPromise;
        console.log('model loaded');
        console.time('predict1');
        const result = await model.detect(image);
        console.timeEnd('predict1');
        const c = document.getElementById('canvas');
        const context = c.getContext('2d');
        context.drawImage(image, 0, 0);
        context.font = '10px Arial';
        console.log('number of detections: ', result.length);
        for (let i = 0; i  10 ? result[i].bbox[1] - 5 : 10);
        }
      };

      描绘对象框

      [前端面包]别动我的摄像头!Tensorflow下的图像分类识别

      async drawBox(imageElement, predictions) {
        const canvas = document.getElementById('canvas');
        const context = canvas.getContext('2d');
        //设定canvas尺寸
        canvas.width = imageElement.width;
        canvas.height = imageElement.height;
        //在图像上画图
        context.drawImage(imageElement, 0, 0, canvas.width, canvas.height);
        for (let prediction of predictions) {
          const [x, y, width, height] = prediction.bbox;
          const text = `${prediction.class} (${(prediction.score * 100).toFixed(2)}%)`;
          //边框
          context.strokeStyle = 'yellow';
          context.lineWidth = 8;
          context.strokeRect(x, y, width, height);
          //字体样式
          context.font = '28px Arial';
          context.fillStyle = 'yellow';
          //文字宽度和高度
          const textWidth = context.measureText(text).width;
          const textHeight = 28 * 1.5;
          const padding = 8;
          //文字背景框
          context.fillStyle = 'white';
          context.fillRect(x - padding, y - 20 - textHeight - padding, textWidth + padding * 2, textHeight + padding * 2);
          /画文字
          context.fillStyle = 'black'; // 文字顏色
          context.fillText(text, x + padding / 2, y - 10 - textHeight / 2);
        }
        
      }

      本段代码及图片转载自August

      结语

      轻量级的模型使用可以用cocossd来进行场景识别,大家可以跟着敲一遍,了解开箱即用的MobileNet,以及进阶使用大模型训练

      “前端也能干深度学习的活!”

免责声明:我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理! 图片声明:本站部分配图来自人工智能系统AI生成,觅知网授权图片,PxHere摄影无版权图库和百度,360,搜狗等多加搜索引擎自动关键词搜索配图,如有侵权的图片,请第一时间联系我们。

相关阅读

目录[+]

取消
微信二维码
微信二维码
支付宝二维码