图片识别少不了画框,前端画框就用canvas,后端返回画框数据点,图片可以是前端自己传的也可以是后端返回的。
实现思路:
1、算好比例尺
2、确定上、左位置,确定宽高(后端如果给上下左右,前端自行计算宽高)
3、图片预加载时画图
4、注意 js 的乘除会有出入,所以要精确化处理

效果图

实现代码:

<template><div class="carDetect"><div class="uploadImg"><el-button type="primary">上传图片</el-button><input type="file" class="upload" @change="uploadImg($event)" /></div><div class="faceCon"><div class="canvasCon"><canvas width="800" height="400" ref="canvas"></canvas></div><div class="faceInfo"><divv-for="(item, index) in imgCarArr":key="index":class="index == activeIndex ? 'active' : ''"><img:class="index == activeIndex ? 'active' : ''":src="item"alt=""@click="showCarInfo(index)"/></div></div><veri-car :carData="carOneData" :visibleCar.sync="visibleCar"></veri-car><!-- <div class="faceInfo"><divv-for="(item, index) in imgArr":key="index":class="index == activeIndex ? 'active' : ''"><img:class="index == activeIndex ? 'active' : ''":src="item"alt=""@click="showFaceInfo(index)"/></div></div><veri-car-face:faceData="faceOneData":visible.sync="visible"></veri-car-face> --></div><canvas v-for="i in canvasLength" :key="i" :id="'canvas' + i"></canvas></div>
</template>
<script>
var div = require("../../../utils/accDiv.js");
var mul = require("../../../utils/accMul.js");
//使用用户上传图片画图时需要做的处理
uploadImg(el) {this.faceOneData = {};this.carOneData = {};if (!el.target.files[0].size) return; // 如果文件大小为0,则返回if (el.target.files[0].type.indexOf("image/png") === -1 &&el.target.files[0].type.indexOf("image/jpeg") === -1 &&el.target.files[0].type.indexOf("image/svg") === -1) {// 如果不是图片格式this.$message.warning("请选择文件为png/jpg格式的图片");} else {const that = this;const reader = new FileReader(); // 创建读取文件对象reader.readAsDataURL(el.target.files[0]); // 发起异步请求,读取文件reader.onload = function() {that.value = this.result;};this.getFaceInfo(el.target.files[0]);}},
// 正式画图
drawFace(data) { //data就是后端返回的数据this.imgCarArr = []; //存放框出来的每一个具体图片this.canvasLength = data.length; //多个框时候用来遍历展示var canvas = this.$refs.canvas;  //获取元素实例var context = canvas.getContext("2d");  //getContext() 方法返回一个用于在画布上绘图的环境。var ratioX = ""; //X轴比例尺var ratioY = ""; //Y轴比例尺context.clearRect(0, 0, 800, 400); //画布大小和起止点var newImg = new Image(); //创建一个Image对象newImg.src = this.value;  //返回的图片地址,或者自己上传的base64图片newImg.onload = () => { //img.onload 实现图片预加载ratioX = div.accDiv(canvas.width, newImg.width);  ratioY = div.accDiv(canvas.height, newImg.height);context.drawImage(newImg, 0, 0, canvas.width, canvas.height); //drawImage() 方法在画布上绘制图像、画布或视频。data.forEach((item, index) => { //如果返回数据只有一个框,可以不循环context.beginPath();if (item.faceInfoParam) {let facePosition =item.faceInfoParam.faceDetectInfoParam.face_position;context.rect( //rect() 方法创建矩形mul.accMul(ratioX, facePosition.left), //精确计算乘(比例尺*坐标点)mul.accMul(ratioY, facePosition.top),mul.accMul(ratioX, facePosition.width),mul.accMul(ratioY, facePosition.height));context.lineWidth = 1;context.strokeStyle = "#0f0";context.stroke();context.closePath();// 获取人脸部分var imageData = context.getImageData(mul.accMul(ratioX, facePosition.left),mul.accMul(ratioY, facePosition.top),mul.accMul(ratioX, facePosition.width),mul.accMul(ratioY, facePosition.height));// 人脸关键点item.faceInfoParam.faceDetectInfoParam.syPointParams.forEach( //遍历返回值(v, i) => {context.beginPath();context.arc( //arc() 方法创建弧/曲线(用于创建圆或部分圆),中心:arc(100,75,50,0*Math.PI,1.5*Math.PI)mul.accMul(ratioX, v.x),mul.accMul(ratioY, v.y),1.5,0,Math.PI * 2);// context.strokeStyle = "#00f";context.fillStyle = "#5AC5BD";context.fill();context.closePath();});// 创建新的canvas存放imgDatavar newCanvas = document.getElementById("canvas" + (index + 1));newCanvas.width = mul.accMul(ratioX, facePosition.width);newCanvas.height = mul.accMul(ratioY, facePosition.height);var newCxt = newCanvas.getContext("2d");newCxt.putImageData(imageData, 0, 0); //通过 getImageData() 复制画布上指定矩形的像素数据this.imgArr.push(newCanvas.toDataURL()); //得到以 base64 编码的 dataURL}if (item.vehicleInfoParam) {let vechiPosition =item.vehicleInfoParam.vehicle_detect_res.syRectParam;context.rect(mul.accMul(ratioX, vechiPosition.left),mul.accMul(ratioY, vechiPosition.top),mul.accMul(ratioX, vechiPosition.width),mul.accMul(ratioY, vechiPosition.height));context.lineWidth = 1;context.strokeStyle = "#0f0";context.stroke(); //使用 stroke() 方法在画布上绘制确切的路径。context.closePath(); //closePath() 方法创建从当前点到开始点的路径。// 获取车辆部分var imageCarData = context.getImageData(mul.accMul(ratioX, vechiPosition.left),mul.accMul(ratioY, vechiPosition.top),mul.accMul(ratioX, vechiPosition.width),mul.accMul(ratioY, vechiPosition.height));// 创建新的canvas存放imgDatavar newCarCanvas = document.getElementById("canvas" + (index + 1));newCarCanvas.width = mul.accMul(ratioX, vechiPosition.width);newCarCanvas.height = mul.accMul(ratioY, vechiPosition.height);var newCarCxt = newCarCanvas.getContext("2d");newCarCxt.putImageData(imageCarData, 0, 0); //通过 getImageData() 复制画布上指定矩形的像素数据,然后通过 putImageData() 将图像数据放回画布this.imgCarArr.push(newCarCanvas.toDataURL());}// 清空新创建的canvasthis.canvasLength = 0;this.showFaceInfo(0);this.showCarInfo(0);});};//img.onload 图片预加载完毕},</script>//mul.js & div.js// 浮点数精确计算乘module.exports = {accMul: function(num1, num2) {var m = 0,s1 = num1.toString(),s2 = num2.toString();try {m += s1.split(".")[1].length;} catch (e) {}try {m += s2.split(".")[1].length;} catch (e) {}return ((Number(s1.replace(".", "")) * Number(s2.replace(".", ""))) /Math.pow(10, m));}// 浮点数精确计算除module.exports = {accDiv: function(num1, num2) {var t1, t2, r1, r2;try {t1 = num1.toString().split(".")[1].length;} catch (e) {t1 = 0;}try {t2 = num2.toString().split(".")[1].length;} catch (e) {t2 = 0;}r1 = Number(num1.toString().replace(".", ""));r2 = Number(num2.toString().replace(".", ""));return (r1 / r2) * Math.pow(10, t2 - t1);}
};
};

参考案例

人脸/物体识别,用 canvas 给图片画框(vue实现)相关推荐

  1. 基于MobileNet的人脸表情识别系统(MATLAB GUI版+原理详解)

    摘要:本篇博客介绍了基于MobileNet的人脸表情识别系统,支持图片识别.视频识别.摄像头识别等多种形式,通过GUI界面实现表情识别可视化展示.首先介绍了表情识别任务的背景与意义,总结近年来利用深度 ...

  2. 12.QT + OpenCV打包成应用(以及QT图标问题详细) --- OpenCV从零开始到图像(人脸 + 物体)识别系列

    本文作者:小嗷 微信公众号:aoxiaoji 关键词:QT + OpenCV打包成应用(接着第11篇) QT开发的程序发布的时候经常采用两种方式: 静态编译,可生成单一的可执行文件. 动态编译,需同时 ...

  3. opencv人脸识别以及自定义物体识别系统

    目录 一.简介: 二.软硬件应用: 三.模块介绍: (一)人脸识别: (二).自定义物体识别: (三).图片展示: (四).python框架: (五).执行器--单片机: 四.效果展示: 五.总结 : ...

  4. 25.消除不相关的细节/裂缝桥接(形态学 --膨胀与腐蚀详解 )--- OpenCV从零开始到图像(人脸 + 物体)识别系列

    本文作者:小嗷 微信公众号:aoxiaoji 吹比QQ群:736854977 简书链接:https://www.jianshu.com/u/45da1fbce7d0 本文你会找到以下问题的答案: 形态 ...

  5. 21.失真/低高通/振铃效应/旁瓣泄漏效应/频域滤波/图像深度/频带/线性滤波源码分析 -- OpenCV从零开始到图像(人脸 + 物体)识别系列

    本文作者:小嗷 微信公众号:aoxiaoji 吹比QQ群:736854977 简书链接:https://www.jianshu.com/u/45da1fbce7d0 本文你会找到以下问题的答案: 失真 ...

  6. 【人脸表情识别】如何做好表情识别任务的图片预处理工作

    上一篇专栏文章中,我们介绍了人脸表情识别的相关概念以及研究现状并了解了目前基于图片的人脸表情识别领域最常用的几个数据集.本文将介绍基于图片的人脸表情识别中最常用的预处理方式和对应的方法. 作者& ...

  7. STM32 OV7725摄像头模块的颜色处理和简单物体识别(串口输出图片)

    目录 前言 一.摄像头采集数据流程 二.如何将图像显示到电脑上 三.图像二值化 1.什么是RGB? 2.RGB565转RGB888 I.RGB565和RGB888的区别 II.代码 3.RGB转HSL ...

  8. jQuery 人脸识别插件,支持图片和视频

    jQuery Face Detection 是一款人脸检测插件,能够检测到图片,视频和画布中的人脸坐标.它跟踪人脸并输出人脸模型的坐标位置为一个数组.我们相信,面部识别技术能够给我们的 Web 应用带 ...

  9. 物体识别_深度学习在物体识别中的应用探讨:以ImageNet和人脸识别为例

    ImageNet图像分类 深度学习在物体识别中最重要的进展体现在ImageNet ILSVRC挑战中的图像分类任务.传统计算机视觉方法在此测试集上最低的错误率是26.172%.2012年,欣顿的研究小 ...

最新文章

  1. stm32和51单片机的区别,先学51还是先学stm32?
  2. GraphDTA | 基于图卷积网络预测药物-靶标结合亲和力
  3. pads最新版本是多少_电路EDA软件究竟有多少?
  4. mac u盘文件过大 拷贝不进去_使用mac时文件太大无法拷贝怎么办
  5. C#语言基础——结构体和枚举类型
  6. 不定方程(质数与因数)
  7. Unity接入百度语音识别WebAPI
  8. opencv 凸包讲解和绘制
  9. 数据中台和平台区别在哪
  10. mid php,mid是什么格式的文件
  11. Dell Inspiron 3443 BIOS升级问题解决
  12. html5做一个动画qq彩贝,HTML 第九章 作业
  13. 30分钟一部动画短片!从MMD入门3D世界,边玩边学的3D教程!(一)“MMD快速入门教程CSDN”
  14. photoshop抠图怀恋抽出滤镜
  15. 云通信的风险隐患和解决之道——SUBMAIL
  16. Stripe支付流程
  17. 基于SSM的概念可视化程序设计学习系统毕业设计源码021009
  18. 苹果怎么换字体_苹果手机电池不行了怎么办,换什么牌子好?
  19. php怎么统计运营天数,zblog教程:如何给网站内容添加运行天数统计
  20. 计算机视觉主要完成哪些任务

热门文章

  1. 重新认识下JVM级别的本地缓存框架Guava Cache——优秀从何而来
  2. webmail企业邮箱登录页面,企业邮箱申请价格
  3. 借csrf理解session原理
  4. 学习日记-安卓Package Manager和Package Installer
  5. vscode如何格式化超大型JS代码
  6. 403 Forbidden nginx/1.20.1
  7. 原创连载《第1篇:道法自然 》
  8. NX二次开发-算法篇-创建最小包容盒
  9. ListActivity和ArrayAdapter
  10. 典型的多层神经网络模型,神经网络储层建模设计