【AR】使用深度API实现虚实遮挡

遮挡效果

本段描述摘自 https://developers.google.cn/ar/develop/depth

遮挡是深度API的应用之一。
遮挡(即准确渲染虚拟物体在现实物体后面)对于沉浸式 AR 体验至关重要。
参考下图,假设场景中有一个Andy,用户可能需要放置在包含门边有后备箱的场景中。渲染时没有遮挡,Andy 会不切实际地与树干边缘重叠。如果您使用场景的深度来了解虚拟 Andy 相对于木箱等周围环境的距离,就可以准确地渲染 Andy 的遮挡效果,使其在周围环境中看起来更逼真。

图片源自 https://developers.google.cn/ar/develop/depth
在这里插入图片描述

使用ARFoundation

ARFoundation中提供了AROcclusionManager脚本,在AR Session Origin的AR Camera对象上挂载该脚本即可。在场景启动后,会自动启用虚实遮挡(当然Depth Mode 不能选择的是disable)。

在这里插入图片描述

AROcclusionManager脚本内容如下:

using System;
using System.Collections.Generic;
using Unity.Collections;
using UnityEngine.Serialization;
using UnityEngine.XR.ARSubsystems;
using UnityEngine.Rendering;namespace UnityEngine.XR.ARFoundation
{/// <summary>/// The manager for the occlusion subsystem./// </summary>[DisallowMultipleComponent][DefaultExecutionOrder(ARUpdateOrder.k_OcclusionManager)][HelpURL(HelpUrls.ApiWithNamespace + nameof(AROcclusionManager) + ".html")]public sealed class AROcclusionManager :SubsystemLifecycleManager<XROcclusionSubsystem, XROcclusionSubsystemDescriptor, XROcclusionSubsystem.Provider>{/// <summary>/// The list of occlusion texture infos./// </summary>/// <value>/// The list of occlusion texture infos./// </value>readonly List<ARTextureInfo> m_TextureInfos = new List<ARTextureInfo>();/// <summary>/// The list of occlusion textures./// </summary>/// <value>/// The list of occlusion textures./// </value>readonly List<Texture2D> m_Textures = new List<Texture2D>();/// <summary>/// The list of occlusion texture property IDs./// </summary>/// <value>/// The list of occlusion texture property IDs./// </value>readonly List<int> m_TexturePropertyIds = new List<int>();/// <summary>/// The human stencil texture info./// </summary>/// <value>/// The human stencil texture info./// </value>ARTextureInfo m_HumanStencilTextureInfo;/// <summary>/// The human depth texture info./// </summary>/// <value>/// The human depth texture info./// </value>ARTextureInfo m_HumanDepthTextureInfo;/// <summary>/// The environment depth texture info./// </summary>/// <value>/// The environment depth texture info./// </value>ARTextureInfo m_EnvironmentDepthTextureInfo;/// <summary>/// The environment depth confidence texture info./// </summary>/// <value>/// The environment depth confidence texture info./// </value>ARTextureInfo m_EnvironmentDepthConfidenceTextureInfo;/// <summary>/// An event which fires each time an occlusion camera frame is received./// </summary>public event Action<AROcclusionFrameEventArgs> frameReceived;/// <summary>/// The mode for generating the human segmentation stencil texture./// This method is obsolete./// Use <see cref="requestedHumanStencilMode"/>/// or  <see cref="currentHumanStencilMode"/> instead./// </summary>[Obsolete("Use requestedSegmentationStencilMode or currentSegmentationStencilMode instead. (2020-01-14)")]public HumanSegmentationStencilMode humanSegmentationStencilMode{get => m_HumanSegmentationStencilMode;set => requestedHumanStencilMode = value;}/// <summary>/// The requested mode for generating the human segmentation stencil texture./// </summary>public HumanSegmentationStencilMode requestedHumanStencilMode{get => subsystem?.requestedHumanStencilMode ?? m_HumanSegmentationStencilMode;set{m_HumanSegmentationStencilMode = value;if (enabled && descriptor?.humanSegmentationStencilImageSupported == Supported.Supported){subsystem.requestedHumanStencilMode = value;}}}/// <summary>/// Get the current mode in use for generating the human segmentation stencil mode./// </summary>public HumanSegmentationStencilMode currentHumanStencilMode => subsystem?.currentHumanStencilMode ?? HumanSegmentationStencilMode.Disabled;[SerializeField][Tooltip("The mode for generating human segmentation stencil texture.\n\n"+ "Disabled -- No human stencil texture produced.\n"+ "Fastest -- Minimal rendering quality. Minimal frame computation.\n"+ "Medium -- Medium rendering quality. Medium frame computation.\n"+ "Best -- Best rendering quality. Increased frame computation.")]HumanSegmentationStencilMode m_HumanSegmentationStencilMode = HumanSegmentationStencilMode.Disabled;/// <summary>/// The mode for generating the human segmentation depth texture./// This method is obsolete./// Use <see cref="requestedHumanDepthMode"/>/// or  <see cref="currentHumanDepthMode"/> instead./// </summary>[Obsolete("Use requestedSegmentationDepthMode or currentSegmentationDepthMode instead. (2020-01-15)")]public HumanSegmentationDepthMode humanSegmentationDepthMode{get => m_HumanSegmentationDepthMode;set => requestedHumanDepthMode = value;}/// <summary>/// Get or set the requested human segmentation depth mode./// </summary>public HumanSegmentationDepthMode requestedHumanDepthMode{get => subsystem?.requestedHumanDepthMode ?? m_HumanSegmentationDepthMode;set{m_HumanSegmentationDepthMode = value;if (enabled && descriptor?.humanSegmentationDepthImageSupported == Supported.Supported){subsystem.requestedHumanDepthMode = value;}}}/// <summary>/// Get the current human segmentation depth mode in use by the subsystem./// </summary>public HumanSegmentationDepthMode currentHumanDepthMode => subsystem?.currentHumanDepthMode ?? HumanSegmentationDepthMode.Disabled;[SerializeField][Tooltip("The mode for generating human segmentation depth texture.\n\n"+ "Disabled -- No human depth texture produced.\n"+ "Fastest -- Minimal rendering quality. Minimal frame computation.\n"+ "Best -- Best rendering quality. Increased frame computation.")]HumanSegmentationDepthMode m_HumanSegmentationDepthMode = HumanSegmentationDepthMode.Disabled;/// <summary>/// Get or set the requested environment depth mode./// </summary>public EnvironmentDepthMode requestedEnvironmentDepthMode{get => subsystem?.requestedEnvironmentDepthMode ?? m_EnvironmentDepthMode;set{m_EnvironmentDepthMode = value;if (enabled && descriptor?.environmentDepthImageSupported == Supported.Supported){subsystem.requestedEnvironmentDepthMode = value;}}}/// <summary>/// Get the current environment depth mode in use by the subsystem./// </summary>public EnvironmentDepthMode currentEnvironmentDepthMode => subsystem?.currentEnvironmentDepthMode ?? EnvironmentDepthMode.Disabled;[SerializeField][Tooltip("The mode for generating the environment depth texture.\n\n"+ "Disabled -- No environment depth texture produced.\n"+ "Fastest -- Minimal rendering quality. Minimal frame computation.\n"+ "Medium -- Medium rendering quality. Medium frame computation.\n"+ "Best -- Best rendering quality. Increased frame computation.")]EnvironmentDepthMode m_EnvironmentDepthMode = EnvironmentDepthMode.Fastest;[SerializeField]bool m_EnvironmentDepthTemporalSmoothing = true;/// <summary>/// Whether temporal smoothing should be applied to the environment depth image. Query for support with/// [environmentDepthTemporalSmoothingSupported](xref:UnityEngine.XR.ARSubsystems.XROcclusionSubsystemDescriptor.environmentDepthTemporalSmoothingSupported)./// </summary>/// <value>When `true`, temporal smoothing is applied to the environment depth image. Otherwise, no temporal smoothing is applied.</value>public bool environmentDepthTemporalSmoothingRequested{get => subsystem?.environmentDepthTemporalSmoothingRequested ?? m_EnvironmentDepthTemporalSmoothing;set{m_EnvironmentDepthTemporalSmoothing = value;if (enabled && descriptor?.environmentDepthTemporalSmoothingSupported == Supported.Supported){subsystem.environmentDepthTemporalSmoothingRequested = value;}}}/// <summary>/// Whether temporal smoothing is applied to the environment depth image. Query for support with/// [environmentDepthTemporalSmoothingSupported](xref:UnityEngine.XR.ARSubsystems.XROcclusionSubsystemDescriptor.environmentDepthTemporalSmoothingSupported)./// </summary>/// <value>Read Only.</value>public bool environmentDepthTemporalSmoothingEnabled => subsystem?.environmentDepthTemporalSmoothingEnabled ?? false;/// <summary>/// Get or set the requested occlusion preference mode./// </summary>public OcclusionPreferenceMode requestedOcclusionPreferenceMode{get => subsystem?.requestedOcclusionPreferenceMode ?? m_OcclusionPreferenceMode;set{m_OcclusionPreferenceMode = value;if (enabled && subsystem != null){subsystem.requestedOcclusionPreferenceMode = value;}}}/// <summary>/// Get the current occlusion preference mode in use by the subsystem./// </summary>public OcclusionPreferenceMode currentOcclusionPreferenceMode => subsystem?.currentOcclusionPreferenceMode ?? OcclusionPreferenceMode.PreferEnvironmentOcclusion;[SerializeField][Tooltip("If both environment texture and human stencil & depth textures are available, this mode specifies which should be used for occlusion.")]OcclusionPreferenceMode m_OcclusionPreferenceMode = OcclusionPreferenceMode.PreferEnvironmentOcclusion;/// <summary>/// The human segmentation stencil texture./// </summary>/// <value>/// The human segmentation stencil texture, if any. Otherwise, <c>null</c>./// </value>public Texture2D humanStencilTexture{get{if (descriptor?.humanSegmentationStencilImageSupported == Supported.Supported &&subsystem.TryGetHumanStencil(out var humanStencilDescriptor)){m_HumanStencilTextureInfo = ARTextureInfo.GetUpdatedTextureInfo(m_HumanStencilTextureInfo,humanStencilDescriptor);DebugAssert.That(((m_HumanStencilTextureInfo.descriptor.dimension == TextureDimension.Tex2D)|| (m_HumanStencilTextureInfo.descriptor.dimension == TextureDimension.None)))?.WithMessage("Human Stencil Texture needs to be a Texture 2D, but instead is "+ $"{m_HumanStencilTextureInfo.descriptor.dimension.ToString()}.");return m_HumanStencilTextureInfo.texture as Texture2D;}return null;}}/// <summary>/// Attempt to get the latest human stencil CPU image. This provides directly access to the raw pixel data./// </summary>/// <remarks>/// The `XRCpuImage` must be disposed to avoid resource leaks./// </remarks>/// <param name="cpuImage">If this method returns `true`, an acquired `XRCpuImage`.</param>/// <returns>Returns `true` if the CPU image was acquired. Returns `false` otherwise.</returns>public bool TryAcquireHumanStencilCpuImage(out XRCpuImage cpuImage){if (descriptor?.humanSegmentationStencilImageSupported == Supported.Supported){return subsystem.TryAcquireHumanStencilCpuImage(out cpuImage);}cpuImage = default;return false;}/// <summary>/// The human segmentation depth texture./// </summary>/// <value>/// The human segmentation depth texture, if any. Otherwise, <c>null</c>./// </value>public Texture2D humanDepthTexture{get{if (descriptor?.humanSegmentationDepthImageSupported == Supported.Supported &&subsystem.TryGetHumanDepth(out var humanDepthDescriptor)){m_HumanDepthTextureInfo = ARTextureInfo.GetUpdatedTextureInfo(m_HumanDepthTextureInfo,humanDepthDescriptor);DebugAssert.That(m_HumanDepthTextureInfo.descriptor.dimension == TextureDimension.Tex2D|| m_HumanDepthTextureInfo.descriptor.dimension == TextureDimension.None)?.WithMessage("Human Depth Texture needs to be a Texture 2D, but instead is "+ $"{m_HumanDepthTextureInfo.descriptor.dimension.ToString()}.");return m_HumanDepthTextureInfo.texture as Texture2D;}return null;}}/// <summary>/// Attempt to get the latest environment depth confidence CPU image. This provides direct access to the/// raw pixel data./// </summary>/// <remarks>/// The `XRCpuImage` must be disposed to avoid resource leaks./// </remarks>/// <param name="cpuImage">If this method returns `true`, an acquired `XRCpuImage`.</param>/// <returns>Returns `true` if the CPU image was acquired. Returns `false` otherwise.</returns>public bool TryAcquireEnvironmentDepthConfidenceCpuImage(out XRCpuImage cpuImage){if (descriptor?.environmentDepthConfidenceImageSupported == Supported.Supported){return subsystem.TryAcquireEnvironmentDepthConfidenceCpuImage(out cpuImage);}cpuImage = default;return false;}/// <summary>/// The environment depth confidence texture./// </summary>/// <value>/// The environment depth confidence texture, if any. Otherwise, <c>null</c>./// </value>public Texture2D environmentDepthConfidenceTexture{get{if (descriptor?.environmentDepthConfidenceImageSupported == Supported.Supported&& subsystem.TryGetEnvironmentDepthConfidence(out var environmentDepthConfidenceDescriptor)){m_EnvironmentDepthConfidenceTextureInfo = ARTextureInfo.GetUpdatedTextureInfo(m_EnvironmentDepthConfidenceTextureInfo,environmentDepthConfidenceDescriptor);DebugAssert.That(m_EnvironmentDepthConfidenceTextureInfo.descriptor.dimension == TextureDimension.Tex2D|| m_EnvironmentDepthConfidenceTextureInfo.descriptor.dimension == TextureDimension.None)?.WithMessage("Environment depth confidence texture needs to be a Texture 2D, but instead is "+ $"{m_EnvironmentDepthConfidenceTextureInfo.descriptor.dimension.ToString()}.");return m_EnvironmentDepthConfidenceTextureInfo.texture as Texture2D;}return null;}}/// <summary>/// Attempt to get the latest human depth CPU image. This provides direct access to the raw pixel data./// </summary>/// <remarks>/// The `XRCpuImage` must be disposed to avoid resource leaks./// </remarks>/// <param name="cpuImage">If this method returns `true`, an acquired `XRCpuImage`.</param>/// <returns>Returns `true` if the CPU image was acquired. Returns `false` otherwise.</returns>public bool TryAcquireHumanDepthCpuImage(out XRCpuImage cpuImage){if (descriptor?.humanSegmentationDepthImageSupported == Supported.Supported){return subsystem.TryAcquireHumanDepthCpuImage(out cpuImage);}cpuImage = default;return false;}/// <summary>/// The environment depth texture./// </summary>/// <value>/// The environment depth texture, if any. Otherwise, <c>null</c>./// </value>public Texture2D environmentDepthTexture{get{if (descriptor?.environmentDepthImageSupported == Supported.Supported&& subsystem.TryGetEnvironmentDepth(out var environmentDepthDescriptor)){m_EnvironmentDepthTextureInfo = ARTextureInfo.GetUpdatedTextureInfo(m_EnvironmentDepthTextureInfo,environmentDepthDescriptor);DebugAssert.That(m_EnvironmentDepthTextureInfo.descriptor.dimension == TextureDimension.Tex2D|| m_EnvironmentDepthTextureInfo.descriptor.dimension == TextureDimension.None)?.WithMessage("Environment depth texture needs to be a Texture 2D, but instead is "+ $"{m_EnvironmentDepthTextureInfo.descriptor.dimension.ToString()}.");return m_EnvironmentDepthTextureInfo.texture as Texture2D;}return null;}}/// <summary>/// Attempt to get the latest environment depth CPU image. This provides direct access to the raw pixel data./// </summary>/// <remarks>/// The `XRCpuImage` must be disposed to avoid resource leaks./// </remarks>/// <param name="cpuImage">If this method returns `true`, an acquired `XRCpuImage`.</param>/// <returns>Returns `true` if the CPU image was acquired. Returns `false` otherwise.</returns>public bool TryAcquireEnvironmentDepthCpuImage(out XRCpuImage cpuImage){if (descriptor?.environmentDepthImageSupported == Supported.Supported){return subsystem.TryAcquireEnvironmentDepthCpuImage(out cpuImage);}cpuImage = default;return false;}/// <summary>/// Attempt to get the latest raw environment depth CPU image. This provides direct access to the raw pixel data./// </summary>/// <remarks>/// > [!NOTE]/// > The `XRCpuImage` must be disposed to avoid resource leaks./// This differs from <see cref="TryAcquireEnvironmentDepthCpuImage"/> in that it always tries to acquire the/// raw environment depth image, whereas <see cref="TryAcquireEnvironmentDepthCpuImage"/> depends on the value/// of <see cref="environmentDepthTemporalSmoothingEnabled"/>./// </remarks>/// <param name="cpuImage">If this method returns `true`, an acquired `XRCpuImage`.</param>/// <returns>Returns `true` if the CPU image was acquired. Returns `false` otherwise.</returns>public bool TryAcquireRawEnvironmentDepthCpuImage(out XRCpuImage cpuImage){if (subsystem == null){cpuImage = default;return false;}return subsystem.TryAcquireRawEnvironmentDepthCpuImage(out cpuImage);}/// <summary>/// Attempt to get the latest smoothed environment depth CPU image. This provides direct access to/// the raw pixel data./// </summary>/// <remarks>/// > [!NOTE]/// > The `XRCpuImage` must be disposed to avoid resource leaks./// This differs from <see cref="TryAcquireEnvironmentDepthCpuImage"/> in that it always tries to acquire the/// smoothed environment depth image, whereas <see cref="TryAcquireEnvironmentDepthCpuImage"/>/// depends on the value of <see cref="environmentDepthTemporalSmoothingEnabled"/>./// </remarks>/// <param name="cpuImage">If this method returns `true`, an acquired `XRCpuImage`.</param>/// <returns>Returns `true` if the CPU image was acquired. Returns `false` otherwise.</returns>public bool TryAcquireSmoothedEnvironmentDepthCpuImage(out XRCpuImage cpuImage){if (subsystem == null){cpuImage = default;return false;}return subsystem.TryAcquireSmoothedEnvironmentDepthCpuImage(out cpuImage);}/// <summary>/// Callback before the subsystem is started (but after it is created)./// </summary>protected override void OnBeforeStart(){requestedHumanStencilMode = m_HumanSegmentationStencilMode;requestedHumanDepthMode = m_HumanSegmentationDepthMode;requestedEnvironmentDepthMode = m_EnvironmentDepthMode;requestedOcclusionPreferenceMode = m_OcclusionPreferenceMode;environmentDepthTemporalSmoothingRequested = m_EnvironmentDepthTemporalSmoothing;ResetTextureInfos();}/// <summary>/// Callback when the manager is being disabled./// </summary>protected override void OnDisable(){base.OnDisable();ResetTextureInfos();InvokeFrameReceived();}/// <summary>/// Callback as the manager is being updated./// </summary>public void Update(){if (subsystem != null){UpdateTexturesInfos();InvokeFrameReceived();requestedEnvironmentDepthMode = m_EnvironmentDepthMode;requestedHumanDepthMode = m_HumanSegmentationDepthMode;requestedHumanStencilMode = m_HumanSegmentationStencilMode;requestedOcclusionPreferenceMode = m_OcclusionPreferenceMode;environmentDepthTemporalSmoothingRequested = m_EnvironmentDepthTemporalSmoothing;}}void ResetTextureInfos(){m_HumanStencilTextureInfo.Reset();m_HumanDepthTextureInfo.Reset();m_EnvironmentDepthTextureInfo.Reset();m_EnvironmentDepthConfidenceTextureInfo.Reset();}/// <summary>/// Pull the texture descriptors from the occlusion subsystem, and update the texture information maintained by/// this component./// </summary>void UpdateTexturesInfos(){var textureDescriptors = subsystem.GetTextureDescriptors(Allocator.Temp);try{int numUpdated = Math.Min(m_TextureInfos.Count, textureDescriptors.Length);// Update the existing textures that are in common between the two arrays.for (int i = 0; i < numUpdated; ++i){m_TextureInfos[i] = ARTextureInfo.GetUpdatedTextureInfo(m_TextureInfos[i], textureDescriptors[i]);}// If there are fewer textures in the current frame than we had previously, destroy any remaining unneeded// textures.if (numUpdated < m_TextureInfos.Count){for (int i = numUpdated; i < m_TextureInfos.Count; ++i){m_TextureInfos[i].Reset();}m_TextureInfos.RemoveRange(numUpdated, (m_TextureInfos.Count - numUpdated));}// Else, if there are more textures in the current frame than we have previously, add new textures for any// additional descriptors.else if (textureDescriptors.Length > m_TextureInfos.Count){for (int i = numUpdated; i < textureDescriptors.Length; ++i){m_TextureInfos.Add(new ARTextureInfo(textureDescriptors[i]));}}}finally{if (textureDescriptors.IsCreated){textureDescriptors.Dispose();}}}/// <summary>/// Invoke the occlusion frame received event with the updated textures and texture property IDs./// </summary>void InvokeFrameReceived(){if (frameReceived != null){int numTextureInfos = m_TextureInfos.Count;m_Textures.Clear();m_TexturePropertyIds.Clear();m_Textures.Capacity = numTextureInfos;m_TexturePropertyIds.Capacity = numTextureInfos;for (int i = 0; i < numTextureInfos; ++i){DebugAssert.That(m_TextureInfos[i].descriptor.dimension == TextureDimension.Tex2D)?.WithMessage($"Texture needs to be a Texture 2D, but instead is {m_TextureInfos[i].descriptor.dimension.ToString()}.");m_Textures.Add((Texture2D)m_TextureInfos[i].texture);m_TexturePropertyIds.Add(m_TextureInfos[i].descriptor.propertyNameId);}subsystem.GetMaterialKeywords(out List<string> enabledMaterialKeywords, out List<string>disabledMaterialKeywords);AROcclusionFrameEventArgs args = new AROcclusionFrameEventArgs();args.textures = m_Textures;args.propertyNameIds = m_TexturePropertyIds;args.enabledMaterialKeywords = enabledMaterialKeywords;args.disabledMaterialKeywords = disabledMaterialKeywords;frameReceived(args);}}}
}

使用EQ-R实现

EQ-R

简介

EQ-Renderer是EQ基于sceneform(filament)扩展的一个用于安卓端的三维AR渲染器。

主要功能

它包含sceneform_v1.16.0中九成接口(剔除了如sfb资源加载等已弃用的内容),扩展了视频背景视图、解决了sceneform模型加载的内存泄漏问题、集成了AREngine和ORB-SLAM3、添加了场景坐标与地理坐标系(CGCS-2000)的转换方法。

注:由于精力有限,文档和示例都不完善。sceneform相关请直接参考谷歌官方文档,扩展部分接口说明请移步git联系。

相关链接

Git仓库
  • EQ-Renderer的示例工程
码云
  • EQ-Renderer的示例工程
EQ-R相关文档
  • 文档目录

使用示例

需要在安卓清单中添加其值设为“com.google.ar.core.depth>

接口调用

在使用ARSceneLayout 创建AR布局控件时,在适当的地方修改深度遮挡模式即可,示例如下。

ARSceneLayout layout = new ARSceneLayout(this);//使用普通3d视图
layout.getSceneView.getCameraStream()setDepthOcclusionMode(DepthOcclusionMode.DEPTH_OCCLUSION_ENABLED);

实现方式

获取深度图和相机帧,在着色器中根据深度数据处理。

EQ-R基于filament

filament材质如下:

material {name : depth,shadingModel : unlit,blending : opaque,vertexDomain : device,parameters : [{type : samplerExternal,name : cameraTexture},{type : sampler2d,name : depthTexture},{type : float4x4,name : uvTransform}],requires : [uv0]
}fragment {void material(inout MaterialInputs material) {prepareMaterial(material);material.baseColor.rgb = inverseTonemapSRGB(texture(materialParams_cameraTexture, getUV0()).rgb);vec2 packed_depth = texture(materialParams_depthTexture, getUV0()).xy;float depth_mm = dot(packed_depth, vec2(255.f, 256.f * 255.f));vec4 view = mulMat4x4Float3(getClipFromViewMatrix(), vec3(0.f, 0.f, -depth_mm / 1000.f));float ndc_depth = view.z / view.w;gl_FragDepth = 1.f - ((ndc_depth + 1.f) / 2.f);}
}vertex {void materialVertex(inout MaterialVertexInputs material) {material.uv0 = mulMat4x4Float3(materialParams.uvTransform, vec3(material.uv0.x, material.uv0.y, 0.f)).xy;}
} 

示例应用

之前基于Android(Java)做过的示例应用。

管线巡检示例 :开挖显示、卷帘效果…

在这里插入图片描述

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

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

相关文章

揭秘英特尔AI芯片如何做到比H100训练快40%、推理快50%

英特尔&#xff0c;开始正面硬刚英伟达了。 深夜时分&#xff0c;英特尔CEO帕特基辛格激动展示全新AI芯片Gaudi 3&#xff0c;引领未来科技潮流&#xff0c;开启智能新篇章。 他为什么开心到现场直接蹦迪&#xff1f; 看下Gaudi 3的性能结果&#xff0c;就一目了然了&#xf…

算法打卡day32

今日任务&#xff1a; 1&#xff09;738.单调递增的数字 2&#xff09;968.监控二叉树 738.单调递增的数字 题目链接&#xff1a;738. 单调递增的数字 - 力扣&#xff08;LeetCode&#xff09; 文章讲解&#xff1a;代码随想录 (programmercarl.com) 视频讲解&#xff1a;贪…

初学网络编程

网络编程是指编写能够在网络环境中运行&#xff0c;进行数据通信的程序的过程。它涵盖了从建立网络连接、发送和接收数据&#xff0c;到关闭连接等一系列操作。网络编程是开发网络应用程序的基础&#xff0c;它使得不同的计算机和设备能够通过网络进行数据交换和通信。 三个核…

ELK企业级日志分析系统(elasticsearch+logstash+kibana)

目录 一.ELK概述 1.定义 &#xff08;1&#xff09;ElasticSearch &#xff08;2&#xff09;Kiabana &#xff08;3&#xff09;Logstash &#xff08;4&#xff09;Filebeat 2.filebeat结合logstash带来好处 3.为什么要是用ELK&#xff1f; 4.完整日志系统基本特征 …

Docker学习笔记(一):入门篇,Docker概述、基本组成等,对Docker有一个初步的认识

前言 记录时间 [2024-4-5] 在先前的文章中&#xff0c;笔者进行了Windows系统下YOLOv8模型的简单测试&#xff0c;并由此引发思考&#xff1a;是否能尝试将此模型运行在Linux中呢&#xff1f;又或者&#xff0c;运行在Docker中。关于Docker的学习就这么展开了。 本文便是有关D…

RX8130CE为用户提供带复位延迟和主备电管理的解决方案

实时时钟作为设备的精确时钟来源&#xff0c;其作用如同人的心脏&#xff0c;为设备提供准确稳定的心跳.而便携式设备由于应用场景多变&#xff0c;所以对内部元器件要求也相对较高&#xff0c;这就对作为核心器件的实时时钟模块提出不少挑战。世强代理品牌EPSON实时钟模块产品…

【Linux】开始了解重定向

送给大家一句话&#xff1a; 人真正的名字是&#xff1a;欲望。所以你得知道&#xff0c;消灭恐惧最有效的办法&#xff0c;就是消灭欲望。 – 史铁生 《我与地坛》 开始了解重定向 1 前言2 重定向与缓冲区2.1 文件描述符分配规则2.2 重定向的现象2.3 重定向的理解2.4 缓冲区…

5.6 mybatis之RowBounds分页用法

文章目录 mybatis 中&#xff0c;使用 RowBounds 进行分页&#xff0c;非常方便&#xff0c;不需要在 sql 语句中写 limit&#xff0c;即可完成分页功能。但是由于它是在 sql 查询出所有结果的基础上截取数据的&#xff0c;所以在数据量大的sql中并不适用&#xff0c;它更适合在…

【Python】OPC UA 服务器扫描工具

引言 OPC UA&#xff08;开放平台通信统一架构&#xff09;是一种跨平台的、开放的数据交换标准&#xff0c;广泛用于工业自动化领域。在工业4.0的大背景下&#xff0c;OPC UA服务器在网络中的部署日益增多&#xff0c;如何快速有效地发现这些服务器成为了一个实际需求。本文将…

UI自动化测试重点思考(下)--装饰器/生成器/夹具的使用/描述符的作用/ddt驱动/多线程

UI自动化测试重点思考--装饰器 装饰器装饰器定义装饰器代码示例装饰器的执行如何将装饰器融合到pytest框架里面 生成器创建生成器生成器的定义如何将生成器融合到pytest框架里面 fixture&#xff08;夹具&#xff09;使用pytest fixture 中 scope 参数的详细解释 描述符的总结描…

【Sentinel的限流使用】⭐️SpringBoot整合Sentinel实现Api的限流

目录 前言 一、Sentinel下载 二、SpringBoot 整合 Sentinel 三、流控规则 章末 前言 小伙伴们大家好&#xff0c;上次使用OpenFeign时用到了 Hystrix实现熔断和限流的功能&#xff0c;但是发现该工具已经停止维护了&#xff0c;于是想到了Spring Cloud Alibaba开发的Sentin…

高创新 | Matlab实现OOA-CNN-GRU-Attention鱼鹰算法优化卷积门控循环单元注意力机制多变量回归预测

高创新 | Matlab实现OOA-CNN-GRU-Attention鱼鹰算法优化卷积门控循环单元注意力机制多变量回归预测 目录 高创新 | Matlab实现OOA-CNN-GRU-Attention鱼鹰算法优化卷积门控循环单元注意力机制多变量回归预测预测效果基本介绍程序设计参考资料 预测效果 基本介绍 1.Matlab实现OOA…

如何在CentOS7.x上生成自签名SSL证书

在配置HTTPS连接时&#xff0c;SSL证书是确保数据传输安全性的关键组件。自签名证书是一种不通过证书颁发机构&#xff08;CA&#xff09;签发的证书&#xff0c;适用于测试和内部使用。以下是在CentOS 7.x系统上生成自签名证书的详细步骤。 1. 安装OpenSSL OpenSSL是一个强大…

【嵌入式学习】ARM day04.11

一、思维导图 二、练习 实现三个灯闪烁 汇编代码 .text .global _start _start: 使能GPIOE和F时钟LDR r0,0x50000A28LDR r1,[R0]ORR R1,R1,#(0X3<<4)STR R1,[R0]配置GPIOE和F的MODER寄存器LDR r0,0x50006000 GPIOELDR R1,0X50007000 G…

顶顶通呼叫中心中间件-回铃音补偿(mod_cti基于FreeSWITCH)

顶顶通呼叫中心中间件-回铃音补偿(mod_cti基于FreeSWITCH) 回铃音的用处 回铃音&#xff1a; 当别人打电话给你时&#xff0c;你的电话响铃了&#xff0c;而他听到的声音叫做回铃音。回铃音是被叫方向主叫方传送&#xff0c;也是彩铃功能的基础。我们平时打电话听到的“嘟 嘟…

【C++进阶】C++异常详解

C异常 一&#xff0c;传统处理错误方式二&#xff0c;C处理的方式三&#xff0c;异常的概念四&#xff0c;异常的使用4.1 异常和捕获的匹配原则4.2 函数调用链中异常栈展开匹配原则4.3 异常的重新抛出&#xff08;异常安全问题&#xff09;4.4 RAII思想在异常中的作用 五&#…

2024 Mathorcup高校数学建模挑战赛(B题)| 甲骨文识别 | 建模秘籍文章代码思路大全

铛铛&#xff01;小秘籍来咯&#xff01; 小秘籍团队独辟蹊径&#xff0c;以CNN卷积神经网络&#xff0c;计算机视觉等强大工具&#xff0c;构建了解决复杂问题的独特方案。深度学习, 混沌模型的妙用&#xff0c;为降低非法野生动物贸易提供新视角。通过综合分析&#xff0c;描…

IP广播对讲系统停车场解决方案

IP广播对讲系统停车场解决方案 一、需求分析 随着国民经济和社会的发展&#xff0c; 选择坐车出行的民众越来越多。在保护交通安全的同时&#xff0c;也给停车场服务部门提出了更高的要求。人们对停车场系统提出了更高的要求与挑战&#xff0c; 需要停车场系统提高工作效率与服…

01-Git 之快速入门操作本地仓库

https://learngitbranching.js.org/?localezh_CN在线练习git 1. Git 安装好Git以后, 先检查是否已经绑定了用户名和邮箱 git config --list1.1 为什么要使用版本控制&#xff1f; 从个人角度&#xff1a; 在做项目时&#xff0c;如果一点点去改代码会很乱&#xff0c;不利…

OpenCV4.9更多形态转换

返回&#xff1a;OpenCV系列文章目录&#xff08;持续更新中......&#xff09; 上一篇:OpenCV4.9处理平滑图像 下一篇:OpenCV4.9更多形态转换 基于这两者&#xff0c;我们可以对图像进行更复杂的转换。在这里&#xff0c;我们简要讨论 OpenCV 提供的 5 个操作&#xff1a; …