当前位置: 首页 > news >正文

Smart Light Random Memory Sprays Retinex 传统图像增强 SLRMSR

文章目录

  • 前言
  • 1、Smart Light Random Memory Sprays Retinex概况
  • 2、Smart Light Random Memory Sprays Retinex的实现
    • 2.1、SLRMSR算法的伪代码
    • 2.2、初始化记忆喷雾(CreateInitialMemorySpray)
    • 2.3、更新记忆喷雾 (UpdateMemorySpray)
    • 2.4、计算颜色校正因子(ComputeColorCorrectionFactor)
    • 2.5、应用强度重映射(ApplyIntensityRemapping)
    • 2.6、应用引导滤波 (ApplyGuidedImageFiltering)
  • 3、Smart Light Random Memory Sprays Retinex效果


前言

  Smart Light Random Memory Sprays Retinex,即“智能光随机记忆喷雾Retinex”,简称SLRMSR。作为一种新的基于Retinex理论的图像增强算法,旨在解决图像亮度调整和颜色校正的问题。


1、Smart Light Random Memory Sprays Retinex概况

论文名称:
Smart light random memory sprays Retinex: a fast Retinex implementation for high-quality brightness adjustment and color correction
作者:
Nikola Banić,Sven Lončarić

  “智能光随机记忆喷雾Retinex”(Smart Light Random Memory Sprays Retinex,简称SLRMSR),该算法提出了记忆喷雾的概念,以减少每个像素操作的数量,从而实现了快速的Retinex基础的局部图像增强。同时提出了一种有效的图像强度重映射的方法,进一步显著地提高了图像的质量。最后通过使用引导滤波作为替代的光照处理方法,减少了原有LRSR算法的光晕效应。作为一种新的基于Retinex理论的图像增强算法,在解决图像亮度调整和颜色校正的问题上,具有显著优势。

2、Smart Light Random Memory Sprays Retinex的实现

2.1、SLRMSR算法的伪代码

在这里插入图片描述

2.2、初始化记忆喷雾(CreateInitialMemorySpray)

  图像第一个像素创建一个包含随机选择的邻近像素强度的记忆喷雾。
① 定义喷雾大小:
  确定记忆喷雾参数的大小n,作为预设值,决定了喷雾中包含像素的数量。
② 选择邻近像素:
  对于图像中每个像素,在其邻域定义一个包含n个随机选择的邻近像素区域。
③ 构建笛卡尔树:
  对于选定的每个邻近像素,收集其RGB强度值,进行笛卡尔树的构造,其每个节点包含子树的最大值。
④ 存储喷雾内容:
  构建好的笛卡尔树被作为存储记忆喷雾的数据结构,用于后续的像素处理。

2.3、更新记忆喷雾 (UpdateMemorySpray)

① 选择新像素:
  当处理新的像素时,算法会从当前像素的局部邻域中选择一个新的邻近像素。
② 更新笛卡尔树:
  新选定的像素强度值被添加到笛卡尔树中,同时,最旧的像素强度值被从树中移除。这种“先进先出”的更新机制确保了记忆喷雾始终反应最新的局部信息。
③ 计算最大值:
  通过笛卡尔树的根节点,可以快速获取当前记忆喷雾中所有像素强度的最大值。

//基于随机内存喷雾Retinex(Random Memory Sprays Retinex)算法对输入的彩色图像进行白平衡处理
void RandomMemorySpraysRetinexPerformWhiteBalance(Mat source, Mat& destination, int N, int n, double upperBound, int rowsStep, int colsStep, double rFactor) {int rows = source.rows;int cols = source.cols;int R = rFactor * sqrt((double)(rows * rows + cols * cols)) + 0.5;Mat normalized;source.convertTo(normalized, CV_64FC3);int outputRows = rows / rowsStep;int outputCols = cols / colsStep;destination = Mat(outputRows, outputCols, CV_64FC3);Vec3d* input = (Vec3d*)normalized.data;Vec3d* inputPoint = input;Vec3d* output = (Vec3d*)destination.data;Vec3d* outputPoint = output;RNG random;CartesianTree<double>** qhs;qhs = new CartesianTree<double>*[N];for (int i = 0; i < N; ++i) {qhs[i] = new CartesianTree<double>[3];}for (int outputRow = 0; outputRow < outputRows; ++outputRow) {for (int outputCol = 0; outputCol < outputCols; ++outputCol) {int row = outputRow * rowsStep;int col = outputCol * colsStep;inputPoint = input + row * cols + col;outputPoint = output + outputRow * outputCols + outputCol;Vec3d& currentPoint = *inputPoint;Vec3d& finalPoint = *outputPoint;finalPoint = Vec3d(0, 0, 0);for (int i = 0; i < N; ++i) {Vec3d max = Vec3d(0, 0, 0);while (qhs[i][0].Size() < n) {double angle = 2 * CV_PI * random.uniform(0.0, 1.0);double r = R * random.uniform(0.0, 1.0);int newRow = row + r * sin(angle);int newCol = col + r * cos(angle);if (newRow >= 0 && newRow < rows && newCol >= 0 && newCol < cols) {Vec3d& newPoint = input[newRow * cols + newCol];for (int k = 0; k < 3; ++k) {qhs[i][k].Push(newPoint[k]);}}}for (int k = 0; k < 3; ++k) {if (max[k] < qhs[i][k].Max()) {max[k] = qhs[i][k].Max();}qhs[i][k].Pop();}for (int k = 0; k < 3; ++k) {if (max[k] == 0) {max[k] = 1;}finalPoint[k] += currentPoint[k] / max[k];}}finalPoint /= N;for (int i = 0; i < 3; ++i) {if (finalPoint[i] > 1) {finalPoint[i] = 1;}}}}for (int i = 0; i < N; ++i) {delete[] qhs[i];}delete[] qhs;double scaleFactor = upperBound;if (rowsStep > 1 || colsStep > 1) {resize(destination, destination, source.size());}destination = destination * scaleFactor - 1;destination.convertTo(destination, source.type());}

2.4、计算颜色校正因子(ComputeColorCorrectionFactor)

  颜色校正因子是基于当前像素亮度值和记忆喷雾的最大强度计算得出。其主要用于调整像素的颜色,以便在不同的光照条件下保持颜色的一致性。

//光照校正算法的实现
void ApplyIllumination(Mat source, Mat illumination, Mat& destination, double upperBound) {vector<Mat> destinationChannels;split(source, destinationChannels);vector<Mat> illuminationChannels;split(illumination, illuminationChannels);for (int i = 0; i < destinationChannels.size(); ++i) {destinationChannels[i].convertTo(destinationChannels[i], CV_64FC1);divide(destinationChannels[i], illuminationChannels[i], destinationChannels[i]);}merge(destinationChannels, destination);double* check = (double*)destination.data;for (int i = 0; i < destination.rows * destination.cols * 3; ++i) {if (check[i] >= upperBound) {check[i] = upperBound - 1;}}destination.convertTo(destination, source.type());}

2.5、应用强度重映射(ApplyIntensityRemapping)

  强度重映射主要用于改善图像亮度调整和颜色校正的方法,特别是在处理高光细节处,以防止过度增强造成细节的丢失。即,在增强图像暗区域的同时,保持亮区域的高光细节,从而获得更为自然的视觉效果。
① 计算初始及LRSR的亮度:
  对于每个像素,首先计算其初始亮度Yi,及LRSR算法处理后的亮度Yo。
② 确定重映射的参数:
  引入重映射参数,用于调整亮度的增加强度。
③ 计算调整后的亮度:
  调整后的亮度是初始亮度Yi和处理后亮度Yo的凸组会。即:Yr = λi * Yi + (1 - λi) * Yo
  其中,λi 是一个介于0和1之间的权重因子,主要基于初始亮度Yi和一个调整参数a来计算。
④ 计算权重因子:
  权重因子λi,即:λi = (Yi / D) / (Yi / D + a)。
  其中,D是颜色通道的最大值(对于8bit颜色通道,D通常是255)。λi的值越大,表示保留的初始亮度越多,处理后亮度的影响越小。
⑤ 过滤处理:
  为了避免亮度增加的剧烈变化,对λi施以一个滤波器(例如使用5*5的均值核)进行平滑处理,得到平滑后的权重因子λ’i。
⑥ 计算最终亮度:
  最终的亮度值,即:OpIci = λ’i * Yo + (1 - λ’i) * Ici。
  其中OpIci是最终的输出亮度,Ici是原始图像中的像素亮度通道强度。

//基于随机内存喷雾Retinex算法对输入的彩色图像进行局部光照估计
void LightRandomMemorySpraysRetinexEstimateLocalIlumination(Mat source, Mat& destination, int N, int n, int inputKernelSize, int illuminantKernelSize, bool normalizeIlluminant = false, int rowsStep = 1, int colsStep = 1, double upperBound = 256.0, double rFactor = 1.0) {Mat retinex;RandomMemorySpraysRetinexPerformWhiteBalance(source, retinex, N, n, upperBound, rowsStep, colsStep, rFactor);Mat inputSource;Mat inputRetinex;source.convertTo(inputSource, CV_64FC3);retinex.convertTo(inputRetinex, CV_64FC3);Mat guidance;inputSource.copyTo(guidance);if (normalizeIlluminant) {Mat illuminant;divide(inputSource, inputRetinex, illuminant);vector<Mat> illuminantChannels;split(illuminant, illuminantChannels);Mat illuminantAverage = (illuminantChannels[0] + illuminantChannels[1] + illuminantChannels[2]) / 3;for (int i = 0; i < 3; ++i) {divide(illuminantChannels[i], illuminantAverage, illuminantChannels[i]);}merge(illuminantChannels, illuminant);inputSource = inputRetinex.mul(illuminant);}if (inputKernelSize > 1) {Mat averaging = Mat::ones(inputKernelSize, inputKernelSize, CV_64FC1) / (double)(inputKernelSize * inputKernelSize);boxFilter(inputSource, inputSource, -1, Size(inputKernelSize, inputKernelSize));boxFilter(inputRetinex, inputRetinex, -1, Size(inputKernelSize, inputKernelSize));}Mat illuminant;divide(inputSource, inputRetinex, illuminant);vector<Mat> illuminantChannels;if (illuminantKernelSize > 1) {Mat averaging = Mat::ones(illuminantKernelSize, illuminantKernelSize, CV_64FC1) / (double)(illuminantKernelSize * illuminantKernelSize);boxFilter(illuminant, illuminant, -1, Size(illuminantKernelSize, illuminantKernelSize));}illuminant.copyTo(destination);}

2.6、应用引导滤波 (ApplyGuidedImageFiltering)

  使用引导滤波来处理重映射后的像素强度,以减少光晕效果并保留图像边缘。
其中,对图像进一步灰度化作为引导图像,进而采用引导滤波进行处理,最后输出目标图像。

//图像引导滤波
//对输入的图像img进行引导滤波,输出结果保存在result中。
void GuidedImageFilterC1(Mat img, Mat guidance, Mat& result, int r, double epsilon) {Mat p;img.convertTo(p, CV_64F);Mat I;guidance.convertTo(I, CV_64F);Mat meanI;boxFilter(I, meanI, -1, Size(r, r));Mat meanP;boxFilter(p, meanP, -1, Size(r, r));Mat corrI;boxFilter(I.mul(I), corrI, -1, Size(r, r));Mat corrIp;boxFilter(I.mul(p), corrIp, -1, Size(r, r));Mat varI = corrI - meanI.mul(meanI);Mat covIp = corrIp - meanI.mul(meanP);Mat a;divide(covIp, varI + epsilon, a);Mat b = meanP - a.mul(meanI);Mat meanA;boxFilter(a, meanA, -1, Size(r, r));Mat meanB;boxFilter(b, meanB, -1, Size(r, r));Mat q = meanA.mul(I) + meanB;q.convertTo(result, img.type());
}//基于引导图像的彩色图像滤波方法
//基于引导图像guidance对输入的彩色图像img进行引导滤波,输出结果保存在result中。
void GuidedImageFilterC3(Mat img, Mat guidance, Mat& result, int r, double epsilon) {vector<Mat> imgChannels;vector<Mat> guidanceChannels;split(img, imgChannels);split(guidance, guidanceChannels);vector<Mat> resultChannels;for (int i = 0; i < imgChannels.size(); ++i) {Mat channelResult;GuidedImageFilterC1(imgChannels[i], guidanceChannels[i], channelResult, r, epsilon);resultChannels.push_back(channelResult);}merge(resultChannels, result);}//基于引导图像和随机内存喷雾Retinex算法的彩色图像局部光照估计方法
void GuidedLightRandomMemorySpraysRetinexEstimateLocalIlumination(Mat source, Mat& destination, int N, int n, int inputKernelSize, int illuminantKernelSize, bool normalizeIlluminant = false, int rowsStep = 1, int colsStep = 1, double upperBound = 256.0, double rFactor = 1.0) {Mat retinex;//白平衡化处理RandomMemorySpraysRetinexPerformWhiteBalance(source, retinex, N, n, upperBound, rowsStep, colsStep, rFactor);Mat inputSource;Mat inputRetinex;source.convertTo(inputSource, CV_64FC3);retinex.convertTo(inputRetinex, CV_64FC3);Mat guidance;inputSource.copyTo(guidance);//归一化处理if (normalizeIlluminant) {Mat illuminant;divide(inputSource, inputRetinex, illuminant);vector<Mat> illuminantChannels;split(illuminant, illuminantChannels);Mat illuminantAverage = (illuminantChannels[0] + illuminantChannels[1] + illuminantChannels[2]) / 3;for (int i = 0; i < 3; ++i) {divide(illuminantChannels[i], illuminantAverage, illuminantChannels[i]);}merge(illuminantChannels, illuminant);inputSource = inputRetinex.mul(illuminant);}double value = 40;double epsilon = value * value;if (inputKernelSize > 1) {//平滑图像GuidedImageFilterC3(inputSource, guidance, inputSource, inputKernelSize, epsilon);GuidedImageFilterC3(inputRetinex, guidance, inputRetinex, inputKernelSize, epsilon);}Mat illuminant;divide(inputSource, inputRetinex, illuminant);vector<Mat> illuminantChannels;if (illuminantKernelSize > 1) {GuidedImageFilterC3(illuminant, guidance, illuminant, illuminantKernelSize, epsilon);}illuminant.copyTo(destination);}

3、Smart Light Random Memory Sprays Retinex效果

在这里插入图片描述

相关文章:

Smart Light Random Memory Sprays Retinex 传统图像增强 SLRMSR

文章目录 前言1、Smart Light Random Memory Sprays Retinex概况2、Smart Light Random Memory Sprays Retinex的实现2.1、SLRMSR算法的伪代码2.2、初始化记忆喷雾&#xff08;CreateInitialMemorySpray&#xff09;2.3、更新记忆喷雾 (UpdateMemorySpray)2.4、计算颜色校正因子…...

Oracle数据库实例概述

Oracle数据库实例是由内存结构&#xff08;SGA和PGA&#xff09;及后台进程这两大部分组成。 内存结构 SGA (System Global Area)&#xff1a;这是数据库实例的共享内存区域&#xff0c;所有与该实例连接的进程都可以访问。SGA包含多个内存结构&#xff0c;例如&#xff1a; 数…...

Odoo17免费开源ERP开发技巧:如何在表单视图中调用JS类

文/Odoo亚太金牌服务开源智造 老杨 在Odoo最新V17新版中&#xff0c;其突出功能之一是能够构建个性化视图&#xff0c;允许用户以独特的方式与数据互动。本文深入探讨了如何使用 JavaScript 类来呈现表单视图来创建自定义视图。通过学习本教程&#xff0c;你将获得关于开发Odo…...

[RCTF2015]EasySQL ---不会编程的崽

今天也是sql注入的新类型---二次注入。不得不说花样真的多哦。 既然真的是sql注入了。那就不测试其他地方了。现在注册进去看一下界面 单纯的回显了名字。源代码里发现user.php。 可以修改密码&#xff1f;二次注入应该就在用户名这里了。因为修改密码时&#xff0c;用户名会被…...

Memcached-分布式内存对象缓存系统

目录 一、NoSQL 介绍 二、Memcached 1、Memcached 介绍 1.1 Memcached 概念 1.2 Memcached 特性 1.3 Memcached 和 Redis 区别 1.4 Memcached 工作机制 1.4.1 内存分配机制 1.4.2 懒惰期 Lazy Expiration 1.4.3 LRU&#xff08;最近最少使用算法&#xff09; 1.4.4…...

bash: sqlplus: command not found 问题解决方法

一、问题描述 在Linux中Oracle安装成功后&#xff0c;首次启动使用时&#xff0c;出现 sqlplus 命令不识别的问题&#xff0c;现象如下&#xff1a; $ sqlplus / as sysdba bash: sqlplus: command not found...二、问题分析 查看环境变量是否正确配置&#xff1a; $ vim .ba…...

大模型-Prompt

一、prompt是什么 在大型语言模型集成中&#xff0c;"prompt" 是指您向模型提供的输入文本或指令&#xff0c;以引导模型生成特定类型的响应。这个 prompt 可以是一个问题、一段描述、一个任务说明&#xff0c;甚至是一部分对话历史记录等。通过设计和优化 prompt&a…...

Python实战:SQLAlchemy ORM使用教程

一、SQLAlchemy ORM使用教程 SQLAlchemy是一个流行的Python SQL工具包和对象关系映射&#xff08;ORM&#xff09;框架&#xff0c;它为开发人员提供了一种高效、灵活的方式来与数据库进行交互。在本篇博客中&#xff0c;我们将深入探讨SQLAlchemy ORM的核心知识&#xff0c;并…...

能不能绕过c去学c++?

目前做工程开发&#xff0c;基本都是c/c混着用的&#xff0c;c/c是同源的&#xff0c;c/是在c的基础上发展起来的&#xff0c;它们之间有些联系和区别&#xff1a; 区别&#xff1a; 1.可用库不同 c基本是系统底层语言&#xff0c;一般系统底层开发用c&#xff08;例如&…...

Python 小爬虫:爬取 bing 每日壁纸设为桌面壁纸

请求 URLJSON 版示例代码代码片段注意点headers 中的 User-Agent响应头中的 Content-Type终端通过代理API从 bing.com 找Bing 每日壁纸设置为桌面壁纸代码设定计划任务自动执行 python 脚本请求 URL 通过模仿必应(Bing)自己的 AJAX 调用方式获得请求 URL。 JSON 格式:...

利用textarea和white-space实现最简单的文章编辑器 支持缩进和换行

当你遇到一个非常基础的文章发布和展示的需求&#xff0c;只需要保留换行和空格缩进&#xff0c;你是否会犹豫要使用富文本编辑器&#xff1f;实际上这个用原生的标签两步就能搞定&#xff01; 1.直接用textarea当编辑器 textarea本身就可以保存空格和换行符&#xff0c;示例如…...

总结mac下解决matplotlib中文显示问题的几种方法

一、前言&#xff1a; 使⽤matplotlib画图时&#xff0c;由于matplotlib默认没有中⽂&#xff0c;显⽰中文时会出现空⽩⼩⽅块。 二、方法&#xff1a; 2.1 matplotlib中使用SimHei字体 1&#xff09;进入终端后查看matplotlib的字体路径&#xff1a; $ python >>&g…...

探索区块链世界:从加密货币到去中心化应用

相信提到区块链&#xff0c;很多人会想到比特币这样的加密货币&#xff0c;但实际上&#xff0c;区块链技术远不止于此&#xff0c;它正在深刻地改变我们的生活和商业。 首先&#xff0c;让我们来简单了解一下什么是区块链。区块链是一种分布式数据库技术&#xff0c;它通过将…...

GitLab/Github从头开始配置秘钥

1、下载git安装包 CNPM Binaries Mirrorhttps://registry.npmmirror.com/binary.html?pathgit-for-windows/ 拉到页面最底部选择 点进文件夹下载32位或者64位的版本&#xff0c;我的是64位就选择64的版本进行安装 2、傻瓜式安装 3、在相应的文件夹右键选择 UserName为你的用…...

uni.getlocation h5获取定位失败后,阻塞问题

uni.getlocation 在H5中&#xff0c;如果用户未开gps定位或者gps定位信号较差时&#xff0c;定位会失败。这种情况uni.getlocation也不会出现报错&#xff0c;也不会有后续执行&#xff0c;导致代码阻塞&#xff0c;体验极差。 解决方案1&#xff1a;拿不到定位或者定位失败这个…...

Flutter 运行 flutter doctor 命令长时间未响应

由于 Flutter 运行 flutter doctor 命令&#xff0c;会从 pub(https://pub.dev/ 类似于 Node.js 的 npm) 上进行资源的下载&#xff0c;如果没有配置国内镜像&#xff0c;可能会由于其服务器在国外导致资源下载慢或者下载不下来&#xff0c;所以出现了运行 flutter doctor 命令…...

【数据挖掘】练习2:数据管理2

课后作业2&#xff1a;数据管理2 一&#xff1a;上机实验2 # 编写函数stat&#xff0c;要求该函数同时计算均值&#xff0c;最大值&#xff0c;最小值&#xff0c;标准差&#xff0c;峰度和偏度。 install.packages("timeDate") library(timeDate) stat <- func…...

【iOS】——Blocks

文章目录 前言一、Blocks概要1.什么是Blocks 二、Block模式1.block语法2.block类型变量3.截获自动变量值4._Block修饰符5.截获的自动变量 三、Blocks的实现1.Block的实质2.截获自动变量值3._Block说明符4.Block存储域 前言 一、Blocks概要 1.什么是Blocks Blocks是C语言的扩…...

体验OceanBase OBD V2.5.0 组件内扩容和组件变更

背景 OBD 是OceanBase的命令行部署工具&#xff0c;在 obd V2.5.0 版本之前&#xff0c;其主要功能主要是部署各类组件&#xff0c;例如 oceanbase-ce,obproxy-ce,obagent 等。然而&#xff0c;它并不支持组件的变更操作以及组件内部的扩缩容调整。具体来说&#xff1a; 1、若…...

关于前端的学习

目录 前言: 1.初识HTML: 1.1超文本: 1.2标记语言: 2.关于html的基本框架: 3.HTML基本文字标签: 3.1.h标题标签: 3.3 文本内容: 3.4换行的和分割的: 3.5 特殊文字标签: 3.5.1表面上看着三对的结果呈现都是一样的: 3.5.2但是其背后的效果其实是不一样的: 3.6转义字符:…...

浅谈 React Hooks

React Hooks 是 React 16.8 引入的一组 API&#xff0c;用于在函数组件中使用 state 和其他 React 特性&#xff08;例如生命周期方法、context 等&#xff09;。Hooks 通过简洁的函数接口&#xff0c;解决了状态与 UI 的高度解耦&#xff0c;通过函数式编程范式实现更灵活 Rea…...

ssc377d修改flash分区大小

1、flash的分区默认分配16M、 / # df -h Filesystem Size Used Available Use% Mounted on /dev/root 1.9M 1.9M 0 100% / /dev/mtdblock4 3.0M...

DBAPI如何优雅的获取单条数据

API如何优雅的获取单条数据 案例一 对于查询类API&#xff0c;查询的是单条数据&#xff0c;比如根据主键ID查询用户信息&#xff0c;sql如下&#xff1a; select id, name, age from user where id #{id}API默认返回的数据格式是多条的&#xff0c;如下&#xff1a; {&qu…...

WEB3全栈开发——面试专业技能点P2智能合约开发(Solidity)

一、Solidity合约开发 下面是 Solidity 合约开发 的概念、代码示例及讲解&#xff0c;适合用作学习或写简历项目背景说明。 &#x1f9e0; 一、概念简介&#xff1a;Solidity 合约开发 Solidity 是一种专门为 以太坊&#xff08;Ethereum&#xff09;平台编写智能合约的高级编…...

涂鸦T5AI手搓语音、emoji、otto机器人从入门到实战

“&#x1f916;手搓TuyaAI语音指令 &#x1f60d;秒变表情包大师&#xff0c;让萌系Otto机器人&#x1f525;玩出智能新花样&#xff01;开整&#xff01;” &#x1f916; Otto机器人 → 直接点明主体 手搓TuyaAI语音 → 强调 自主编程/自定义 语音控制&#xff08;TuyaAI…...

排序算法总结(C++)

目录 一、稳定性二、排序算法选择、冒泡、插入排序归并排序随机快速排序堆排序基数排序计数排序 三、总结 一、稳定性 排序算法的稳定性是指&#xff1a;同样大小的样本 **&#xff08;同样大小的数据&#xff09;**在排序之后不会改变原始的相对次序。 稳定性对基础类型对象…...

LangChain知识库管理后端接口:数据库操作详解—— 构建本地知识库系统的基础《二》

这段 Python 代码是一个完整的 知识库数据库操作模块&#xff0c;用于对本地知识库系统中的知识库进行增删改查&#xff08;CRUD&#xff09;操作。它基于 SQLAlchemy ORM 框架 和一个自定义的装饰器 with_session 实现数据库会话管理。 &#x1f4d8; 一、整体功能概述 该模块…...

关于uniapp展示PDF的解决方案

在 UniApp 的 H5 环境中使用 pdf-vue3 组件可以实现完整的 PDF 预览功能。以下是详细实现步骤和注意事项&#xff1a; 一、安装依赖 安装 pdf-vue3 和 PDF.js 核心库&#xff1a; npm install pdf-vue3 pdfjs-dist二、基本使用示例 <template><view class"con…...

从物理机到云原生:全面解析计算虚拟化技术的演进与应用

前言&#xff1a;我的虚拟化技术探索之旅 我最早接触"虚拟机"的概念是从Java开始的——JVM&#xff08;Java Virtual Machine&#xff09;让"一次编写&#xff0c;到处运行"成为可能。这个软件层面的虚拟化让我着迷&#xff0c;但直到后来接触VMware和Doc…...

WebRTC调研

WebRTC是什么&#xff0c;为什么&#xff0c;如何使用 WebRTC有什么优势 WebRTC Architecture Amazon KVS WebRTC 其它厂商WebRTC 海康门禁WebRTC 海康门禁其他界面整理 威视通WebRTC 局域网 Google浏览器 Microsoft Edge 公网 RTSP RTMP NVR ONVIF SIP SRT WebRTC协…...