16bit转8bit的常见方法(图像归一化)
文章目录
- 16-bit转8-bit的常用方法
- 一、数据类型转换:image.astype(np.uint8) —— 若数值 x 超出 0-255 范围,则取模运算。如:x = 600 % 256 = 88
- 二、截断函数:np.clip().astype(np.uint8) —— 若数值 x 超出 0-255 范围,则>255=255,<0=0。如:x = 600 => 255
- 三、线性缩放
- (1)固定比例(×) —— 适用于像素值均匀分布的高动态范围图像,对高对比度图像不够灵活,损失信息。
- (2)动态比例(√) —— 适用于对比度较低的图像,能提升细节。
- 四、图像归一化:[0,1 或 [0,255]
- (1)手动归一化(√)
- (2)OpenCV归一化:cv2.normalize()
- (3)百分比缩放:np.percentile()(√)
- 五、Fiji - Auto - B&C:min + max
将16-bit图像转换为8-bit图像是图像处理中的常见操作,目的是将原图像的像素值压缩至0-255范围。这种转换有助于减少存储空间、适应常见显示设备,并压缩动态范围。虽然16-bit图像能提供更丰富的细节和灰度级别,但其占用的内存和存储空间较大。通过转换为8-bit图像,可以有效降低数据量,满足日常应用需求,同时保持足够的视觉效果。
- 数据位数(bit) —— 描述了可以用多少个二进制位来表示一个数值。
- 16位:范围[0,216-1],即
[0,65535]
- 8位: 范围[0,28-1],即
[0,255]
- 图像概念:
- 16-bit 图像:每个像素的值由 16位 二进制数表示,范围为 [0, 65535]。这种高位深的图像可以表示更多的灰度级别,适用于医学影像、遥感图像等需要高动态范围和精细色彩细节的应用。
- 8-bit 图像:每个像素的值由 8位 二进制数表示,范围为 [0, 255]。8位图像的动态范围较小,但在许多普通的显示设备和图像处理应用中已经足够。8位图像广泛用于一般的灰度图像、彩色图像等。
- 图像转换:由于 8-bit 图像 的像素范围(0-255)比 16-bit 图像 的像素范围(0-65535)要小得多,因此,16-bit 图像转换为 8-bit 图像时需要做 缩放 或 归一化 操作,将其像素值映射到适当的范围。
16-bit转8-bit的常用方法
"""
输入图像:
[a, b]
[c, d]扩展后的图像:
[a, 0, b, 0]
[0, 0, 0, 0]
[c, 0, d, 0]
[0, 0, 0, 0]卷积核(3x3):
[w, x, y]
[z, p, q]
[r, s, t]
"""
import numpy as np
import cv2def normalize(x, pmin=2, pmax=99.8, axis=None, clip=True, eps=1e-20, dtype=np.float32):"""Percentile-based image normalization."""mi = np.percentile(x, pmin, axis=axis, keepdims=True)ma = np.percentile(x, pmax, axis=axis, keepdims=True)return normalize_mi_ma(x, mi, ma, clip=clip, eps=eps, dtype=dtype)def normalize_mi_ma(x, mi, ma, clip=False, eps=1e-20, dtype=np.float32):if dtype is not None:x = x.astype(dtype, copy=False)mi = dtype(mi) if np.isscalar(mi) else mi.astype(dtype, copy=False)ma = dtype(ma) if np.isscalar(ma) else ma.astype(dtype, copy=False)eps = dtype(eps)try:import numexprx = numexpr.evaluate("(x - mi) / ( ma - mi + eps )")except ImportError:x = (x - mi) / (ma - mi + eps)if clip:x = np.clip(x, 0, 1)return x###############################################################################################
import tifffile
image_16bit = tifffile.imread(r"561result-1-part-1.tif")
image_16bit = image_16bit[0:100, 0:100]# image_16bit = np.array([[260, 50, 600], [400, 500, 300]], dtype=np.uint16)
###############################################################################################
"""(1)数据类型转换(强转)"""
image_8bit_astype = image_16bit.astype(np.uint8)"""(2)截断函数"""
image_8bit_clip = np.clip(image_16bit, 0, 255).astype(np.uint8)
###############################################################################################
min_value = np.min(image_16bit) # 获取图像的最小值
max_value = np.max(image_16bit) # 获取图像的最大值"""(3.1)线性缩放-(固定)比例"""
scale_factor = 255.0 / 65535.0 # (固定)缩放比例
image_8bit_scaled_G = (image_16bit * scale_factor).astype(np.uint8)"""(3.2)线性缩放-(动态)比例"""
if max_value != min_value:scale = 255.0 / (max_value - min_value) # (动态)缩放比例
else:scale = 1 # 或者其他特殊处理
image_8bit_scaled_D = np.clip(image_16bit * scale + 0.5, 0, 255).astype(np.uint8)
###############################################################################################
"""(4.1)手动归一化"""
image_8bit_manual = ((image_16bit - min_value) / (max_value - min_value) * 255).astype(np.uint8)"""(4.2)cv2.normalize归一化"""
image_8bit_cv2 = cv2.normalize(image_16bit, None, 0, 255, cv2.NORM_MINMAX).astype(np.uint8)"""(4.3)percentile归一化函数"""
data_nor = normalize(image_16bit, pmin=2, pmax=99.8, clip=True, dtype=np.float32)
image_8bit_percentile = np.clip(data_nor * 255, 0, 255).astype(np.uint8)print("image_16bit:", image_16bit) # [[260 50 600] [400 500 300]]
print("image_8bit_astype:", image_8bit_astype) # [[ 4 50 88] [144 244 44]]
print("image_8bit_clip:", image_8bit_clip) # [[255 50 255] [255 255 255]]
print("image_8bit_scaled_G:", image_8bit_scaled_G) # [[1 0 2] [1 1 1]]
print("image_8bit_scaled_D:", image_8bit_scaled_D) # [[121 23 255] [185 232 139]]
print("image_8bit_manual:", image_8bit_manual) # [[ 97 0 255] [162 208 115]]
print("image_8bit_cv2:", image_8bit_cv2) # [[ 97 0 255] [162 209 116]]
print("image_8bit_percentile:", image_8bit_percentile) # [[0.35795453 0. 1. ] [0.62310606 0.8125 0.43371212]]import matplotlib.pyplot as plt
plt.figure(figsize=(10, 10))
plt.subplot(2, 4, 1), plt.imshow(image_16bit, cmap="gray"), plt.title("image_16bit"), plt.axis("off")
plt.subplot(2, 4, 2), plt.imshow(image_8bit_astype, cmap="gray"), plt.title("image_8bit_astype"), plt.axis("off")
plt.subplot(2, 4, 3), plt.imshow(image_8bit_clip, cmap="gray"), plt.title("image_8bit_clip"), plt.axis("off")
plt.subplot(2, 4, 4), plt.imshow(image_8bit_scaled_G, cmap="gray"), plt.title("image_8bit_scaled_G"), plt.axis("off")
plt.subplot(2, 4, 5), plt.imshow(image_8bit_scaled_D, cmap="gray"), plt.title("image_8bit_scaled_D"), plt.axis("off")
plt.subplot(2, 4, 6), plt.imshow(image_8bit_manual, cmap="gray"), plt.title("image_8bit_manual"), plt.axis("off")
plt.subplot(2, 4, 7), plt.imshow(image_8bit_cv2, cmap="gray"), plt.title("image_8bit_cv2"), plt.axis("off")
plt.subplot(2, 4, 8), plt.imshow(image_8bit_percentile, cmap="gray"), plt.title("image_8bit_percentile"), plt.axis("off")
plt.show()# import napari
# viewer = napari.Viewer() # 创建napari视图
# viewer.add_image(image_16bit, name="image_16bit")
# viewer.add_image(image_8bit_astype, name="image_8bit_astype")
# viewer.add_image(image_8bit_clip, name="image_8bit_clip")
# viewer.add_image(image_8bit_scaled_G, name="image_8bit_scaled_G")
# viewer.add_image(image_8bit_scaled_D, name="image_8bit_scaled_D")
# viewer.add_image(image_8bit_manual, name="image_8bit_manual")
# viewer.add_image(image_8bit_cv2, name="image_8bit_cv2")
# viewer.grid.enabled = not viewer.grid.enabled # 切换到网格模式
# napari.run() # 启动 napari 事件循环,使得窗口保持打开并可交互。
一、数据类型转换:image.astype(np.uint8) —— 若数值 x 超出 0-255 范围,则取模运算。如:x = 600 % 256 = 88
import numpy as npimage_16bit = np.array([[260, 50, 600], [400, 500, 300]], dtype=np.uint16)
image_8bit = image_16bit.astype(np.uint8)
print("image_8bit:", image_8bit) # [[ 4 50 88] [144 244 44]]
二、截断函数:np.clip().astype(np.uint8) —— 若数值 x 超出 0-255 范围,则>255=255,<0=0。如:x = 600 => 255
import numpy as npimage_16bit = np.array([[260, 50, 600], [400, 500, 300]], dtype=np.uint16)
image_8bit = np.clip(image_16bit, 0, 255).astype(np.uint8)
print("image_8bit:", image_8bit) # [[255 50 255] [255 255 255]]
三、线性缩放
(1)固定比例(×) —— 适用于像素值均匀分布的高动态范围图像,对高对比度图像不够灵活,损失信息。
import numpy as npimage_16bit = np.array([[260, 50, 600], [400, 500, 300]]).astype(np.uint16)
scale_factor = 255.0 / 65535.0 # (固定)缩放比例
image_8bit = (image_16bit * scale_factor * 255).astype(np.uint8)
print("image_8bit:", image_8bit) # [[ 1 49 83] [140 240 41]]
(2)动态比例(√) —— 适用于对比度较低的图像,能提升细节。
import numpy as npimage_16bit = np.array([[260, 50, 600], [400, 500, 300]]).astype(np.uint16)
scale_factor = 255.0 / (np.max(image_16bit) - np.min(image_16bit)) # (动态)缩放比例
image_8bit = np.clip(image_16bit * scale_factor + 0.5, 0, 255).astype(np.uint8)
print("image_8bit:", image_8bit) # [[121 23 255] [185 232 139]]
四、图像归一化:[0,1 或 [0,255]
(1)手动归一化(√)
import numpy as npimage_16bit = np.array([[260, 50, 600], [400, 500, 300]]).astype(np.uint16)
image_8bit = np.clip((image_16bit - np.min(image_16bit)) / (np.max(image_16bit) - np.min(image_16bit)) * 255, 0, 255).astype(np.uint8)
print("image_8bit:", image_8bit) # [[ 97 0 255] [162 209 116]]
(2)OpenCV归一化:cv2.normalize()
import numpy as np
import cv2image_16bit = np.array([[260, 50, 600], [400, 500, 300]]).astype(np.uint16)
image_8bit = cv2.normalize(image_16bit, None, 0, 255, cv2.NORM_MINMAX).astype(np.uint8)
print("image_8bit:", image_8bit) # [[ 97 0 255] [162 209 116]]
(3)百分比缩放:np.percentile()(√)
百分比缩放(Percentile Stretching):通过选择图像的百分比值,通常选择图像中的前 99% 或 95% 像素值作为实际的范围,然后将这些值线性映射到0-255范围。这种方法可以避免因极端像素值(如噪声或过曝光区域)影响结果。
import numpy as npdef normalize(x, pmin=2, pmax=99.8, axis=None, clip=True, eps=1e-20, dtype=np.float32):"""Percentile-based image normalization."""mi = np.percentile(x, pmin, axis=axis, keepdims=True)ma = np.percentile(x, pmax, axis=axis, keepdims=True)return normalize_mi_ma(x, mi, ma, clip=clip, eps=eps, dtype=dtype)def normalize_mi_ma(x, mi, ma, clip=False, eps=1e-20, dtype=np.float32):if dtype is not None:x = x.astype(dtype, copy=False)mi = dtype(mi) if np.isscalar(mi) else mi.astype(dtype, copy=False)ma = dtype(ma) if np.isscalar(ma) else ma.astype(dtype, copy=False)eps = dtype(eps)try:import numexprx = numexpr.evaluate("(x - mi) / ( ma - mi + eps )")except ImportError:x = (x - mi) / (ma - mi + eps)if clip:x = np.clip(x, 0, 1)return xif __name__ == '__main__':data = np.array([[260, 50, 600], [400, 500, 300]]).astype(np.uint16)data_nor = normalize(data, pmin=2, pmax=99.8, clip=True, dtype=np.float32)data_nor8bit = np.clip(data_nor * 255, 0, 255).astype(np.uint8)print(data_nor) # [[0.35795453 0. 1. ] [0.62310606 0.8125 0.43371212]] print(data_nor8bit) # [[ 91 0 255] [158 207 110]]
五、Fiji - Auto - B&C:min + max
(1)提取 TIFF 图像页的元数据标签:min + max
(2)Fiji - JAVA:ImageProcessor convertToByteProcessor()
(3)Fiji - Auto - B&C(对比度函数)
import numpy as np
import tifffiledef auto(data, num_bins=256, times=1):"""函数功能: Fiji - Brightness/Contrast输入参数: data ———— 2D or 3D图像num_bins ———— bin数量times ———— auto次数备注:若为3D图像,需要提取具有一定意义的帧图像为参考帧。"""print(f"Fiji - Brightness/Contrast - Auto(times={times}).")if data.ndim == 3:# 在3D图像中(背景为黑,前景为白),计算每一帧图像的像素值总和,并以sum最大为参考帧。effective_frame = []for index, frame in enumerate(data):effective_frame.append(np.sum(frame))# # (部分)全黑的帧图像会出现(部分)像素值>0,但远小于50。# if frame.max() > 50:# data = frame# breakframe_max_value = max(effective_frame)frame_max_index = effective_frame.index(frame_max_value)data = data[frame_max_index]print(f"frame_max_index={frame_max_index}")limit = data.size / 10auto_threshold = 0min_value, max_value = 0, 0for i in range(times):if auto_threshold < 10:auto_threshold = 5000else:auto_threshold /= 2data_min, data_max = data.min(), data.max()threshold = data.size / auto_thresholdhist, bins = np.histogram(data, bins=num_bins)hist[hist > limit] = 0bin_size = (data_max - data_min) / num_binsx = np.where(hist > threshold)[0]if len(x) <= 1:return data_min, data_maxmin_bin, max_bin = x[0], x[-1]min_value = data_min + min_bin * bin_sizemax_value = data_min + max_bin * bin_sizereturn min_value, max_valuedef convert_short_to_byte(pixels16, min_val, max_val, do_scaling=True):"""(复现函数)BIRDS-JAVA: ImageProcessor convertToByteProcessor() """# 使用掩码0xffff来提取16位像素值的低16位(低16位的像素值保留,高于16位的部分置0)。0xffff是一个16位的二进制数,所有位均为1。# pixels8 = (pixels16 & 0xffff).astype(np.int16) # 执行按位与操作。# pixels8_min_before, pixels8_min_before = np.min(pixels8), np.max(pixels8)if do_scaling:"""任务:image = image - value已知:image为uint16数组, value为正数且大于image的最小值(min_image)输出:最小值的结果(整数溢出)=(65535 + min_image) - value"""pixels_result = np.where(pixels16 >= min_val, pixels16 - min_val, 0).astype(np.uint16) # 对于每个像素值,若像素值大于等于min_val,则减去min_val,否则置为0。scale = 256.0 / (max_val - min_val + 1) # 计算缩放比例pixels8 = np.clip(pixels_result * scale + 0.5, 0, 255).astype(np.uint8) # 截断函数 + 数据类型转换else:pixels8 = np.clip(pixels16, 0, 255).astype(np.uint8) # 使用NumPy的矢量化操作,避免循环return pixels8def tiff_pages_tags_min_max(tiff_path):""""提取 TIFF 图像页的元数据标签:min + max"""import reTIFF = tifffile.TiffFile(tiff_path) # 打开 TIFF 文件tiff_pages_tags = TIFF.pages[0].tags # 获取第一页的元数据标签min_value, max_value = 0, 0# 检查是否存在 ImageDescription 标签if 'ImageDescription' in tiff_pages_tags:image_description_tag = tiff_pages_tags['ImageDescription']image_description = image_description_tag.value# 使用正则表达式匹配 min 和 max 属性的值,直接匹配 µ 字符match = re.search(r'min\s*=\s*([0-9.]+)\s*max\s*=\s*([0-9.]+)', image_description)if match:min_value = round(float(match.group(1)))max_value = round(float(match.group(2)))if min_value == max_value: # 属性存在但未赋值: min=0.0 + max=0.0stack_image = tifffile.imread(tiff_path)min_value, max_value = auto(stack_image)min_value = round(min_value)max_value = round(max_value)print(f"image: min_gray_value={min_value}, max_gray_value={max_value}")else:print(f"No match found in image_description: {image_description}")stack_image = tifffile.imread(tiff_path)min_value, max_value = auto(stack_image)min_value = round(min_value)max_value = round(max_value)print(f"image: min_gray_value={min_value}, max_gray_value={max_value}")return min_value, max_valueif __name__ == "__main__":# (1)生成1000个介于0到65535之间的随机整数image_16bit = np.random.randint(0, 65536, 1000).reshape(10, 10, 10).astype(np.uint16)save_path = "image.tif"tifffile.imwrite(save_path, image_16bit) # 保存图像为TIFF# (2)提取 TIFF 图像页的元数据标签:min + maxtag_min_value, tag_max_value = tiff_pages_tags_min_max(save_path)print(f"min ={tag_min_value}, max ={tag_max_value}")# (3)16bit转8bitload_image = tifffile.imread(save_path) # 加载图像数据image_8bit = convert_short_to_byte(load_image, tag_min_value, tag_max_value, do_scaling=True)print(f"16位图像 ={image_16bit.shape}, min ={np.min(image_16bit)}, max ={np.max(image_16bit)}")print(f" 8位图像 ={image_8bit.shape}, min ={np.min(image_8bit)}, max ={np.max(image_8bit)}")# (4)可视化import napariviewer = napari.Viewer() # 创建napari视图viewer.add_image(image_16bit, name="image_16bit", colormap='gray') # 添加图像(指定红色)viewer.add_image(image_8bit, name="image_8bit", colormap='gray') # 添加图像(指定红色)viewer.dims.ndisplay = 3 # 切换到n维显示模式viewer.grid.enabled = not viewer.grid.enabled # 切换网格模式napari.run() # 显示napari图形界面
"""
No match found in image_description: {"shape": [10, 10, 10]}
min =650, max =6479516位图像 =(10, 10, 10), min =8, max =655198位图像 =(10, 10, 10), min =0, max =255
"""
相关文章:
16bit转8bit的常见方法(图像归一化)
文章目录 16-bit转8-bit的常用方法一、数据类型转换:image.astype(np.uint8) —— 若数值 x 超出 0-255 范围,则取模运算。如:x 600 % 256 88二、截断函数:np.clip().astype(np.uint8) —— 若数值 x 超出 0-255 范围࿰…...
消息中间件kafka,rabbitMQ
在分布式系统中,消息中间件是实现不同组件之间异步通信的关键技术。Kafka 和 RabbitMQ 是两个非常流行的消息中间件系统,它们各自有着不同的特点和应用场景。下面将分别介绍 Kafka 和 RabbitMQ,并讨论它们在消息队列中的使用。 一、Kafka (Apache Kafka) 主要特点: 高吞吐…...
C语言编译预处理3
条件编译:是对源程序的一部分指定编译条件,满足条件进行编译否则不编译。 形式1 #indef 标识符 程序段1 #else 程序段2 #endif 标识符已经被定义用#ifdef #include <stdio.h>// 可以通过注释或取消注释下面这行来控制是否定义 DEBUG 宏 // …...
数据结构·树
树的特点 最小连通图 无环 有且只有 n − 1 n-1 n−1 条边 树的建立方式 顺序存储 只适用于满n叉树,完全n叉树 1<<n 表示结点 2 n 2^n 2nP4715 【深基16.例1】淘汰赛 void solve() {cin >> n;for (int i 0; i<(1<<n); i) {cin >&g…...
队列的各种操作实现(数据结构C语言多文件编写)
1.先创建queue.h声明文件(Linux命令:touch queue.h)。编写函数声明如下(打开文件 Linux 操作命令:vim queue.h): //头文件 #ifndef __QUEUE_H__ #define __QUEUE_H__ //队列 typedef struct queue{int* arr;int in;int out;int cap;int size; }queue_t;…...
48V/2kW储能电源纯正弦波逆变器详细设计方案-可量产
48V/2kW储能电源纯正弦波逆变器详细设计方案 1.后级驱动电路图 2.前级驱动电路图 3.功率表电路原理图 4.功率板BOM: 5.后级驱动BOM 6.前级驱动BOM...
[redis进阶二]分布式系统之主从复制结构(2)
目录 一 redis的拓扑结构 (1)什么是拓扑 (2)⼀主⼀从结构 (3)⼀主多从结构 (4)树形主从结构 (5)三种拓扑结构的优缺点,以及适用场景 二 redis的复制原理 (1)复制过程 (2)数据同步psync replicationid/replid (复制id)(标注同步的数据来自哪里:数据来源) offset (偏移…...
Playwright多语言生态:跨Python_Java_.NET的统一采集方案
一、问题背景:爬虫多语言割裂的旧时代 在大规模数据采集中,尤其是学术数据库如 Scopus,开发者常遇到两个经典问题: 技术语言割裂:Python开发人员使用Selenium、requests-html等库;Java阵营使用Jsoup或Htm…...
day30 第八章 贪心算法 part04
452. 用最少数量的箭引爆气球 先排序,再算重叠区间 class Solution:def findMinArrowShots(self, points: List[List[int]]) -> int:if len(points)0:return 0points.sort(keylambda x:x[0])result 1for i in range(1, len(points)):if points[i][0] > point…...
java操作redis库,开箱即用
application.yml spring:application:name: demo#Redis相关配置redis:data:# 地址host: localhost# 端口,默认为6379port: 6379# 数据库索引database: 0# 密码password:# 连接超时时间timeout: 10slettuce:pool:# 连接池中的最小空闲连接min-idle: 0# 连接池中的最…...
clickhouse中的窗口函数
窗口函数 边界核心参数 窗口边界通过 ROWS、RANGE 或 GROUPS 模式定义,语法为: ROWS BETWEEN AND 基于 物理行位置 定义窗口,与排序键的实际值无关,适用于精确控制窗口行数 – 或 RANGE BETWEEN AND 基于 排序键的数值范围 定义窗口,适用于时间序列或连续数值的场景(…...
YZ系列工具之YZ02:字典的多功能应用
我给VBA下的定义:VBA是个人小型自动化处理的有效工具。利用好了,可以大大提高自己的工作效率,而且可以提高数据的准确度。我的教程一共九套一部VBA手册,教程分为初级、中级、高级三大部分。是对VBA的系统讲解,从简单的…...
金山科技在第91届中国国际医疗器械博览会CMEF 首发新品 展现智慧装备+AI
4月8日—11日,国家会展中心(上海),第91届中国国际医疗器械(春季)博览会(以下简称“CMEF 2025”)举办。金山科技在盛会上隆重推出年度新品——全高清电子内镜光学放大镜与肛肠测压系统…...
STM32 BOOT设置,bootloader,死锁使用方法
目录 BOOT0 BOOT1的配置含义 bootloader使用方法 芯片死锁解决方法开发调试过程中,由于某种原因导致内部Flash锁死,无法连接SWD以及JTAG调试,无法读到设备,可以通过修改BOOT模式重新刷写代码。修改为BOOT01,BOOT10…...
机器学习:让数据开口说话的科技魔法
在人工智能飞速发展的今天,「机器学习」已成为推动数字化转型的核心引擎。无论是手机的人脸解锁、网购平台的推荐系统,还是自动驾驶汽车的决策能力,背后都离不开机器学习的技术支撑。那么,机器学习究竟是什么?它又有哪…...
PDF解析示例代码学习
以下是结合多种技术实现的PDF解析详细示例(Python实现),涵盖文本、表格和扫描件处理场景: 一、环境准备与依赖安装 # 核心依赖库 pip install pdfplumber tabula-py pytesseract opencv-python mysql-connector-python 二、完整…...
【云平台监控】安装应用Ansible服务
安装应用Ansible服务 文章目录 安装应用Ansible服务资源列表基础环境一、安装Ansible1.1、部署Ansible1.2、配置主机清单1.2.1、方法11.2.2、方法2 二、Ansible命令应用基础2.1、ping模块2.2、command模块2.3、user模块2.4、group模块2.5、cron模块2.6、copy模块2.7、file模块2…...
项目执行中的目标管理:从战略到落地的闭环实践
——如何让目标不“跑偏”、团队不“掉队”? 引言:为什么目标管理决定项目成败? 根据PMI研究,47%的项目失败源于目标模糊或频繁变更。在复杂多变的项目环境中,目标管理不仅是制定KPI,更是构建“方向感-执行…...
如何优雅地处理 API 版本控制?
API 会不断发展,而用户的需求也会随之变化。那么,如何确保你的 API 在升级时不会影响现有用户?答案就是:API 版本控制。就像你更新了一个应用程序,引入了新功能,但旧功能仍然保留,让老用户继续愉…...
如何通过Radius认证服务器实现虚拟云桌面安全登录认证:安当ASP身份认证系统解决方案
引言:虚拟化时代的安全挑战 随着云计算和远程办公的普及,虚拟云桌面(如VMware Horizon、Citrix)已成为企业数字化办公的核心基础设施。然而,传统的用户名密码认证方式暴露了诸多安全隐患:弱密码易被暴力破…...
自然语言处理spaCy
spaCy 是一个流行的开源 自然语言处理(NLP) 库,专注于 高效、易用和工业化应用。它由 Explosion AI 开发,广泛应用于文本处理、信息提取、机器翻译等领域。 zh_core_web_sm 是 spaCy 提供的一个小型中文预训练语言模型࿰…...
大语言模型(LLMs)中的强化学习(Reinforcement Learning, RL)
第一部分:强化学习基础回顾 在深入探讨LLMs中的强化学习之前,我们先快速回顾一下强化学习的核心概念,确保基础扎实。 1. 强化学习是什么? 强化学习是一种机器学习范式,目标是让智能体(Agent)…...
数字后端实现Innovus DRC Violation之如何利用脚本批量解决G4:M7i DRC Violation
大家在跑完物理验证calibre DRC之后,会发现DRC里面存在一种G4:M7i的DRC违例,这种违例一般都是出现在memory的边界。今天教大家如何利用脚本来批量处理这一类DRC问题的解决。 首先,我们需要把calibre的DRC结果读取到innovus里面来,…...
Java版企业电子招标采购系统源业码Spring Cloud + Spring Boot +二次开发+ MybatisPlus + Redis
功能描述 1、门户管理:所有用户可在门户页面查看所有的公告信息及相关的通知信息。主要板块包含:招标公告、非招标公告、系统通知、政策法规。 2、立项管理:企业用户可对需要采购的项目进行立项申请,并提交审批,查看所…...
CTF web入门之文件上传
知识点 产生文件上传漏洞的原因 原因: 对于上传文件的后缀名(扩展名)没有做较为严格的限制 对于上传文件的MIMETYPE(用于描述文件的类型的一种表述方法) 没有做检查 权限上没有对于上传的文件目录设置不可执行权限,(尤其是对于shebang类型的文件) 对于web server对于上传…...
ArmSoM Sige5 CM5:RK3576 上 Ultralytics YOLOv11 边缘计算新标杆
在计算机视觉技术加速落地的今天,ArmSoM 正式宣布其基于 Rockchip RK3576 的旗舰产品 Sige5 开发板 和 CM5 核心板 全面支持 Ultralytics YOLOv11 模型的 RKNN 部署。这一突破标志着边缘计算领域迎来新一代高性能、低功耗的 AI 解决方案&am…...
游戏引擎学习第224天
回顾游戏运行并指出一个明显的图像问题。 回顾一下之前那个算法 我们今天要做一点预加载的处理。上周刚完成了游戏序章部分的所有剪辑内容。在运行这一部分时,如果观察得足够仔细,就会注意到一个问题。虽然因为视频流压缩质量较低,很难清楚…...
PN1-S25系列ProfiNet网关模组产品方案
PN1-S25系列ProfiNet网关模组是一款专为工业通信环境设计的先进设备,旨在实现ProfiNet与Modbus RTU协议之间的无缝转换,从而优化工业自动化系统中的数据传输效率。以下是对该系列ProfiNet网关模组产品的详细介绍: 一、ProfiNet网关模组功能特…...
提示工程指南学习记录(三)
提示词示例 文本概括 Explain the above in one sentence(用一句话解释上面的信息): 提示词工程是一种用于自然语言处理的任务,目的是通过给定的文本或语音输入来生成相应的输出。它基于预训练的大型语言模型,例如通…...
04 GE - 钳制属性,等级
1.PostGameplayEffectExecute 1.作用:在这里对生命值进行最后的钳制防止越界。 2.参数中有什么: FGameplayEffectModCallbackData //传进来的值 {EffectSpec; //GESpecTargetASC //目标ASCFGameplayModifierEvaluatedData& EvaluatedData{Magni…...
【机器学习】机器学习笔记
1 机器学习定义 计算机程序从经验E中学习,解决某一任务T,进行某一性能P,通过P测定在T上的表现因经验E而提高。 eg:跳棋程序 E: 程序自身下的上万盘棋局 T: 下跳棋 P: 与新对手下跳棋时赢的概率…...
使用SSE实现实时消息推送并语音播报:从后端到前端的完整指南
前言 在现代Web应用中,实时消息推送已成为提升用户体验的关键功能。无论是即时聊天、通知提醒还是实时数据更新,都需要一种高效的服务器到客户端的通信机制。本文将详细介绍如何使用Server-Sent Events (SSE)技术实现后端向前端的实时消息推送ÿ…...
交通运输部4项网络与数据安全标准发布
近日,交通运输部审查通过并发布《交通运输数据安全风险评估指南》《交通运输行业网络安全实战演练工作规程》《交通运输电子证照数据交换与应用要求》《冷藏集装箱智能终端技术规范》等 4 项交通运输行业标准(2025 年第 3 批)。 其中&#…...
HarmonyOS-ArkUI V2装饰器: @Monitor装饰器:状态变量修改监听
Monitor作用 Monitor的作用就是来监听状态变量的值变化的。被Monitor修饰的函数,会在其对应监听的变量发生值的变化时,回调此函数,从而可以让您知道是什么值发生变化了,变化前是什么值,变化后是什么值。 V1版本的装饰器,有个叫@Watch的装饰器,其实也有监听变化的能力,…...
在Ubuntu系统中运行Windows程序
在Ubuntu系统中运行Windows程序可通过以下方法实现,根据使用场景和需求选择最适合的方案: 一、使用Wine兼容层(推荐轻量级场景) 原理:通过模拟Windows API环境直接运行.exe文件,无需安装完整系统。 步骤&a…...
七大数据库全面对比:ClickHouse、ES、MySQL等特性、优缺点及使用场景
七大数据库全面对比:ClickHouse、ES、MySQL等特性、优缺点及使用场景 引言 在数字化时代,数据库的选择对于业务的成功至关重要。本文将通过表格形式,对ClickHouse、Elasticsearch(ES)、MySQL、SQL Server、MongoDB、HBase、Cassandra这七大数据库进行特性、优缺点及使用…...
循环神经网络 - 门控循环单元网络之参数学习
GRU(门控循环单元)的参数学习与其他循环神经网络类似,主要依赖于梯度下降和反向传播通过时间(BPTT)算法。下面我们通过一个简单例子来说明 GRU 参数是如何在训练过程中“自适应”调整的。 一、GRU参数学习 假设我们的…...
Java并发编程面试题:内存模型(6题)
🧑 博主简介:CSDN博客专家,历代文学网(PC端可以访问:https://literature.sinhy.com/#/?__c1000,移动端可微信小程序搜索“历代文学”)总架构师,15年工作经验,精通Java编…...
SpringBoot Starter自定义:创建可复用的自动配置模块
文章目录 引言一、自定义Starter基础知识二、创建自动配置模块2.1 项目结构搭建2.2 配置属性类2.3 服务接口及实现2.4 自动配置类2.5 spring.factories文件2.6 Maven依赖配置 三、创建Starter模块3.1 项目结构3.2 Maven依赖配置 四、使用自定义Starter4.1 添加依赖4.2 配置属性…...
服务器风扇故障导致过热问题的解决方案
# 服务器风扇故障导致过热问题的解决方案 ## 一、故障诊断与确认 ### 1. 确认风扇故障现象 bash # 检查系统日志中的硬件错误 dmesg | grep -i fan journalctl -b | grep -i thermal # 查看传感器数据(需要安装lm-sensors) sudo sensors-detect sudo …...
[OS] vDSO + vvar(频繁调用的处理) | 存储:寄存器(高效)和栈(空间大)| ELF标准包装规范(加速程序加载)
vDSO vvar 一、社区公告板系统(类比 vDSO vvar) 想象你住在一个大型社区,管理员(内核)需要向居民(用户程序)提供实时信息(如天气预报、社区活动时间等)。直接让每个居…...
SQL刷题日志(day1)
1、substring_index(截取字符串) 参数说明: profile:要处理的字符串字段。,:分隔符。-1:表示从字符串的右侧开始截取,第一个出现的分隔符后面的所有内容。 SELECT SUBSTRING_INDEX(profile, ,…...
爬虫:一文掌握 curl-cffi 的详细使用(支持 TLS/JA3 指纹仿真的 cURL 库)
更多内容请见: 爬虫和逆向教程-专栏介绍和目录 文章目录 一、curl-cffi 概述1.1 curl-cffi介绍1.2 主要特性1.3 适用场景1.4 使用 curl-cffi 的注意事项1.5 与 requests 和 pycurl 对比1.6 curl-cffi 的安装二、基本使用2.1 同步请求2.2 异步请求三、高级功能3.1 模拟浏览器指…...
前端开发基础:HTML 与 CSS 入门详解
目录 一、HTML 基础 (一)HTML 概述 (二)HTML 标签 标签分类 常用标签详解 (三)HTML 注释 二、CSS 样式 (一)CSS 概述 (二)CSS 引入方式 ࿰…...
实时语音交互数字人VideoChat,可自定义形象与音色,支持音色克隆,首包延迟低至3s
简介 实时语音交互数字人,支持端到端语音方案(GLM-4-Voice - THG)和级联方案(ASR-LLM-TTS-THG)。用户可通过麦克风或文本输入,与数字人进行语音或视频交互。 目前支持的功能 支持自定义形象TTS模块添加音…...
25.OpenCV中的霍夫圆变换
OpenCV中的霍夫圆变换 在图像处理与计算机视觉中,圆形检测是一项常见的任务,应用场景包括车牌识别、瞳孔检测、交通标志识别等。霍夫圆变换(Hough Circle Transform)是一种高效且鲁棒的算法,通过在参数空间中寻找局部…...
OpenTiny使用指南
最近项目里用到了一个新的组件库——OpenTiny,但是官方文档的使用指南的描述很复杂,花了一些时间尝试才正常使用。下面是一个使用步骤的描述,可放心食用: 一、安装 TinyVue 组件库同时支持 Vue 2.0 和 Vue 3.0 框架,…...
Uniapp: 大纲
目录 一、基础巩固1.1、Uniapp:下拉选择框ba-tree-picker 二、项目配置2.1、Uniapp:修改端口号2.2、Uniapp:本地存储 一、基础巩固 1.1、Uniapp:下拉选择框ba-tree-picker 二、项目配置 2.1、Uniapp:修改端口号 2.2、Uniapp:本…...
A2A协议实现详解及示例
A2A协议概述 A2A (Agent2Agent) 是Google推出的一个开放协议,旨在使AI智能体能够安全地相互通信和协作。该协议打破了孤立智能体系统之间的壁垒,实现了复杂的跨应用自动化。[1] A2A协议的核心目标是让不同的AI代理能够相互通信、安全地交换信息以及在各…...
HTTP协议入门
文章目录 1. 概述2. 请求协议2.1 Get 方式请求协议2.2 POST 方式的请求2.3 获取请求数据 3. 响应协议3.1 响应数据格式3.2 设置响应数据 1. 概述 概念 :Hyper Text Transfer Protocol,超文本传输协议,规定了浏览器和服务器之间数据传输的规则…...