webGL学习

news2024/10/6 10:40:59

1 初试webGL

const canvas = document.getElementById('canvas')
//获取webgl上下文对象 相当于设置画笔
const gl = canvas.getContext('webgl')
//声明颜色
gl.clearColor(0,0,0,1)

gl.clear(gl.COLOR_BUFFER_BIT)

2 将rbga颜色设置为webgl颜色

使用three.js的color

const color = new Color('rgba(255,1,2,1)')

3 webgl坐标系

坐标中心位于原点,y轴方向朝上,其余和正常坐标系一致

4 webgl绘图步骤

  1. 建立canvas画图
  2. 获取canvas画布
  3. 使用canvas获取wegbl绘图上下文
  4. 在script中建立顶点着色器和片元着色器
<script id="vertexShader" type="x-shader/x-vertex">
<script id="fragmentShader" type="x-shader/x-fragment">
  1. 初始化着色器

      //获取着色器文本
      const vsSource = document.querySelector("#vertexShader").innerHTML;
      const fsSource = document.querySelector("#fragmentShader").innerHTML;
      //初始化着色器
      initShaders(gl, vsSource, fsSource);

      function initShaders(gl, vsSource, fsSource) {
        //创建程序对象
        const program = gl.createProgram();
        //建立着色对象
        const vertexShader = loadShader(gl, gl.VERTEX_SHADER, vsSource);
        const fragmentShader = loadShader(gl, gl.FRAGMENT_SHADER, fsSource);
        //把顶点着色对象装进程序对象中
        gl.attachShader(program,vertexShader)
        gl.attachShader(program,fragmentShader)
        //连接webgl上下文对象和程序对象
        gl.linkProgram(program)
        //启动程序对象
        gl.useProgram(program)
        //将程序对象挂载到上下文对象中
        gl.program = program
        return true
      }

      function loadShader(gl,type,source){
        //根据着色类型,建立着色器对象
        const shader = gl.createShader(type)
        //将着色器源文件传入着色器对象中
        gl.shaderSource(shader,source)
        //编译着色器对象
        gl.compileShader(shader)
        return shader
      }

5 着色器

着色器语言是GLSL ES语言

  • 顶点着色器:描述顶点的特征,如位置、颜色
  • 片元着色器:进行逐片元处理,如光照

着色器编程

void main(){
	gl_Position = vec4(x,y,z,1.0);
	gl_PointSize = 100.0;
	gl_FragColor = vec4(r,g,b,a)
}

着色器初始化

//建立程序对象
const shader = gl.createProgram()

//建立着色对象
const vertexShader = loadShader(gl,gl.VERTEX_SHADER,vsSource)
const fragShader = loadShader(gl,gl.FRAGMENT_SHADER,fsSource)

//将着色器对象装入程序对象中
gl.attachShader(program,vertexShader)
gl.attachShader(program,fragmentShader)

//连接webgl上下文对象和程序对象
gl.linkProgram(program)

//启动程序对象
gl.useProgram(program)

gl.program = program


function loadShader(gl,type,source){
	//根据着色器类型,建立着色器对象
	const shader = gl.createShader(type)
	//将着色器对象放入着色器源文件中
	gl.shaderSource(shader,source)
	//编译着色器对象
	gl.compileShader(shader)
	return shader
}

attribute变量及设置:

const position = gl.getAttribLocation(gl.program,'z_position')

//设置前3各值
gl.vertexAttrib3f(position,0,0,0)

6 获取鼠标点在webgl坐标系中的位置

webgl是同步绘图是由颜色缓冲区导致的,颜色缓冲区中存储的图像只在当前线程有效;在执行异步线程时,颜色缓冲区会被重置

canvas.addEventListener('click',(e)=>{
	const { clientX,clientY } = e
	const {left,top,width,height} = gl.getBoundingClientRect()
	const [ cssX,cssY ] = [clientX-left,clientY-top]
	const [halfWidth,halfHeight] = [width/2,height/2]
	const [ x,y ] =  [(cssX-halfWidth)/halfWidth,(halfHeight-cssY)/halfHeight]
	a.points.push({x,y})
	render()
})

function render(){
	gl.clear(gl.COLOR_BUFFER_BIT)
	a.points.forEach(({x,y})=>{
		gl.vertexAttrib2f(a_position,x,y)
		gl.drawArrays(gl.POINTS,0,1)
	})
}

7 修改顶点颜色

使用uniform限定符

const u_fragColor= gl.getUniformLocation(gl.program,'u_fragColor')
gl.uniform4f(u_fragColor,0,0,0,0)
const arr = new Float32Array([r,g,b,a])
gl.uniform4fv(u_fragColor,arr)

8 鼠标绘制星空

设置切片范围

precision mediump float;
uniform rec4 u_fragcolor;
void main(){
	float dist = distance(gl_PointCoord,rec2(0.5,0.5));
	if(dist<0.5){
		gl_FragColor = u_fragcolor;	
	}else {
		discard;
	}
}

9 设置颜色透明度

需要开启片元的颜色合成功能

gl.enable(gl.BLEND)
//设置片元的合成方式
gl.blendFunc(gl.SRC_ALPHA,gl.ONE_MINUS_SRC_ALPHA)

10 绘制多个点

//设置顶点坐标
const vertices = new Float32Array([0,0,0.1,0.1,0.2,0.2])
//建立顶点缓冲区
const vertexBuffer = gl.createBuffer()
//绑定缓冲区对象
gl.bindBuffer(gl.ARRAY_BUFFER,vertexBuffer)
//写入顶点数据
gl.bufferData(gl.ARRAY_BUFFER,vertices,gl.STATIC_DRAW)
//获取attribute变量
const a_position = gl.getAttribLocation(gl.program,'a_position')
//设置attribute变量
gl.vertexAttribPointer(a_position,2,gl.FLOAT,false,0,0)
gl.clearColor(0,0,1,1)
gl.clear(gl.COLOR_BUFFER_BIT)
gl.drawArrays(gl.POINTS,0,3)

11 绘制线

  • LINES:每两点连线
  • LINE_STRIP:连接所有点成线
  • LINE_LOOP:形成闭环

12 判断三角形的第三个顶点是否处于正半边

有A(x1,y1)、B(x2,y2)、C(x3,y3)

const abX = x2-x1
const abY = y2-y1
const acX = x3-x1
const acY = y3-y1

const dist = abX*acY - abY*acX

if(dist>0){
	return true
} 

13 旋转

无论绕那个轴,从正半轴向正半轴逆时针旋转都是正

(1)先移动后旋转
移动到相应位置后,按原来的中心点进行旋转

(2)先旋转后移动
先按中心点旋转,然后再位移

绕z轴逆时针旋转角度:[[cosθ,-sinθ],[sinθ,cosθ]]

14 视图矩阵

  • 视点:相机的位置
  • 视线方向:相机所看的方向
  • 上方向:相机绕视线转动的方向

三维向量叉乘

x={ax,ay,az}
y = {bx,by,bz}

cross(x,y)=(ay*bz-az*by,)

生成视图矩阵

function getViewMatrix(e, t, u){
	const c = new Vector3().subVectors(e, t).normalize()
	const a = new Vector3().corssVectors(u, c).normalize()
	const b = new Vector3().crossVectors(c, a).normalize()
	const mr = new Matrix4().set(
		...a,0,
		...b,0,
		-c.x,-c.y,-c.z,0,
		0,0,0,1
	)
	const mt = new Matrix4().set(
		1,0,0,-e.x,
		0,1,0,-e.y,
		0,0,1,-e.z,
		0,0,0,1	
	)
	return mr.multiple(mt).elements
}

15 多attribute数据合一

//按列拼接
const source = new Float32Array([])
//元素字节数
const elementBytes = source.BYTES_PRE_ELEMENT
//变量长度
const verticeSize = 3
const colorSize = 4
//总长度
const category = verticeSize + colorSize
//总字节数
const categoryBytes = catefory*elementBtyes
//变量索引
const verticeIndex = 0
const colorIndex = verticeSize * elementBytes
//顶点总数
const sourceSize = source.length/categorySize

//设置某个attribute变量
//gl.vertexArrtibPointer(index,size,type,normalized,stride,offset)
const a_color = gl.getAttribLocation(gl.program,'a_color')
gl.vertexAttribPointer(
	a_color,
	colorSize,
	gl.FLOAT,
	false,
	categoryBytes,
	colorIndex
)

16 纹理

//将图片上下对称翻转坐标轴
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL)

//激活纹理单元
gl.activeTexture(gl.TEXTURE0)
//创建纹理对象
const texture = gl.createTexture()
//将纹理对象装进纹理单元中
gl.bindTexture(gl.TEXTURE_2D,texture)
//创建图像
const image = new Image()
img.src = ''
img.onlaod = function(){
gl.texImage2D(gl.TEXTURE_2D,0,gl.RGB,gl.RGB,gl.UNSIGNED_BYTE,image)
gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_MIN_FILTER,gl.LINEAR)
//防止非2的n次幂图像无法显示
gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_WRAP_S,gl.CLAMP_TO_EDGE)

gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_WRAP_T,gl.CLAMP_TO_EDGE)

}

纹理混合:mix(m,n,a):m+(n-m)*a

跨域贴图:设置image.setAttribute(‘crossOrigin’,‘Anonymous’)

17 GLSL ES语言

  1. 结构体:struct
struct Light{
	vec4 color;
	vec3 pos;
};

void main(){
	Light l1 = Light(
		vec4(255,255,0,255),
		vec3(1,2,3)
	)
	gl_FragColor = l1.color/255.0;
}
  1. 数组
vec4 vs[2];
vs[0]=vec4();


const int n=2;
vec4 vs[n];
  1. for循环
    for循环的循环变量必须是int或float
for(int i=0;i<3;i++){}

for(float i=0.0;i<4.0;i++){}
  1. 函数
//不会影响原始数据,如果想修改原始数据要使用out
void setLum(in vec3 color){
	color.y = 255.0
}
  1. 设置精度
    精度有:highp、mediump、lowp,float是没有默认精度的
//设置某个变量的精度
mediump float size;

//设置某种数据类型的精度
precision mediump float;
  1. 设置颜色渐变
//获取片元的投影长度
//以投影长度比例乘以颜色差值获得该点的颜色

18 四元数

在这里插入图片描述
例如有一点p需要绕OC2轴旋转ang度,那么可以让c2旋转到z轴对齐,然后点p绕z轴旋转ang度,然后再旋转回来

在这里插入图片描述
如何旋转到Z轴?C2旋转B2OB1度到C3,然后C3旋转C3OB1度到Z轴

//three.js中采用四元数旋转
const quaternion = new Quaternion()
quaternion.setFromAxisAngle(oc2,ang)
const m = new Matrix4()
m.makeRotationFromQuaternion(quaternion)
p1.clone().applyMatrix4(m)

19 正交投影矩阵

顶点在空间中的位置投影矩阵\*视图矩阵\*模型矩阵*顶点的初始位置

正交投影矩阵=缩放矩阵*位移矩阵

const projectMatrix = new Matrix4()
//定义相机世界高度的一半
const halfH = 2
//计算画布的宽高比
const ratio = canvas.width/canvas.height
//计算相机的宽度
const halfW = halfH*ratio
//定义相机的6个边界
const [left,right,top,bottom,near,far]=[
	-halfW,halfW,halfH,-halfH,0,4
]

//获取正交投影矩阵
projectionMatrix.makeOrthographic(left,right,top,bottom,near,far)
 

20 视图位移

const camera = new OrthographicCamera(left,right,top,bottom,near,far)

camera.position.set(0,0,3)
camera.updateWorldMatrix(true)

const pvMatrix = new Matrix4().multiplyMatrices(
	camera.projectionMatrix,
	camera.matrixWorldInverse
)

21 视图旋转

const eye = new Vector3(1,2,3)
const target = new Vector3(0,0,0)
const up = new Vector3(1,1,1)

const camera = new OrthographicCamera(left,right,top,bottom,near,far)
camera.position.set(eye)

camera.lookat(target)
camera.updateWorldMatrix(true)

//计算投影矩阵
const pvMatrix = new Matrix4().multiplyMatrices(
	camera.projectionMatrix,
	camera.matrixWorldInverse
)

原理:

//位移矩阵
const positionMatrix = new Matrix4().setPosition(eye)

//旋转矩阵
const rotationMatrix = new Matrix4().lookAt(eye,target,up)

//计算相机的视图矩阵
const viewMatrix = new Matrix4().multiplyMatrices(
	positionMatrix,rotationMatrix
)

//投影视图矩阵
const pvMatrix = new Matrix4().multiplyMatrices(
	camera.projectionMatrix,viewMatrix
)

22 透视投影矩阵

在这里插入图片描述
两种数据间的转换关系为y=k*x+b
其中k=(maxM-minM)/(maxN-minN)以及b=minM-k*minN
在这里插入图片描述

在这里插入图片描述

  • fov:相机视锥体垂直视野角度
  • aspect:摄像机视锥体宽高比
  • near:近裁剪面到视点的距离
  • far:远裁剪面到视点的距离

在这里插入图片描述

//在three.js中使用透视投影矩阵
//建立透视相机
const [fov,aspect,near,far] = [45,canvas.width/canvas.height,1,20]

const camera = new PerspectiveCamera(fov,aspect,near,far)

23 对投影矩阵、视图矩阵、模型矩阵的理解

  • 模型矩阵:相当于更改物体的位置
  • 视图矩阵:相当于改变相机位置
  • 投影矩阵:将顶点坐标变换到裁剪坐标

24 相机轨道控制器

(1)设置相机位移轨道

//鼠标事件
const mouseButtons = new Map([
	[2, 'pan']
])

//轨道控制器状态,'pan'代表位移
let state = 'none'

//鼠标拖拽的起始和结束位置
const dragStart = new Vector2()
const dragEnd = new Vector2()

//鼠标移动的位移量
const panoffset = new Vector3()

//鼠标垂直拖拽,是基于y轴还是z轴
// true:y false:z
const screenSpacePanning = true

//取消右击菜单显示
canvas.addEventListener('contextmenu',event=>{
	event.preventDefault()
})

//指针按下时,设置拖拽起始位,获取轨道控制器状态
canvas.addEventListener('pointerdown',({clientX,clientY,button})=>{
	dragStart.set(clientX,clientY)
	state = mouseButtons.get(button)
})

//指针平移时,如果控制器处于移动状态,平移相机
canvas.addEventListener('pointermove',(event)=>{
	switch(case){
		case 'pan':
			handleMouseMovePan(event)	
	}
})

//指针抬起,清楚控制器状态
canvas.addEventListener('pointerup',(event)=>{
	state = 'none'
})

const handleMouseMovePan = ({clientX,clientY,button})=>{
	dragEnd.set(clientX,clientY)
	//基于拖拽距离拖拽相机
	pan(dragEnd.clone().sub(dragStart))
	//重置起始点位置
	dragStart.clone(dragEnd)
}	

//相机移动是基于鼠标在近裁剪面上的位移量来移动的
const pan = (delta)=>{
	//相机近裁剪面尺寸
	const cameraWidth = camera.right - camera.left
	const cameraHeight = camera.top - camera.bottom
	//指针拖拽量在画布中的比值
	const ratioX = delta.x / canvas.clientWidth
	const ratioY = delta.y / canvas.clientHeight
	//将像素单位的位移量转换为近裁剪面上的位移量
	const distanceLeft = ratioX * cameraWidth
	const distanceUp = ratioY * cameraHeight
	//相机本地坐标系的x轴 取相机本地坐标系第一列作为x轴
	const mx = new Vector3().setFromMatrixColumn(camera.matrix,0)
	//相机x轴位移量
	const vx = mx.clone().multiplyScalar(-distanceLeft)
	//相机z/y轴平移量
	const vy = new Vector3()
	if (screenSpacePanning){
		vy.setFromMatrixColumn(camera.matrix,1)
	} else {
	//-z向
	//相机的上方向叉乘x轴会得到-z轴 x轴叉乘上方向得到z轴
		vy.crossVectors(camera.up,mx)
	}
	vy.multiplyScalar(distanceUp)
	//整合平移量
	panoffset.copy(vx.add(vy))
	update()
}

const update = ()=>{
	//移动相机的目标点
	target.add(panoffset)
	//移动相机视点
	camera.position.add(panoffset)
	//看向目标点
	camera.lookAt(target)
	//更新相机世界坐标系
	camera.updateWorldMatrix(true)
	//计算投影视图矩阵
	pvMatrix.multiplyMatrix(
		camera.projectionMatrix,
		camera.matrixWorldInverse,
	)
	render()	
}

(2)设置相机旋转轨道


(3)设置相机缩放轨道
主要是让在同一深度上的东西更多或者更少

//定义缩放系数
const zoomScale = 0.95

//添加滚动事件
canvas.addEventListener('wheel',handleMouseWheel)

const handleMouseWheel = ({deltaY})=>{
	if(deltaY<0){
		dolly(1/zoomScale)	
	} else if (deltaY>0) {
		dolly(zoomScale)
	}
	update()
}




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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

在一个已经EXIT的docker容器中,修改配置文件

文章目录背景一、方法一二、方法二1.通过运行docker inspect [容器id]来获取到底层的容器对象信息2.修改配置文件总结背景 当我们在修改容器里的配置文件后(例如mysql),发现重新运行容器起不来了,此时不要慌&#xff01;下面我来介绍两种方法来修改已经停止的容器里的配置文件,…

jvm监控服务性能、以及资源使用情况

目录 1.前言&#xff1a; 2.如何监控 2.1.spring admin 2.2.pass平台 2.3jvm 本地jdk监控本地服务 2.3.1介绍 2.3.2JVisualVM能做什么 2.3.3使用 2.4jvm 本地jdk监控远程服务 方式一 方式二 1.前言&#xff1a; 常规新项目上线&#xff0c;做非功能测试&#xff08…

【目标检测】Faster R-CNN的几点理解

目录&#xff1a;Faster R-CNN的几点理解一、Faster R-CNN概述二、R-CNN、Fast R-CNN、Faster R-CNN的对照2.1 R-CNN2.1.1 R-CNN的检测步骤2.1.2 R-CNN的主要缺点2.2 Fast R-CNN2.2.1 Fast R-CNN的检测步骤2.2.2 Fast R-CNN的缺点2.3 R-CNN、Fast R-CNN、Faster R-CNN的比较三、…

【Android App】获取照片里的位置信息及使用全球卫星导航系统(GNSS)获取位置实战(附源码和演示 超详细)

需要全部代码请点赞关注收藏后评论区留言私信~~~ 一、获取照片里的位置信息 手机拍摄的相片还保存着时间、地点、镜头参数等信息&#xff0c;这些信息由相片接口工具ExifInterface管理&#xff0c;它的常用方法说明如下&#xff1a; getLatLong&#xff1a;获取相片拍摄时候的…

双飞翼布局

实现双飞翼布局&#xff0c;两边保持不保&#xff0c;只有中间变化&#xff1a; html代码&#xff1a; ------------------------------------------------------------------------------------ <!doctype html> <html> <head> <meta charset"utf…

拼多多季报图解:营收355亿同比增65% 研发投入达27亿

雷递网 雷建平 11月28日拼多多今日发布2022年第三季度业绩报告。财报显示&#xff0c;拼多多2022年第三季度营收为355亿元&#xff0c;同比增长65.1%。受到一些项目投入延缓等偶发因素影响&#xff0c;三季度平台运营费用为176.5亿元&#xff0c;占收入的比例从上年同期的59.6&…

VH03型多功能采集仪

河北稳控科技手持振弦传感器VH03型多功能采集仪&#xff0c;是专用的多类型传感器手持式读数仪&#xff0c;主测传感类型为单弦式振弦传感器&#xff0c;辅测传感类型为电压、电流传感。采用32位ARM处理器和大尺寸全彩屏、阵列按键设计&#xff0c;在完成快速测读的同时还具备极…

高校排课系统/排课管理系统的设计与实现

摘 要 网络的广泛应用给生活带来了十分的便利。所以把高校排课与现在网络相结合&#xff0c;利用JSP技术建设高校排课系统&#xff0c;实现高校排课的信息化。则对于进一步提高高校排课发展&#xff0c;丰富高校排课经验能起到不少的促进作用。 高校排课系统能够通过互联网得到…

国民经济行业代码查询系统-公司行业代码查询

今天在申请公司的一些信息时&#xff0c;要我给公司行业的代码&#xff0c;4位&#xff0c;问了财务和高企的申请伙伴&#xff0c;都没有特别清晰&#xff0c;让百度&#xff0c;直接百度花了点时间&#xff0c;记录一下&#xff0c;帮助其他的伙伴 国民经济行业代码查询系统 …

Python的10个编程技巧,你不一定都知道

文末有Python资料下载 1. 原地交换两个数字 Python 提供了一个直观的在一行代码中赋值与交换&#xff08;变量值&#xff09;的方法&#xff0c;请参见下面的示例&#xff1a; 赋值的右侧形成了一个新的元组&#xff0c;左侧立即解析&#xff08;unpack&#xff09;那个&…

2022-安洵杯

WEB babyphp call_user_func() 函数如果传入的参数是array类型的话&#xff0c;会将数组的成员当作类名和方法&#xff0c; array(0) { } <?php //something in flag.phpclass A {public $a;public $b;public function __wakeup(){$this->a "babyhacker";…

Mathematica(36)-在Plot中画平行于y轴的线

在论文写作过程中&#xff0c;我们常常也需要画一条平行于y坐标轴的直线&#xff0c;怎么实现呢&#xff1f; 比如&#xff0c;下面的代码就是绘制了一条平行于y轴的直线&#xff0c;这条直线采用了虚线来表示 Plot[Sin[x], {x, 0, 2 Pi}, Epilog -> {Dashed, Line[{{5, -…

ISCSLP 2022 | AccentSpeech—从众包数据中学习口音来构建目标说话人的口音语音合成系统

构建带口音的语音合成系统可以增加语音合成的多样性和趣味性。然而不是每个人都能说多种口音。为了实现口音与说话人音色的自由组合&#xff0c;借助迁移学习技术&#xff0c;为没有口音数据的说话人构建口音合成系统&#xff0c;是实现“口音任意说”的有效途径。但是以往大多…

[网络工程师]-应用层协议-WWW与HTTP

1、WWW 万维网&#xff08;World Wide Web,WWW&#xff09;是一个规模巨大、可以互联的资料空间&#xff0c;该资料空间的资源依靠URL进行定位&#xff0c;通过HTTP协议传送给使用者&#xff0c;又由HTML进行文档的展现。由此可知&#xff0c;WWW的核心由三个主要标准构成&…

[附源码]SSM计算机毕业设计校园疫情防控管理系统JAVA

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

【遥感图像:信息增强】

SDPNet: A Deep Network for Pan-Sharpening With Enhanced Information Representation &#xff08;SDPNet&#xff1a;一种增强信息表示的泛锐化深度网络&#xff09; 本文提出了一种基于表层和深层约束的全色锐化网络SDPNet&#xff0c;以解决全色锐化问题。聚焦于全色锐…

[附源码]计算机毕业设计springboot基于java的社区管理系统

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

第二证券|重磅利好!国家能源局发文,多股立马涨停!

今日早上&#xff0c;各位小伙伴有点跌懵了吧&#xff1f;不过&#xff0c;我大A盘中又支楞起来了&#xff0c;惊不惊喜&#xff1f;意不意外&#xff1f; 周一早盘&#xff0c;A股、港股直接跳空低开。A股顺利回补此前跳空高开的缺口&#xff0c;技能上现已没有跌落的空间。 …

广和通基于联发科技 T830平台的5G模组FG370率先通过CE认证测试

11月&#xff0c;广和通5G模组FG370率先通过CE认证测试&#xff0c;进而可用于无线宽带终端部署。5G模组FG370于9月启动研发&#xff0c;并于10月正式发布&#xff0c;随后仅短短一个月&#xff0c;便通过CE认证测试。至此&#xff0c;广和通5G模组FG370已进入工程送样阶段&…

快速复现 实现 facenet-pytorch 人脸识别 windows上 使用cpu实现 人脸对比

目录0 前言1 搭建环境与项目2 人脸预测与结果展示0 前言 这一次要复现的是人脸识别中的 facenet-pytorch 参考了&#xff1a; Pytorch 搭建自己的Facenet人脸识别网络&#xff08;Bubbliiiing 深度学习 教程&#xff09; https://gitee.com/xiaozhao123666/facenet-pytorch ht…