前端也能玩人工智能—猫猫在哪里?

一起用代码吸猫!本文正在参与【喵星人征文活动】

屏幕快照 2021-11-14 下午1.10.47.png

ml5.js 和 p5.js 都是旨在为创意编程提供开箱即用的库,不过 ml5 是专注于机器学习,为一些出身前端工程师无需深入了解机器学习就可以玩一玩AI。

该库封装了常用的机器学习算法和预训练模型,基于TensorFlow.js,可单独使用,也可搭配p5.js使用。

object_detection_001.png

什么是目标检测

希望将 AI 带到你手边,让你觉得他并不是深不可测、绕不可及。所以这里我们不去聊个过深,首先介绍一下什么是目标检测,我们可能知道什么是分类问题,也就是给模型一张图片,图片中只有一个我们感兴趣的类别,是一只狗或者是一只猫,模型经过预测输出一个图片类别,告诉图片是一张狗图片还是一张猫图片这样就是分类器。

而今天谈目标检测,多目标检测则不同,是输入一张可能有多个类别的图像,图片不再只是一只狗或者一只猫,可能是多只狗或者猫和狗,目标检测模型不但给出图像所包含类别还会用边框将标出其所在位置,这就目标检测,接下来我们就用 ml5.js 实现一个目标检测,检测出猫猫来。

如何选择预训练模型

一个模型好坏,数据是其天花板,近些年所以涌现出 ResNet Inception GoogleNet 这些优秀的模型和 ImageNet 这个 200 万张 1000 个分类的数据集是分不开的。ml5.js 通常使用预训练好模型,那么我们选择模型时候就需要关心 2 件事,第一个模型基于什么网络,是 MobileNet 还是 ResNet 还是 VGG 呀,这个是我们关心,因为不同网络模型可能应用场景和解决问题能力不同,存在差异,然后看一看是基于什么数据集训练,COCO 是一个比较经典的数据,提供很丰富数据集用于不同类型任务,例如语义分割、关键点,姿态等等。

在 ml5.js 对于目标检测提供两个预训练模型 YOLO 和 COCOSsd, 这里就选择 COCOSsd,这里 COCO 80 类别,其中应该包括今天主角猫咪。

搭建环境

这里我们 p5.js 简单搭建环境

function setup() {
  createCanvas(640, 480);
}

function draw(){
  background(0);
}

复制代码

读取图片

let img;


function preload(){
  img = loadImage('dog_and_cat_03.jpeg');
}

function setup() {
  createCanvas(640, 480);
  image(img,0,0);
}

复制代码

p5.js 如果大家还不熟悉,可以看看官方文档,比较简单。其实不用看文档,通过上面 code 也是一目了然,p5.js 设计的,代码可读性还是比较好的,

屏幕快照 2021-11-14 下午1.48.19.png

创建检测器

let img;
let detector;

function preload(){
  img = loadImage('dog_and_cat_03.jpeg');
  detector = ml5.objectDetector('cocossd');
}

function setup() {
  createCanvas(640, 480);
  console.log(detector);
  image(img,0,0);
}

复制代码

创建一个目标检测器,传入我们要使用预训练模型,这里选择了 cocossd。然后就是使用检测器去检测上面图片。

开始检测

let img;
let detector;

function preload(){
  img = loadImage('dog_and_cat_03.jpeg');
  detector = ml5.objectDetector('cocossd');
}

function hanldeDetectResult(error,results){
  if(error){
    console.log(error);
  }
  console.log(results);
  
}

function setup() {
  createCanvas(640, 480);
  // console.log(detector);
  image(img,0,0);
  detector.detect(img,hanldeDetectResult);
}
复制代码

获取目标检测器,这个一个对象,调用 detect 方法,这个方法接受 2 个参数分别是要检测的图像和一个接受处理检测结果的回调函数。因为检测是一个耗时过程,可能需要等待一会儿,

waiting.gif

检测结果信息


1.  0:
1.  1.  confidence: 0.9443305134773254
    1.  height: 297.570499420166
    1.  label: "dog"
    1.  normalized: {x0.3297404646873474y0.13195198774337769width0.3925212621688843height0.6888206005096436}
    1.  width: 301.4563293457031
    1.  x: 253.2406768798828
    1.  y: 57.00325870513916
    1.  [[Prototype]]: Object
1.  1:
1.  1.  confidence: 0.9138157963752747
    1.  height: 334.8041739463806
    1.  label: "cat"
    1.  normalized: {x0.08691723644733429y0.09776231646537781width0.31792615354061127height0.7750096619129181}
    1.  width: 244.16728591918945
    1.  x: 66.75243759155273
    1.  y: 42.23332071304321
    
复制代码

种类简单解释一下

  • cnfidence 表示模型对于其给出结果的信心程度,越高越好,有时候我们可以设置 threshold 将模型把握度不大结果去掉
  • height/width 目标边框的宽和高
  • x, y 目标左上角,这个结果根据实际情况而定,不同框架或者模型可能解析结果不同,也可能是中心点
  • label 就是返回类别结果

接下来工作就是提供数据,将这些分类信息和位置信息绘制到图像上了。

  for (let i = 0; i < results.length; i++) {
    let object = results[i];
    stroke(0, 255, 0);
    strokeWeight(4);
    noFill();
    rect(object.x, object.y, object.width, object.height);
    noStroke();
    fill(255);
    textSize(24);
    text(object.label, object.x + 10, object.y + 24);
  }
复制代码

猜你喜欢

转载自juejin.im/post/7030307248257630245