Three.js+pcl.js 实现Web端的点云处理+显示

news2024/12/17 17:31:45

1 功能实现

在前面我们实现了PCD的加载器的基础上,这次将加上 pcl.js —— 著名的PCL库的web版本,详情见https://pcl.js.org/,来处理我们加载上去的点云。

具体实现如下:

brief image-20231209154425964

用户可以通过每个板块的右上角进行处理前 / 后的切换,还可以通过一些参数调控pcl算法(注意:调完参数后需要切换显示模式才能生效

  1. 点云过滤示例1:
    • 主要功能:通过统计离群值移除算法,用户可以调整参数 meanKstddevMulThresh 查看过滤效果。
  2. 点云关键点提取示例2:
    • 主要功能:应用 ISS(Intrinsic Shape Signatures) 算法进行关键点提取,用户可以调整参数 SalientRadiusNonMaxRadiusThreshold21Threshold32MinNeighbors 查看效果。
  3. 最小切割示例3:
    • 主要功能:通过最小切割算法,用户可以调整参数 RadiusSigmaSourceWeightNumberOfNeighbours 查看效果。

2 具体实现

本项目是基于 Three.jspcl.js 实现的简单一个Web应用程序,用于可视化三维点云数据并且处理三维点云。

使用 VSCode 的 Live Serve 搭建网络编程的环境,采用CDN的方式引入 Three.js (版本:r158) 和 pcl.js(版本:1.16.0)

2.1 html

HTML 代码定义了一个基本网页,用于使用三个不同的JS文件处理点云数据:

  • PCLFilter.js
  • PCLKeyPoints.js
  • PCLCutter.js

结构:

  • 页面包含一个分为三个面板的容器

  • 每个面板都有一个用于选择“原始”和“过滤”点云数据显示的单选按钮组

    通过 radio 按钮选择不同的显示模式,可以查看原始点云数据或经过处理后的点云数据。

  • 每个面板还有一个引用特定 .js 文件的脚本标签

  • 使用 flex 布局来布局三个面板,使页面分为左上左下,三个板块

<!DOCTYPE html>
<html>

<head>
	<meta charset="utf-8">
	<title>PCD visulize</title>
	<style>
		body {
			margin: 0;
			padding: 0;
			overflow: hidden;
		}
	</style>
</head>

<body style="color: rgb(131, 131, 131);">
	<script type="importmap">
		{
		  "imports": {
			"three": "https://cdn.jsdelivr.net/npm/three@0.158.0/build/three.module.js",
			"three/addons/": "https://cdn.jsdelivr.net/npm/three@0.158.0/examples/jsm/"		
		  }
		}
	</script>
	<div class="container">
		<div class="panel panel1" id="Panel1"
			style="position: relative;height: calc(50vh - 2px);width: 50vw;border-bottom: #ccc 2px solid;border-right: #ccc 2px solid">
			<fieldset style="position: absolute; right: 0; top: 0;">
				<legend>选择显示模式</legend>
				<div>
					<input type="radio" id="original1" name="display1" value="original1" checked />
					<label for="original1">处理前</label>
				</div>
				<div>
					<input type="radio" id="filtered1" name="display1" value="filtered1" />
					<label for="filtered1">处理后</label>
				</div>
			</fieldset>

			<script type="module" src="js/PCLFilter.js"> </script>
		</div>
		<div class="panel panel2" id="Panel2"
			style="position: absolute;right: 0;top: 0;height: 100vh;width: calc(50vw - 4px);">
			<fieldset style="position: absolute; right: 0; top: 0;">
				<legend>选择显示模式</legend>
				<div>
					<input type="radio" id="original2" name="display2" value="original2" checked />
					<label for="original2">处理前</label>
				</div>
				<div>
					<input type="radio" id="filtered2" name="display2" value="filtered2" />
					<label for="filtered2">处理后</label>
				</div>
			</fieldset>

			<script type="module" src="js/PCLKeyPoints.js"> </script>
		</div>
		<div class="panel panel3" id="Panel3"
			style="position: relative;height: 50vh;width: 50vw;border-right: #ccc 2px solid">
			<fieldset style="position: absolute; right: 0; top: 0;">
				<legend>选择显示模式</legend>
				<div>
					<input type="radio" id="original3" name="display3" value="original3" checked />
					<label for="original3">处理前</label>
				</div>
				<div>
					<input type="radio" id="filtered3" name="display3" value="filtered3" />
					<label for="filtered3">处理后</label>
				</div>
			</fieldset>

			<script type="module" src="js/PCLCutter.js"> </script>
		</div>

	</div>
	<style>
		.container {
			/* display: grid; */
			/* grid-template-columns: 1fr 1fr;
			grid-template-rows: 1fr 1fr; */
			height: 100vh;
		}

		.panel {
			flex: 1 0 50%;
			border: 1px solid #ccc;
			display: flex;
			justify-content: center;
			align-items: center;
		}

		#panel2 {
			height: 100vh;
		}
	</style>
</body>
</html>

2.2 js

该项目中有三个类似的JS文件,每个都大同小异,只是使用了不同的PCL功能罢了,我将主要详细讲解其中一个的全流程

2.2.1 PCLFilter.js

实现点云过滤处理

1. 引入库

通过 import 方式引入了 pcl.js 和 three.js 库,以及一些 three.js 相关的模块。

import * as PCL from "https://cdn.jsdelivr.net/npm/pcl.js@1.16.0/dist/pcl.esm.js";
import * as THREE from 'three';
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
import { PCDLoader } from 'three/addons/loaders/PCDLoader.js';
import { GUI } from 'three/addons/libs/lil-gui.module.min.js';
2. three.js 初始化

three.js 的经典三大件,初始化了 OrbitControls 使我们可以用鼠标控制点云,还创建了一个GUI

const container = document.getElementById('Panel1');
// 创建场景、相机、渲染器
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(80, container.offsetWidth / container.offsetHeight, 0.01, 10000000);
camera.position.set(0, 0, 1.5);
const renderer = new THREE.WebGLRenderer();
renderer.setSize(container.offsetWidth, container.offsetHeight);
container.appendChild(renderer.domElement);
// 创建控制器
const controls = new OrbitControls(camera, renderer.domElement);

var gui = new GUI();
gui.title('示例1:点云过滤');
var attributesFolder = gui.addFolder('点云设置');
gui.domElement.style.left = '0.1%';
gui.domElement.style.position = 'absolute';
3. 加载点云数据执行滤波
  • 异步加载点云数据: 通过 fetch 函数异步获取点云数据,将数据转换为 ArrayBuffer;使用 PCL.init 初始化 pcl.js 库,指定 wasm 文件的路径;再使用 PCL.loadPCDData 函数加载点云数据
  • 创建 StatisticalOutlierRemoval 滤波器: 使用 new PCL.StatisticalOutlierRemoval() 创建统计离群值滤波器;使用 sor.setMeanKsor.setStddevMulThresh 设置滤波器的参数;再使用 sor.filter() 对点云进行滤波
  • 保存滤波后和原始点云的数据: 使用 PCL.savePCDDataASCII 将滤波后和原始点云的数据保存为 ASCII 格式
  • 绑定事件: 调用 bindEvent() 函数,用于处理滤波后数据
let cloud;                // 存储点云数据
let cloudOriginalData;    // 存储原始点云数据
let cloudFilteredData;    // 存储滤波后的点云数据

async function main() {
    // 异步获取点云数据
    const cloudBuffer = await fetch("./images/point_cloud.pcd").then((res) =>
        res.arrayBuffer()
    );

    // 初始化 pcl.js 库
    await PCL.init({
        url: `https://cdn.jsdelivr.net/npm/pcl.js/dist/pcl-core.wasm`
    });

    // 加载点云数据
    cloud = PCL.loadPCDData(cloudBuffer, PCL.PointXYZ);

    // 创建 StatisticalOutlierRemoval 滤波器
    const sor = new PCL.StatisticalOutlierRemoval();
    sor.setInputCloud(cloud);
    sor.setMeanK(40);
    sor.setStddevMulThresh(3.0);
    
    // 对点云进行滤波
    const cloudFiltered = sor.filter();

    // 保存滤波后和原始点云的数据(ASCII格式)
    cloudFilteredData = PCL.savePCDDataASCII(cloudFiltered);
    cloudOriginalData = PCL.savePCDDataASCII(cloud);

    // 绑定事件
    bindEvent();
}

// 调用 main 函数
main();
4. 显示切换
  1. bindEvent切换函数

    为页面上的两个单选按钮添加 “change” 事件监听器,实现用户选择显示原始点云或滤波后点云的功能

    function bindEvent() {
        // 初始显示原始点云
        showPointCloud(cloudOriginalData);
    
        // 获取两个单选按钮元素
        const radioOriginal = document.getElementById("original1");
        const radioFiltered = document.getElementById("filtered1");
    
        // 为两个单选按钮添加 "change" 事件监听器
        [radioOriginal, radioFiltered].forEach((el) => {
            el.addEventListener("change", (e) => {
                const mode = e.target.id; // 获取选中按钮的 id
                reset(); // 重置 GUI
    
                // 根据选中的按钮 id,显示相应的点云数据
                switch (mode) {
                    case "original1":
                        showPointCloud(cloudOriginalData);
                        break;
                    case "filtered1":
                        showPointCloud(cloudFilteredData);
                        break;
                }
            });
        });
    }
    
  2. GUI重置函数

    • 删除之前的 GUI:使用 gui.destroy() 方法删除之前的 GUI 实例。
    • 创建新的 GUI 实例:创建一个新的 GUI 实例,并进行一些设置,如添加标题、文件夹等。
    • 删除之前的点云:通过 scene.remove(scene.children[0]) 删除之前的点云对象。
    function reset() {
        // 删除之前的 GUI
        gui.destroy();
    
        // 创建一个新的 GUI 实例
        gui = new GUI();
        // gui.add(isRotation, 'bool').name('旋转');
        gui.title('点云过滤');
        attributesFolder = gui.addFolder('点云设置');
        gui.domElement.style.left = '0.1%';
        gui.domElement.style.position = 'absolute';
        // 删除之前的点云
        scene.remove(scene.children[0]);
    }
    
5. 点云显示
  1. 将PCL的点云的数据(ASCII格式),转换为URL以便 three.js 的PCD加载
    • 将 ArrayBuffer 转换为字符串: 使用 TextDecoder 将输入的 ArrayBuffer 数据解码为字符串。
    • 从字符串创建 Blob: 使用 Blob 构造函数将字符串数据转换为 Blob 对象,设置 MIME 类型为 ‘text/plain’。
    • 从 Blob 创建 URL: 使用 URL.createObjectURL 创建一个包含 Blob 数据的 URL,用于加载点云模型。
  2. three.js 的点云加载显示
    • 加载点云模型:使用点云加载器的 load 方法加载点云模型。在加载完成后,调用回调函数,其中 points 包含了点云的几何信息。
    • 几何变换:对点云的几何进行居中和绕 X 轴旋转。
    • 创建点云材质:使用 THREE.PointsMaterial 创建点云的材质,设置颜色、点大小等属性。
    • 根据点云数据设置颜色:根据当前点云是原始数据还是滤波后的数据,设置点云的颜色。
    • 创建点云对象:使用 THREE.Points 创建点云对象,将其添加到场景中。
    • 在 GUI 中添加点云相关设置:使用 attributesFolder.addFolder 创建一个 GUI 文件夹,添加文件名、点数、点大小、点颜色等设置。
function showPointCloud(currentPointCloud) {
    // 将 ArrayBuffer 转换为字符串
    const decoder = new TextDecoder('utf-8');
    const pcdString = decoder.decode(new Uint8Array(currentPointCloud));

    // 从字符串创建 Blob
    const blob = new Blob([pcdString], { type: 'text/plain' });

    // 从 Blob 创建 URL
    const url = URL.createObjectURL(blob);

    // 创建点云加载器
    const loader = new PCDLoader();

    // 加载点云模型
    loader.load(url, function (points) {
        // 将点云几何居中
        points.geometry.center();
        points.geometry.rotateX(Math.PI);

        // 创建点云材质
        const material = new THREE.PointsMaterial({ color: 0xffffff, size: 0.02, vertexColors: false });

        // 根据当前点云是原始数据还是滤波后的数据设置点云颜色
        if (currentPointCloud == cloudOriginalData) {
            material.color.setHex(0xad1010); // 设置为红色
        } else {
            material.color.setHex(0x1ea10c); // 设置为绿色
        }

        // 创建点云对象
        const pointCloud = new THREE.Points(points.geometry, material);
        scene.add(pointCloud);

        // 在 GUI 中添加点云相关设置
        const folder = attributesFolder.addFolder(`点云 0`);
        const text = { pointsNum: points.geometry.attributes.position.count, file: "初始pcd" };
        folder.add(text, 'file').name('文件');
        folder.add(text, 'pointsNum').name('点数');
        folder.add(material, 'size', 0.001, 0.03).name('点大小');
        folder.addColor(material, 'color').name('点颜色');
    });
}

6. 参数调整更新
  1. 创建和配置 GUI

    • 创建 GUI 实例:使用 GUI 类创建了一个 GUI 实例。
    • 设置 GUI 样式:通过 domElement 对象的样式属性设置 GUI 的位置和样式。
    var plcgui = new GUI();
    plcgui.domElement.style.left = '0.1%';
    plcgui.domElement.style.top = '175px';
    plcgui.domElement.style.position = 'absolute';
    
    • 定义参数对象 params:包含两个属性 meanKstddevMulThresh,分别表示均值的 K 值和标准差的倍数阈值。
    • 使用 plcgui.add 添加控件:将参数添加到 GUI 中,并使用 onChange 事件指定在值变化时调用 filterPointCloud 函数
    • 设置控件的范围和名称:对 meanK 设置范围为 1 到 100,对 stddevMulThresh 设置范围为 0.1 到 10,并为每个控件指定名称。
    const params = {
        meanK: 40,
        stddevMulThresh: 3.0
    };
    plcgui.add(params, 'meanK', 1, 100).name('meanK').onChange(filterPointCloud);
    plcgui.add(params, 'stddevMulThresh', 0.1, 10).name('stddevMulThresh').onChange(filterPointCloud);
    
  2. 过滤点云函数

    与之前的初始滤波的操作一致

    async function filterPointCloud() {
        const cloudBuffer = await fetch("./images/point_cloud.pcd").then((res) =>
            res.arrayBuffer()
        );
        cloud = PCL.loadPCDData(cloudBuffer, PCL.PointXYZ);
        const sor = new PCL.StatisticalOutlierRemoval();
        sor.setInputCloud(cloud);
        sor.setMeanK(params.meanK);
        sor.setStddevMulThresh(params.stddevMulThresh);
        const cloudFiltered = sor.filter();
    
        cloudFilteredData = PCL.savePCDDataASCII(cloudFiltered);
        cloudOriginalData = PCL.savePCDDataASCII(cloud);
    }
    
7. 渲染循环
function animate() {
    requestAnimationFrame(animate);

    // 渲染场景
    renderer.render(scene, camera);
}

animate();
2.2.2 PCLKeyPoints.js

实现点云关键点提取操作

大致内容与 PCLFilter.js 相似,这里只对关键差异之处进行描述

1. 关键点提取
  • 计算点云分辨率: 使用 PCL.computeCloudResolution 计算点云的分辨率。
  • 创建 Kd 树和 ISS 关键点提取器: 使用 PCL.SearchKdTree 创建 Kd 树,使用 PCL.ISSKeypoint3D 创建 ISS 关键点提取器。
  • 设置参数: 设置 ISS 关键点提取器的各项参数,如搜索半径、非极大值抑制半径、阈值等。
  • 计算关键点: 使用 compute 方法计算关键点,并将结果保存在 keypoints 中。

注意:此处是将结果(关键点)保存到了 keypoints 当中

let cloud;
let keypoints;

async function main() {
    const cloudBuffer = await fetch("./images/point_cloud.pcd").then((res) =>
        res.arrayBuffer()
    );

    await PCL.init({
        url: `https://cdn.jsdelivr.net/npm/pcl.js/dist/pcl-core.wasm`
    });

    cloud = PCL.loadPCDData(cloudBuffer, PCL.PointXYZ);
    const resolution = PCL.computeCloudResolution(cloud);
    const tree = new PCL.SearchKdTree();
    const iss = new PCL.ISSKeypoint3D();
    keypoints = new PCL.PointCloud();
    iss.setSearchMethod(tree);
    iss.setSalientRadius(6 * resolution);
    iss.setNonMaxRadius(4 * resolution);
    iss.setThreshold21(0.975);
    iss.setThreshold32(0.975);
    iss.setMinNeighbors(5);
    iss.setInputCloud(cloud);
    iss.compute(keypoints);

    cloudOriginalData = PCL.savePCDDataASCII(cloud);

    bindEvent();
}
2. 关键点显示

bindEvent() 函数中设置显示 false/true 来控制显示关键点

function bindEvent() {
...
    switch (mode) {
        case "original2":
            showPointCloud(false);
            break;
        case "filtered2":
            showPointCloud(true);
            break;
...
}
  • 展示关键点:如果 showKeypoints 为真,将关键点的坐标添加到 pos 数组中,并创建关键点的 BufferGeometryPointsMaterial
  • 创建点云对象:创建点云的 BufferGeometryPointsMaterial
  • 组合点云和关键点:将点云和关键点组合到一个 THREE.Group 中。
  • 调整位置:通过计算包围盒中心,调整组的位置,使其居中。
  • GUI 设置:在 GUI 中添加点云和关键点的相关设置,如文件名、点数、点大小、颜色等。
function showPointCloud(showKeypoints) {
...
    const pos = [];

    // 如果需要展示关键点
    if (showKeypoints) {
        for (let i = 0; i < keypoints.points.size; ++i) {
            const point = keypoints.points.get(i);
            pos.push(point.x, point.y, point.z);
        }
    }

    // 创建关键点 PointsMaterial
    const geometry = new THREE.BufferGeometry();
    geometry.setAttribute('position', new THREE.Float32BufferAttribute(pos, 3));
    const keypointsMaterial = new THREE.PointsMaterial({ size: 0.05, color: 0xff0000 });
    const keypointsMesh = new THREE.Points(geometry, keypointsMaterial);

    // 创建点云的 PointsMaterial
    const material = new THREE.PointsMaterial({ color: 0xffffff, size: 0.02, vertexColors: false });
    const pointCloud = new THREE.Points(points.geometry, material);

    // 创建一个组,将点云和关键点添加到组中
    const group = new THREE.Group();
    group.add(pointCloud);
    group.add(keypointsMesh);

    // 调整组的旋转,使其在显示时朝上
    group.rotation.set(Math.PI, 0, 0);

    // 计算组的包围盒
    const boundingBox = new THREE.Box3();
    boundingBox.setFromObject(group);

    // 获取包围盒中心
    const center = new THREE.Vector3();
    boundingBox.getCenter(center);

    // 计算平移向量,使组居中
    const translation = new THREE.Vector3();
    translation.subVectors(new THREE.Vector3(0, 0, 0), center);
    group.position.add(translation);

    // 将组添加到场景中
    scene.add(group);

    ...
    // 在GUI中添加关键点大小的调整
    folder.add(keypointsMaterial, 'size', 0.03, 0.1).name('关键点大小');
...
}
2.2.3 PCLCutter.js

实现点云最小切割操作

大致内容与 PCLFilter.js 相似,这里只对关键差异之处进行描述

1. 最小切割
  • 创建对象中心和前景点云: 创建一个表示对象中心的 PCL.PointXYZ 实例,并创建一个前景点云 foregroundPoints,将对象中心添加到其中。
  • 创建 MinCutSegmentation 分割器: 使用 PCL.MinCutSegmentation 创建点云分割器。
  • 设置分割器参数: 设置分割器的参数,包括前景点云、输入点云、半径、标准差、源权重和邻居数量等。
  • 执行分割: 执行分割操作。
  • 获取着色的点云: 使用getColoredCloud方法获取切割部分着色的点云数据,并保存到 cloudFilteredData 中。
async function main() {
    const cloudBuffer = await fetch("./images/point_cloud.pcd").then((res) =>
        res.arrayBuffer()
    );

    await PCL.init({
        url: `https://cdn.jsdelivr.net/npm/pcl.js/dist/pcl-core.wasm`
    });

    cloud = PCL.loadPCDData(cloudBuffer, PCL.PointXYZ);

    const objectCenter = new PCL.PointXYZ(2, 0, 0);
    const foregroundPoints = new PCL.PointCloud();
    foregroundPoints.addPoint(objectCenter);

    const seg = new PCL.MinCutSegmentation();
    seg.setForegroundPoints(foregroundPoints);
    seg.setInputCloud(cloud);
    seg.setRadius(3.0433856);
    seg.setSigma(0.1);
    seg.setSourceWeight(0.8);
    seg.setNumberOfNeighbours(14);
    seg.extract();
    const coloredCloud = seg.getColoredCloud();

    cloudFilteredData = PCL.savePCDDataASCII(coloredCloud);
    cloudOriginalData = PCL.savePCDDataASCII(cloud);

    bindEvent();
}
2. 最小切割显示

showPointCloud 函数中通过设置是否显示点云的顶点颜色来显示切割部分

let showVertColor = false;
// 当前是切割后的点云就显示点云颜色
if (currentPointCloud != cloudOriginalData) {
    showVertColor = true;
}

// 创建点云材质
const material = new THREE.PointsMaterial({ color: 0xffffff, size: 0.02, vertexColors: showVertColor });

3 源码

源码见 Github : 图像与动画实验

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

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

相关文章

php使用vue.js实现省市区三级联动

参考gpt 有问题问gpt 实现效果 现省市区三级联动的方法可以使用PHP结合AJAX异步请求来实现。下面是一个简单的示例代码&#xff1a; HTML部分&#xff1a; <!DOCTYPE html> <html> <head><meta charset"UTF-8"><title>省市区三级联动…

vue-seamless-scroll无缝滚动组件

首先找到他的官网vue-seamless-scroll 1.进行安装依赖 vue2 npm install vue-seamless-scroll --save vue3 npm install vue3-seamless-scroll --save 2.全局引入 vue2 import scroll from vue-seamless-scroll Vue.use(scroll) vue3 import vue3SeamlessScroll fro…

JVM 内存分析工具 Memory Analyzer Tool(MAT)的深度讲解

目录 一. 前言 二. MAT 使用场景及主要解决问题 三. MAT 基础概念 3.1. Heap Dump 3.2. Shallow Heap 3.3. Retained Set 3.4. Retained Heap 3.5. Dominator Tree 3.6. OQL 3.7. references 四. MAT 功能概述 4.1. 内存分布 4.2. 对象间依赖 4.3. 对象状态 4.4…

【交流】PHP生成唯一邀请码

目录 前言&#xff1a; 1.随机生成&#xff0c;核对user表是否已存在 代码&#xff1a; 解析&#xff1a; 缺点&#xff1a; 2.建表建库&#xff0c;每次从表中随机抽取一条&#xff0c;用完时扩充 表结构 表视图 代码 解析 缺点 结论&#xff1a; 前言&#xff1a; …

【rabbitMQ】rabbitMQ的下载,安装与配置

目录 1. 下载Erland 安装步骤&#xff1a; 配置环境变量&#xff1a; 校验环境变量配置是否成功 2.下载MQ 安装步骤&#xff1a; 添加可视化插件 &#xff1a; 启动&#xff1a; 拒绝访问 1. 下载Erland 因为rabbitMQ是基于Erland,所以在安装rabbitMQ之前需要安装Erla…

距离度量(各距离含义)

欧氏距离 在n维空间中两点的真实距离&#xff0c;向量的自然长度 由于欧几里得几何学的关系称为欧氏距离 二维空间两点计算公式&#xff1a; d ( x 1 − x 2 ) 2 ( y 1 − y 2 ) 2 d \sqrt{(x_1 - x_2)^2 (y_1 - y_2)^2} d(x1​−x2​)2(y1​−y2​)2 ​ 三维空间两点计算…

7.MySQL 存储过程

目录 概述 概念&#xff1a; 特性&#xff1a; 变量 局部变量 定义方法&#xff1a; 语法1: 语法2: 用户变量 语法&#xff1a; 系统变量 全局变量 会话变量 参数传递 in out inout 流程控制 分支语句 if case 循环语句 循环控制: while while while…

Java面试遇到的一些常见题

目录 1. Java语言有几种基本类型&#xff0c;分别是什么&#xff1f; 整数类型&#xff08;Integer Types&#xff09;&#xff1a; 浮点类型&#xff08;Floating-Point Types&#xff09;&#xff1a; 字符类型&#xff08;Character Type&#xff09;&#xff1a; 布尔类…

基于Springboot的校园失物招领系统(有报告)。Javaee项目,springboot项目。

演示视频&#xff1a; 基于Springboot的校园失物招领系统&#xff08;有报告&#xff09;。Javaee项目&#xff0c;springboot项目。 项目介绍&#xff1a; 采用M&#xff08;model&#xff09;V&#xff08;view&#xff09;C&#xff08;controller&#xff09;三层体系结构…

【智能家居】七、人脸识别 翔云平台编程使用(编译openSSL支持libcurl的https访问、安装SSL依赖库openSSL)

一、翔云 人工智能开放平台 API文档开发示例下载 二、编译openSSL支持libcurl的https访问 安装SSL依赖库openSSL(使用工具wget)libcurl库重新配置&#xff0c;编译&#xff0c;安装运行&#xff08;运行需添加动态库为环境变量&#xff09; 三、编程实现人脸识别 四、Base6…

react中使用react-konva实现画板框选内容

文章目录 一、前言1.1、API文档1.2、Github仓库 二、图形2.1、拖拽draggable2.2、图片Image2.3、变形Transformer 三、实现3.1、依赖3.2、源码3.2.1、KonvaContainer组件3.2.2、use-key-press文件 3.3、效果图 四、最后 一、前言 本文用到的react-konva是基于react封装的图形绘…

【rabbitMQ】rabbitMQ控制台模拟收发消息

目录 1.新建队列 2.交换机绑定队列 3.查看消息是否到达队列 总结&#xff1a; 1.新建队列 2.交换机绑定队列 点击amq.fonout 3.查看消息是否到达队列 总结&#xff1a; 生产者&#xff08;publisher&#xff09;发送消息&#xff0c;先到达交换机&#xff0c;再到队列&…

深度学习之全面了解预训练模型

在本专栏中&#xff0c;我们将讨论预训练模型。有很多模型可供选择&#xff0c;因此也有很多考虑事项。 这次的专栏与以往稍有不同。我要回答的问题全部源于 MathWorks 社区论坛&#xff08;ww2.mathworks.cn/matlabcentral/&#xff09;的问题。我会首先总结 MATLAB Answers …

计算机视觉-05-目标检测:LeNet的PyTorch复现(MNIST手写数据集篇)(包含数据和代码)

文章目录 0. 数据下载1. 背景描述2. 预测目的3. 数据总览4. 数据预处理4.1 下载并加载数据&#xff0c;并做出一定的预先处理4.2 搭建 LeNet-5 神经网络结构&#xff0c;并定义前向传播的过程4.3 将定义好的网络结构搭载到 GPU/CPU&#xff0c;并定义优化器4.4 定义训练过程4.5…

机器学习算法(9)——集成技术(Bagging——随机森林分类器和回归)

一、说明 在这篇文章&#xff0c;我将向您解释集成技术和著名的集成技术之一&#xff0c;它属于装袋技术&#xff0c;称为随机森林分类器和回归。 集成技术是机器学习技术&#xff0c;它结合多个基本模块和模型来创建最佳预测模型。为了更好地理解这个定义&#xff0c;我们需要…

C语言进阶之路之结构体、枚举关卡篇

目录 一、学习目标 二、组合数据类型-结构体 结构体基本概念 结构体的声明&#xff1a; 小怪实战 结构体初始化 指定成员初始化的好处&#xff1a; 结构体成员引用 结构体指针与数组 关卡BOOS 三、结构体的尺寸 CPU字长 地址对齐 结构体的M值 可移植性 四、联合体…

ssm的健身房预约系统(有报告)。Javaee项目。ssm项目。

演示视频&#xff1a; ssm的健身房预约系统&#xff08;有报告&#xff09;。Javaee项目。ssm项目。 项目介绍&#xff1a; 采用M&#xff08;model&#xff09;V&#xff08;view&#xff09;C&#xff08;controller&#xff09;三层体系结构&#xff0c;通过Spring Spring…

极智一周 | AI 算力国产化、通义开源、Gemini、鸿蒙、蔚来 And so on

欢迎关注我的公众号 [极智视界]&#xff0c;获取我的更多技术分享 大家好&#xff0c;我是极智视界&#xff0c;带来本周的 [极智一周]&#xff0c;关键词&#xff1a;AI 算力国产化、通义开源、Gemini、鸿蒙、蔚来 And so on。 邀您加入我的知识星球「极智视界」&#xff0c;…

c-语言->数据在内存的存储

系列文章目录 文章目录 系列文章目录前言 前言 目的&#xff1a;学习整数在内存的储存&#xff0c;什么是大小端&#xff0c;浮点数的储存。 1. 整数在内存中的存储 在讲解操作符的时候&#xff0c;我们就讲过了下⾯的内容&#xff1a; 整数的2进制表⽰⽅法有三种&#xff0…

带有 RaspiCam 的 Raspberry Pi 监控和延时摄影摄像机

一、说明 一段时间以来&#xff0c;我一直想构建一个运动激活且具有延时功能的树莓派相机&#xff0c;但从未真正找到我喜欢的案例。我在thingiverse上找到了这个适合树莓派和相机的好案例。它是为特定的鱼眼相机设计的&#xff0c;但从模型来看&#xff0c;我拥有的廉价中国鱼…