智能面试——录音及播放下载js-audio-recorder — post请求,formdata传参

录音插件 js-audio-recorder

image.png

bug:本地调试调取不起来麦克风

  • 浏览器配置安全域名 chrome://flags/
  • Insecure origins treated as secure
  • 输入域名即可
  • 电脑需要连接上耳机
<template><div class="BaseRecorder"><div class="BaseRecorder-record"><el-button @click="startRecorder()">开始录音</el-button><el-button @click="pauseRecorder()">暂停录音</el-button><el-button @click="resumeRecorder()">继续录音</el-button><el-button @click="stopRecorder()">结束录音</el-button></div><div class="BaseRecorder-play"><el-button @click="playRecorder()">录音播放</el-button><el-button @click="pausePlayRecorder()">暂停录音播放</el-button><el-button @click="resumePlayRecorder()">恢复录音播放</el-button><el-button @click="stopPlayRecorder()">停止录音播放</el-button></div><div class="BaseRecorder-download"><el-button @click="downPCM()">下载PCM</el-button><el-button @click="downWAV()">下载WAV</el-button></div><div class="BaseRecorder-destroy"><el-button type="error" @click="destroyRecorder()">销毁录音</el-button></div><div class="BaseRecorder-wave"><canvas ref="record"></canvas><canvas ref="play"></canvas></div></div>
</template><script>
import Recorder from "js-audio-recorder";export default {name: "home",data() {return {recorder: null,// 波浪图-录音drawRecordId: null,// 波浪图-播放drawPlayId: null,};},mounted() {this.init();},methods: {// 初始化init() {this.recorder = new Recorder({// 采样位数,支持 8 或 16,默认是16sampleBits: 16,// 采样率,支持 11025、16000、22050、24000、44100、48000,根据浏览器默认值sampleRate: 48000,// 声道,支持 1 或 2, 默认是1numChannels: 1,// 是否边录边转换,默认是falsecompiling: false,});},// 开始录音startRecorder() {this.recorder.start().then(() => {console.log("开始录音", this.recorder);this.drawRecord();this.recorder.onprogress = (params) => {console.log(params);// 此处控制数据的收集频率if (this.recorder.config.compiling) {console.log("音频总数据:", params.data);}};// 定时获取录音的数据并播放this.recorder.config.compiling &&(playTimer = setInterval(() => {let newData = this.recorder.getNextData();if (!newData.length) {return;}let byteLength = newData[0].byteLength;let buffer = new ArrayBuffer(newData.length * byteLength);let dataView = new DataView(buffer);// 数据合并for (let i = 0, iLen = newData.length; i < iLen; ++i) {for (let j = 0, jLen = newData[i].byteLength; j < jLen; ++j) {dataView.setInt8(i * byteLength + j, newData[i].getInt8(j));}}// 将录音数据转成WAV格式,并播放let a = encodeWAV(dataView,config.sampleRate,config.sampleRate,config.numChannels,config.sampleBits);let blob = new Blob([a], { type: "audio/wav" });blob.arrayBuffer().then((arraybuffer) => {console.log(arraybuffer);// Player.play(arraybuffer);});}, 3000));},(error) => {// 出错了console.log(`${error.name} : ${error.message}`);});},// 继续录音resumeRecorder() {this.recorder.resume();},// 暂停录音pauseRecorder() {this.recorder.pause();this.drawRecordId && cancelAnimationFrame(this.drawRecordId);this.drawRecordId = null;},// 结束录音stopRecorder() {this.recorder.stop();this.drawRecordId && cancelAnimationFrame(this.drawRecordId);this.drawRecordId = null;},// 录音播放playRecorder() {this.recorder.play();this.drawPlay(); // 绘制波浪图},// 暂停录音播放pausePlayRecorder() {this.recorder.pausePlay();},// 恢复录音播放resumePlayRecorder() {this.recorder.resumePlay();this.drawPlay(); // 绘制波浪图},// 停止录音播放stopPlayRecorder() {this.recorder.stopPlay();},// 销毁录音destroyRecorder() {this.recorder.destroy().then(() => {this.drawRecordId && cancelAnimationFrame(this.drawRecordId);this.drawRecordId = null;this.drawPlayId && cancelAnimationFrame(this.drawPlayId);this.drawPlayId = null;this.recorder = null;});},/***  下载录音文件* */// 下载pcmdownPCM() {console.log("pcm: ", this.recorder.getPCMBlob());// 这里传参进去的时文件名this.recorder.downloadPCM("新文件");},// 下载wavdownWAV() {console.log("wav: ", this.recorder.getWAVBlob());// 这里传参进去的时文件名this.recorder.downloadWAV("新文件");},/*** 绘制波浪图-录音* */drawRecord() {this.drawRecordId = requestAnimationFrame(this.drawRecord);this.drawWave({canvas: this.$refs.record,dataArray: this.recorder.getRecordAnalyseData(),bgcolor: "rgb(255, 128, 200)",lineWidth: 1,lineColor: "rgb(0, 128, 255)",});},/*** 绘制波浪图-播放* */drawPlay() {this.drawPlayId = requestAnimationFrame(this.drawPlay);this.drawWave({canvas: this.$refs.play,dataArray: this.recorder.getPlayAnalyseData(),});},drawWave({canvas,dataArray,bgcolor = "rgb(200, 200, 200)",lineWidth = 2,lineColor = "rgb(0, 0, 0)",}) {if (!canvas) return;const ctx = canvas.getContext("2d");const bufferLength = dataArray.length;// 一个点占多少位置,共有bufferLength个点要绘制const sliceWidth = canvas.width / bufferLength;// 绘制点的x轴位置let x = 0;// 填充背景色ctx.fillStyle = bgcolor;ctx.fillRect(0, 0, canvas.width, canvas.height);// 设定波形绘制颜色ctx.lineWidth = lineWidth;ctx.strokeStyle = lineColor;ctx.beginPath();for (let i = 0; i < bufferLength; i++) {const v = dataArray[i] / 128;const y = (v * canvas.height) / 2;if (i === 0) {// 第一个点ctx.moveTo(x, y);} else {// 剩余的点ctx.lineTo(x, y);}// 依次平移,绘制所有点x += sliceWidth;}// 最后一个点ctx.lineTo(canvas.width, canvas.height / 2);ctx.stroke();},},
};
</script>
<style lang="scss" scoped>
.BaseRecorder {& > div {margin: 20px 0;}&-wave {canvas {width: 100%;border: 1px solid #ccc;}}
}
</style>

智能面试页面

image.png

<template><div class="flex1 w100 h100 bg"><div style="width: 300px" class="bg-white h100 flex-column center"><div class="blue size-30 mb-60">Java面试专场</div><div class="size-26">张三</div><div class="gray-2 mt-20 mb-100">18378562388</div><el-button type="success" round @click="start()">开始面试</el-button></div><div class="flex-1 h100 over-hidden"><divclass="h100 w65 flex1 flex-column"style="margin: 0 auto; min-width: 800px"><div class="flex-1 scroll w100 pt-30"><divv-for="(item, index) in list.filter((item) => item.show)":key="index"class="mb-30"><div class="flex_l mb-30"><i class="el-icon-question size-28 blue mr-10"></i><div class="">{{ item.topic }}</div></div><div class="flex_l" v-if="item.file"><el-avatarclass="mr-10"size="small"src="https://cube.elemecdn.com/3/7c/3ea6beec64369c2642b92c6726f1epng.png"></el-avatar><el-card class="flex-1"> 语音已发送 </el-card></div><div class="flex_l" v-if="item.answer"><el-avatarclass="mr-10"size="small"src="https://cube.elemecdn.com/3/7c/3ea6beec64369c2642b92c6726f1epng.png"></el-avatar><el-card class="flex-1">{{ item.answer }}</el-card></div></div></div><div class="w100 flex1 pb-30"><el-inputtype="textarea"placeholder="请输入内容"v-model="textarea"maxlength="500"show-word-limit:autosize="{ minRows: 4 }"></el-input><div class="w10 text-center"><el-buttontype="success"icon="el-icon-microphone"circleclass="size-16 mb-10"@click="startRecorder":disabled="disabled"></el-button><el-button:disabled="disabled"type="primary"round@click="submit(1)">提交</el-button></div></div></div></div><!-- 结果 --><el-dialog:close-on-click-modal="false":close-on-press-escape="false"title="面试结果":visible.sync="centerDialogVisible"width="600px"center:show-close="false"style="top: 16vh"><el-result:icon="score >= 80 ? 'success' : score >= 60 ? 'warning' : 'error'":title="score >= 80 ? '优秀' : score >= 60 ? '良好' : '不合格'"subTitle="面试结果"><template slot="extra"><el-button type="primary" size="medium" @click="back">返回</el-button></template></el-result></el-dialog><!-- 录音 --><el-dialog:close-on-click-modal="false":close-on-press-escape="false"title="正在录音...":visible.sync="audioVisible"width="600px"center:show-close="false"style="top: 16vh"><div class="mb-20 size-18" v-if="list[index]">{{ list[index].topic }}</div><div class="BaseRecorder-wave"><canvas ref="record"></canvas><!-- <canvas ref="play"></canvas> --></div><div class="center mt-20"><el-button type="primary" size="medium" @click="submit(2)">提交</el-button></div></el-dialog></div><!-- <div class="BaseRecorder"><div class="BaseRecorder-record"><el-button @click="startRecorder()">开始录音</el-button><el-button @click="pauseRecorder()">暂停录音</el-button><el-button @click="resumeRecorder()">继续录音</el-button><el-button @click="stopRecorder()">结束录音</el-button></div><div class="BaseRecorder-play"><el-button @click="playRecorder()">录音播放</el-button><el-button @click="pausePlayRecorder()">暂停录音播放</el-button><el-button @click="resumePlayRecorder()">恢复录音播放</el-button><el-button @click="stopPlayRecorder()">停止录音播放</el-button></div><div class="BaseRecorder-download"><el-button @click="downPCM()">下载PCM</el-button><el-button @click="downWAV()">下载WAV</el-button></div><div class="BaseRecorder-destroy"><el-button type="error" @click="destroyRecorder()">销毁录音</el-button></div><div class="BaseRecorder-wave"><canvas ref="record"></canvas><canvas ref="play"></canvas></div></div> -->
</template><script>
import Recorder from "js-audio-recorder";
// import { subText, subAudio } from "../api/test.js";
import axios from "axios";
export default {name: "home",data() {return {index: null,disabled: true,list: [{topic: "题目1:1+2等于几?",show: false,answer: "",result: "",file: "",},{topic: "题目2:2+2等于几?",show: false,answer: "",result: "",file: "",},{topic: "题目3:白日依山尽的下一句是什么?",show: false,answer: "",result: "",file: "",},],textarea: "",config: {headers: {"Content-Type": "multipart/form-data",},},centerDialogVisible: false, //结果弹窗score: "", //得分audioVisible: false, //录音弹窗recorder: null,// 波浪图-录音drawRecordId: null,// 波浪图-播放drawPlayId: null,};},mounted() {this.init();},beforeDestroy() {this.destroyRecorder();},methods: {start(i = 0) {this.index = i;this.list[this.index].show = true;this.disabled = false;},// type 1 文字  2 语音async submit(type) {if (type == 1) {if (!this.textarea.trim()) {this.$message({message: "请输入答案",type: "warning",});return;}this.list[this.index].answer = this.textarea;this.disabled = true;this.textarea = "";const formData = new FormData();formData.append("topic", this.list[this.index].topic);formData.append("answer", this.list[this.index].answer);const { data } = await axios.post("/ququ/recognize-text",formData,this.config);console.log(data.result, 99);this.list[this.index].result = data.result;this.index += 1;if (this.index == this.list.length) {this.centerDialogVisible = true;this.index = null;console.log(this.list, 88);this.score =(this.list.filter((item) => item.result == "对").length * 100) /this.list.length;} else {this.start(this.index);}} else {this.stopRecorder();this.audioVisible = false;this.list[this.index].file = this.recorder.getWAVBlob();this.disabled = true;const formData = new FormData();formData.append("topic", this.list[this.index].topic);formData.append("file", this.list[this.index].file);const { data } = await axios.post("/ququ/recognize-video",formData,this.config);console.log(data.result, 99);this.list[this.index].result = data.result;this.index += 1;if (this.index == this.list.length) {this.centerDialogVisible = true;this.index = null;console.log(this.list, 88);this.score =(this.list.filter((item) => item.result == "对").length * 100) /this.list.length;} else {this.start(this.index);}}},back() {this.centerDialogVisible = false;this.list = [{topic: "题目1:1+2等于几?",show: false,answer: "",result: "",file: "",},{topic: "题目2:2+2等于几?",show: false,answer: "",result: "",file: "",},{topic: "题目3:白日依山尽的下一句是什么?",show: false,answer: "",result: "",file: "",},];},// 初始化init() {this.recorder = new Recorder({// 采样位数,支持 8 或 16,默认是16sampleBits: 16,// 采样率,支持 11025、16000、22050、24000、44100、48000,根据浏览器默认值sampleRate: 48000,// 声道,支持 1 或 2, 默认是1numChannels: 1,// 是否边录边转换,默认是falsecompiling: false,});},// 开始录音startRecorder() {this.recorder.start().then(() => {console.log("开始录音", this.recorder);this.audioVisible = true;this.drawRecord();this.recorder.onprogress = (params) => {console.log(params);// 此处控制数据的收集频率if (this.recorder.config.compiling) {console.log("音频总数据:", params.data);}};// 定时获取录音的数据并播放this.recorder.config.compiling &&(playTimer = setInterval(() => {let newData = this.recorder.getNextData();if (!newData.length) {return;}let byteLength = newData[0].byteLength;let buffer = new ArrayBuffer(newData.length * byteLength);let dataView = new DataView(buffer);// 数据合并for (let i = 0, iLen = newData.length; i < iLen; ++i) {for (let j = 0, jLen = newData[i].byteLength; j < jLen; ++j) {dataView.setInt8(i * byteLength + j, newData[i].getInt8(j));}}// 将录音数据转成WAV格式,并播放let a = encodeWAV(dataView,config.sampleRate,config.sampleRate,config.numChannels,config.sampleBits);let blob = new Blob([a], { type: "audio/wav" });blob.arrayBuffer().then((arraybuffer) => {console.log(arraybuffer);// Player.play(arraybuffer);});}, 3000));},(error) => {// 出错了console.log(`${error.name} : ${error.message}`);});},// 继续录音resumeRecorder() {this.recorder.resume();},// 暂停录音pauseRecorder() {this.recorder.pause();this.drawRecordId && cancelAnimationFrame(this.drawRecordId);this.drawRecordId = null;},// 结束录音stopRecorder() {this.recorder.stop();this.drawRecordId && cancelAnimationFrame(this.drawRecordId);this.drawRecordId = null;},// 录音播放playRecorder() {this.recorder.play();this.drawPlay(); // 绘制波浪图},// 暂停录音播放pausePlayRecorder() {this.recorder.pausePlay();},// 恢复录音播放resumePlayRecorder() {this.recorder.resumePlay();this.drawPlay(); // 绘制波浪图},// 停止录音播放stopPlayRecorder() {this.recorder.stopPlay();},// 销毁录音destroyRecorder() {this.recorder.destroy().then(() => {this.drawRecordId && cancelAnimationFrame(this.drawRecordId);this.drawRecordId = null;this.drawPlayId && cancelAnimationFrame(this.drawPlayId);this.drawPlayId = null;this.recorder = null;});},/***  下载录音文件* */// 下载pcmdownPCM() {console.log("pcm: ", this.recorder.getPCMBlob());// 这里传参进去的时文件名this.recorder.downloadPCM("新文件");},// 下载wavdownWAV() {console.log("wav: ", this.recorder.getWAVBlob());// 这里传参进去的时文件名this.recorder.downloadWAV("新文件");},/*** 绘制波浪图-录音* */drawRecord() {this.drawRecordId = requestAnimationFrame(this.drawRecord);this.drawWave({canvas: this.$refs.record,dataArray: this.recorder.getRecordAnalyseData(),bgcolor: "#a8e1fc",lineWidth: 1,lineColor: "rgb(255, 128, 200)",});},/*** 绘制波浪图-播放* */drawPlay() {this.drawPlayId = requestAnimationFrame(this.drawPlay);this.drawWave({canvas: this.$refs.play,dataArray: this.recorder.getPlayAnalyseData(),});},drawWave({canvas,dataArray,bgcolor = "rgb(200, 200, 200)",lineWidth = 2,lineColor = "rgb(0, 0, 0)",}) {if (!canvas) return;const ctx = canvas.getContext("2d");const bufferLength = dataArray.length;// 一个点占多少位置,共有bufferLength个点要绘制const sliceWidth = canvas.width / bufferLength;// 绘制点的x轴位置let x = 0;// 填充背景色ctx.fillStyle = bgcolor;ctx.fillRect(0, 0, canvas.width, canvas.height);// 设定波形绘制颜色ctx.lineWidth = lineWidth;ctx.strokeStyle = lineColor;ctx.beginPath();for (let i = 0; i < bufferLength; i++) {const v = dataArray[i] / 128;const y = (v * canvas.height) / 2;if (i === 0) {// 第一个点ctx.moveTo(x, y);} else {// 剩余的点ctx.lineTo(x, y);}// 依次平移,绘制所有点x += sliceWidth;}// 最后一个点ctx.lineTo(canvas.width, canvas.height / 2);ctx.stroke();},},
};
</script>
<style lang="scss" scoped>
.BaseRecorder {& > div {margin: 20px 0;}&-wave {canvas {width: 100%;border: 1px solid #ccc;}}
}
</style>

post请求,formdata传参

const formData = new FormData();
formData.append("topic", this.list[this.index].topic);
formData.append("answer", this.list[this.index].answer);
const { data } = await axios.post("/ququ/recognize-text",formData,{headers: {"Content-Type": "multipart/form-data",},});
console.log(data.result, 99);

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/306083.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

React之基础项目搭建

前言 React的生态系统非常庞大&#xff0c;拥有大量的第三方库和工具&#xff0c;如React Native&#xff08;用于构建原生移动应用&#xff09;、Next.js&#xff08;用于构建服务器渲染应用&#xff09;、Create React App&#xff08;用于快速搭建React应用的脚手架&#x…

鸿蒙内核源码分析 (物理内存篇) | 怎么管理物理内存

如何初始化物理内存&#xff1f; 鸿蒙内核物理内存采用了段页式管理&#xff0c;先看两个主要结构体。结构体的每个成员变量的含义都已经注解出来&#xff0c;请结合源码理解. #define VM_LIST_ORDER_MAX 9 //伙伴算法分组数量&#xff0c;从 2^0&#xff0c;2^1&#…

【网络初识】网络相关概念详解

一.局域网VS广域网 局域网 局域网:Local Area Network~简称LAN.指在某一特定区域内由多台计算机组成的互联网组。局域网内的主机之间能方便的进行网络通信&#xff0c;又称为内网.局域网和局域网之间在没有连接的情况下&#xff0c;是无法通信的。局域网的组建方式: 基于网线…

新规来了!智能音视频技术重塑信贷体验

近日&#xff0c;国家金融监督管理总局发布《固定资产贷款管理办法》《流动资金贷款管理办法》《个人贷款管理办法》&#xff08;以下简称“三个办法”&#xff09;。 具体来看&#xff0c;新规明确了以下要求&#xff1a; 1、明确视频面签、电子签约要求 允许商业银行通过视…

【话题】AI技术创业有那些机会,简单探讨下

大家好&#xff0c;我是全栈小5&#xff0c;欢迎阅读小5的系列文章&#xff0c;这是《话题》系列文章 目录 背景机会一、引言二、AI技术的创业机遇1.智能服务行业的兴起2.数据驱动的业务模式创新3.AI与产业融合的创新发展 三、AI技术创业的挑战1.技术门槛高2.法规政策的不确定性…

Java 中文官方教程 2022 版(三十四)

原文&#xff1a;docs.oracle.com/javase/tutorial/reallybigindex.html 长期持久性 原文&#xff1a;docs.oracle.com/javase/tutorial/javabeans/advanced/longpersistence.html 长期持久性是一种模型&#xff0c;可以将 bean 保存为 XML 格式。 有关 XML 格式和如何为非 be…

软件定义网络中的网络流量控制

软件定义网络&#xff08;SDN&#xff09;是一种网络范例&#xff0c;它支持一种新的方法来构建网络基础设施&#xff0c;其主要概念是基于集中控制平面和分布式转发平面的分离&#xff0c;其中整个网络及其设备通过使用开放API的软件应用程序进行集中控制和管理。SDN使网络虚拟…

Java高频面试之JVM篇

说一下 Jvm 的主要组成部分&#xff1f;及其作用&#xff1f; 类加载器执行器运行时数据区域本地接口 谈谈对运行时数据区的理解&#xff1f; 堆和栈的区别是什么&#xff1f; 堆中存什么&#xff1f;栈中存什么&#xff1f; 堆总存对象,栈中存局部变量,引用 为什么要把堆…

设计模式系列:单例模式

作者持续关注WPS二次开发专题系列&#xff0c;持续为大家带来更多有价值的WPS开发技术细节&#xff0c;如果能够帮助到您&#xff0c;请帮忙来个一键三连&#xff0c;更多问题请联系我&#xff08;WPS二次开发QQ群:250325397&#xff09;&#xff0c;摸鱼吹牛嗨起来&#xff01…

一起学习python——基础篇(15)

今天讲一下python的网络请求方法。 如果使用python语言做接口测试&#xff0c;可以安装Requests模块。 安装步骤&#xff1a;打开编程软件&#xff0c;然后点击settings——>Project:System——>Python Interpreter——>加号——>搜索栏里面输入“Requests”——&…

Redis中的集群(一)

集群 概述 Redis集群是Redis提供的分布式数据库方案&#xff0c;集群通过分片(sharding)来进行数据共享&#xff0c;并提供复制和故障转移功能 节点 一个Redis集群通常由多个节点(node)组成&#xff0c;在刚开始的时候&#xff0c;每个节点都是相互独立的&#xff0c;它们都…

appium

app元素抓取在线工具 Appium Inspector by Appium Pro appium安装&#xff08;通过node.js安装&#xff09; Python3Appium安装使用教程_python_脚本之家 Node version is 18.17.1

[计算机网络] 当输入网址到网页

HTTP 首先&#xff0c;对URL进行解析&#xff0c;URL包含了Web服务器和对应的文件&#xff08;文件路径&#xff09; URL是请求服务器中的文件资源 通过Web服务器和对应文件来生产HTTP包&#xff08;超文本传输协议&#xff09; DNS 根据域名查询对应的IP地址 域名的层级 根…

代理模式:控制对象访问的智能方式

在面向对象的软件开发中&#xff0c;代理模式是一种结构型设计模式&#xff0c;它为其他对象提供一个代理或占位符以控制对这个对象的访问。代理模式在实现权限控制、延迟初始化和远程对象访问等方面非常有用。本文将详细介绍代理模式的定义、实现、应用场景以及优缺点&#xf…

奎芯科技:智能时代的芯片上游企业如何突破?

半导体IP&#xff08;Intellectual Property&#xff0c;知识产权&#xff09;&#xff0c;通常也称作IP核&#xff08;IP core&#xff09;&#xff0c;指芯片设计中预先设计、验证好的功能模块&#xff0c;主要服务于芯片设计&#xff0c;因部分通用功能模块在芯片中被反复使…

鸿蒙南向开发:【智能烟感】

样例简介 智能烟感系统通过实时监测环境中烟雾浓度&#xff0c;当烟雾浓度超标时&#xff0c;及时向用户发出警报。在连接网络后&#xff0c;配合数字管家应用&#xff0c;用户可以远程配置智能烟感系统的报警阈值&#xff0c;远程接收智能烟感系统报警信息。实现对危险及时报…

智慧港口多场景解决方案(二)

港机智能化管理 港机智能化管理解决方案 [功能特点」 专门定制适合港机应用的专业摄像机高性能无线传输系统,高带宽、高抗干扰能力、高频谱利用率高移动性:支持港机移动高清视频的实时传送多业务承载能力:支持视频图像、CMS、告警数据、生产数据等业务的同时接入统一管理平台…

微软卡内基梅隆大学:无外部干预,GPT4等大语言模型难以自主探索

目录 引言&#xff1a;LLMs在强化学习中的探索能力探究 研究背景&#xff1a;LLMs的在情境中学习能力及其重要性 实验设计&#xff1a;多臂老虎机环境中的LLMs探索行为 实验结果概览&#xff1a;LLMs在探索任务中的普遍失败 成功案例分析&#xff1a;Gpt-4在特定配置下的探…

YOLOv8草莓生长状态(灰叶病缺钙需要肥料)检测系统(python开发,带有训练模型,可以重新训练,并有Pyqt5界面可视化)

本次检测系统&#xff0c;不仅可以检测图片、视频或摄像头当中出现的草莓叶子是否有灰叶病&#xff0c;还可以检测出草莓叶是否缺钙、是否需要施肥等状态。基于最新的YOLO-v8训练的草莓生长状态检测模型和完整的python代码以及草莓的训练数据&#xff0c;下载后即可运行&#x…

nvm安装详细教程(安装nvm、node、npm、cnpm、yarn及环境变量配置)

一、安装nvm 1. 下载nvm 点击 网盘下载 进行下载 2、双击下载好的 nvm-1.1.12-setup.zip 文件 3.双击 nvm-setup.exe 开始安装 4. 选择我接受&#xff0c;然后点击next 5.选择nvm安装路径&#xff0c;路径名称不要有空格&#xff0c;然后点击next 6.node.js安装路径&#…