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

【IP101】图像处理进阶:从直方图均衡化到伽马变换,全面掌握图像增强技术

🌟 图像增强魔法指南

🎨 在图像处理的世界里,增强就像是给图片化妆,让它展现出最佳的状态。让我们一起来探索这些神奇的增强术吧!

📚 目录

  1. 基础概念 - 图像增强的"美容院"
  2. 直方图均衡化 - 光线的"均衡师"
  3. 伽马变换 - 曝光的"调节师"
  4. 对比度拉伸 - 图像的"拉筋师"
  5. 亮度调整 - 光线的"调光师"
  6. 饱和度调整 - 色彩的"调色师"
  7. 代码实现 - 增强的"工具箱"
  8. 实验效果 - 增强的"成果展"

1. 什么是图像增强?

图像增强就像是给照片做"美容",主要目的是:

  • 🔍 提高图像的视觉效果
  • 🎯 突出感兴趣的特征
  • 🛠️ 改善图像质量
  • 📊 优化图像显示效果

常见的增强操作包括:

  • 调整亮度和对比度
  • 改善图像清晰度
  • 增强边缘细节
  • 调整色彩饱和度

2. 直方图均衡化

2.1 基本原理

直方图均衡化就像是给图像"调整光线分布",让暗的地方变亮,亮的地方适当压暗,使得整体更加和谐。

数学表达式:
对于灰度图像,设原始图像的灰度值为 r k r_k rk,变换后的灰度值为 s k s_k sk,则:

s k = T ( r k ) = ( L − 1 ) ∑ j = 0 k n j n s_k = T(r_k) = (L-1)\sum_{j=0}^k \frac{n_j}{n} sk=T(rk)=(L1)j=0knnj

其中:

  • L L L 是灰度级数(通常为256)
  • n j n_j nj 是灰度值为j的像素数量
  • n n n 是图像总像素数
  • k k k 是当前灰度值(0到L-1)

2.2 实现方法

  1. 全局直方图均衡化:

    • 计算整幅图像的直方图
    • 计算累积分布函数(CDF)
    • 进行灰度映射
  2. 自适应直方图均衡化(CLAHE):

    • 将图像分成小块
    • 对每个小块进行均衡化
    • 使用双线性插值合并结果
      详细可以参考限制对比度自适应直方图均衡化(CLAHE)

2.3 手动实现

C++实现
void histogram_equalization(const Mat& src, Mat& dst) {CV_Assert(!src.empty() && src.channels() == 1);// 计算直方图int hist[256] = {0};for (int y = 0; y < src.rows; y++) {for (int x = 0; x < src.cols; x++) {hist[src.at<uchar>(y, x)]++;}}// 计算累积分布函数float cdf[256] = {0};cdf[0] = hist[0];for (int i = 1; i < 256; i++) {cdf[i] = cdf[i-1] + hist[i];}// 归一化CDFfor (int i = 0; i < 256; i++) {cdf[i] = cdf[i] * 255 / (src.rows * src.cols);}// 应用映射dst.create(src.size(), src.type());for (int y = 0; y < src.rows; y++) {for (int x = 0; x < src.cols; x++) {dst.at<uchar>(y, x) = saturate_cast<uchar>(cdf[src.at<uchar>(y, x)]);}}
}
Python实现
def histogram_equalization_manual(image):"""手动实现直方图均衡化参数:image: 输入灰度图像"""if len(image.shape) == 3:gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)else:gray = image.copy()# 计算直方图hist = cv2.calcHist([gray], [0], None, [256], [0, 256])# 计算累积分布函数cdf = hist.cumsum()cdf_normalized = cdf * 255 / cdf[-1]# 应用映射result = np.interp(gray.flatten(), np.arange(256), cdf_normalized.flatten())result = result.reshape(gray.shape).astype(np.uint8)return result

3. 伽马变换

3.1 基本原理

伽马变换就像是给图像调整"曝光度",可以有效地改变图像的整体亮度。

数学表达式:
s = c r γ s = cr^\gamma s=crγ

其中:

  • r r r 是输入像素值(0到1之间)
  • s s s 是输出像素值(0到1之间)
  • c c c 是常数(通常取1)
  • γ \gamma γ 是伽马值
    • γ > 1 \gamma > 1 γ>1 图像变暗
    • γ < 1 \gamma < 1 γ<1 图像变亮
    • γ = 1 \gamma = 1 γ=1 图像不变

3.2 手动实现

C++实现
void gamma_correction(const Mat& src, Mat& dst, double gamma) {CV_Assert(!src.empty());// 创建查找表uchar lut[256];for (int i = 0; i < 256; i++) {lut[i] = saturate_cast<uchar>(pow(i / 255.0, gamma) * 255.0);}// 应用伽马校正dst.create(src.size(), src.type());for (int y = 0; y < src.rows; y++) {for (int x = 0; x < src.cols; x++) {if (src.channels() == 3) {Vec3b pixel = src.at<Vec3b>(y, x);dst.at<Vec3b>(y, x) = Vec3b(lut[pixel[0]],lut[pixel[1]],lut[pixel[2]]);} else {dst.at<uchar>(y, x) = lut[src.at<uchar>(y, x)];}}}
}
Python实现
def gamma_correction_manual(image, gamma=1.0):"""手动实现伽马变换参数:image: 输入图像gamma: 伽马值"""# 创建查找表lut = np.array([((i / 255.0) ** gamma) * 255.0 for i in range(256)]).astype(np.uint8)# 应用伽马校正if len(image.shape) == 3:result = np.zeros_like(image)for i in range(3):result[:,:,i] = lut[image[:,:,i]]else:result = lut[image]return result

4. 对比度拉伸

4.1 基本原理

对比度拉伸就像是给图像"拉筋",让暗部更暗,亮部更亮,增加图像的"张力"。

数学表达式:
s = r − r m i n r m a x − r m i n ( s m a x − s m i n ) + s m i n s = \frac{r - r_{min}}{r_{max} - r_{min}}(s_{max} - s_{min}) + s_{min} s=rmaxrminrrmin(smaxsmin)+smin

其中:

  • r r r 是输入像素值
  • s s s 是输出像素值
  • r m i n , r m a x r_{min}, r_{max} rmin,rmax 是输入图像的最小和最大灰度值
  • s m i n , s m a x s_{min}, s_{max} smin,smax 是期望的输出范围

4.2 手动实现

C++实现
void contrast_stretching(const Mat& src, Mat& dst,double smin = 0, double smax = 255) {CV_Assert(!src.empty());// 找到最小和最大像素值double rmin, rmax;minMaxLoc(src, &rmin, &rmax);// 计算拉伸参数double scale = (smax - smin) / (rmax - rmin);double offset = smin - rmin * scale;// 应用对比度拉伸dst.create(src.size(), src.type());for (int y = 0; y < src.rows; y++) {for (int x = 0; x < src.cols; x++) {if (src.channels() == 3) {Vec3b pixel = src.at<Vec3b>(y, x);dst.at<Vec3b>(y, x) = Vec3b(saturate_cast<uchar>(pixel[0] * scale + offset),saturate_cast<uchar>(pixel[1] * scale + offset),saturate_cast<uchar>(pixel[2] * scale + offset));} else {dst.at<uchar>(y, x) = saturate_cast<uchar>(src.at<uchar>(y, x) * scale + offset);}}}
}
Python实现
def contrast_stretching_manual(image, smin=0, smax=255):"""手动实现对比度拉伸参数:image: 输入图像smin: 输出最小值smax: 输出最大值"""# 找到最小和最大像素值rmin, rmax = image.min(), image.max()# 计算拉伸参数scale = (smax - smin) / (rmax - rmin)offset = smin - rmin * scale# 应用对比度拉伸result = image * scale + offsetresult = np.clip(result, smin, smax).astype(np.uint8)return result

5. 亮度调整

5.1 基本原理

亮度调整就像是给图像调整"灯光",可以让整体变亮或变暗。

数学表达式:
s = r + β s = r + \beta s=r+β

其中:

  • r r r 是输入像素值
  • s s s 是输出像素值
  • β \beta β 是亮度调整值
    • β > 0 \beta > 0 β>0 增加亮度
    • β < 0 \beta < 0 β<0 降低亮度

5.2 手动实现

C++实现
void brightness_adjustment(const Mat& src, Mat& dst, int beta) {CV_Assert(!src.empty());dst.create(src.size(), src.type());for (int y = 0; y < src.rows; y++) {for (int x = 0; x < src.cols; x++) {if (src.channels() == 3) {Vec3b pixel = src.at<Vec3b>(y, x);dst.at<Vec3b>(y, x) = Vec3b(saturate_cast<uchar>(pixel[0] + beta),saturate_cast<uchar>(pixel[1] + beta),saturate_cast<uchar>(pixel[2] + beta));} else {dst.at<uchar>(y, x) = saturate_cast<uchar>(src.at<uchar>(y, x) + beta);}}}
}
Python实现
def brightness_adjustment_manual(image, beta):"""手动实现亮度调整参数:image: 输入图像beta: 亮度调整值"""result = image.astype(np.int16) + betaresult = np.clip(result, 0, 255).astype(np.uint8)return result

6. 饱和度调整

6.1 基本原理

饱和度调整就像是给图像调整"色彩浓度",可以让颜色更鲜艳或更淡雅。

数学表达式:
s = r ⋅ ( 1 − α ) + r a v g ⋅ α s = r \cdot (1 - \alpha) + r_{avg} \cdot \alpha s=r(1α)+ravgα

其中:

  • r r r 是输入像素值
  • s s s 是输出像素值
  • r a v g r_{avg} ravg 是像素的灰度值
  • α \alpha α 是饱和度调整系数
    • α > 1 \alpha > 1 α>1 增加饱和度
    • α < 1 \alpha < 1 α<1 降低饱和度

6.2 手动实现

C++实现
void saturation_adjustment(const Mat& src, Mat& dst, float alpha) {CV_Assert(!src.empty() && src.channels() == 3);dst.create(src.size(), src.type());for (int y = 0; y < src.rows; y++) {for (int x = 0; x < src.cols; x++) {Vec3b pixel = src.at<Vec3b>(y, x);float gray = 0.299f * pixel[2] + 0.587f * pixel[1] + 0.114f * pixel[0];dst.at<Vec3b>(y, x) = Vec3b(saturate_cast<uchar>(pixel[0] * (1 - alpha) + gray * alpha),saturate_cast<uchar>(pixel[1] * (1 - alpha) + gray * alpha),saturate_cast<uchar>(pixel[2] * (1 - alpha) + gray * alpha));}}
}
Python实现
def saturation_adjustment_manual(image, alpha):"""手动实现饱和度调整参数:image: 输入图像alpha: 饱和度调整系数"""# 转换为HSV空间hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)# 调整饱和度通道hsv[:,:,1] = np.clip(hsv[:,:,1] * alpha, 0, 255).astype(np.uint8)# 转回BGR空间result = cv2.cvtColor(hsv, cv2.COLOR_HSV2BGR)return result

7. 代码实现与优化

7.1 性能优化技巧

  1. SIMD加速:
// 使用AVX2指令集加速直方图计算
inline void calculate_histogram_simd(const uchar* src, int* hist, int width) {alignas(32) int local_hist[256] = {0};for (int x = 0; x < width; x += 32) {__m256i pixels = _mm256_loadu_si256((__m256i*)(src + x));for (int i = 0; i < 32; i++) {local_hist[_mm256_extract_epi8(pixels, i)]++;}}
}
  1. OpenMP并行化:
#pragma omp parallel for collapse(2)
for (int y = 0; y < src.rows; y++) {for (int x = 0; x < src.cols; x++) {// 处理每个像素}
}
  1. 内存对齐:
alignas(32) float buffer[256];  // AVX2对齐

7.2 关键代码实现

💡 更多精彩内容和详细实现,请关注微信公众号【GlimmerLab】,项目持续更新中…

🌟 欢迎访问我们的Github项目: GlimmerLab

8. 实验效果与应用

8.1 应用场景

  1. 照片处理:

    • 逆光照片修正
    • 夜景照片增强
    • 老照片修复
  2. 医学图像:

    • X光片增强
    • CT图像优化
    • 超声图像处理
  3. 遥感图像:

    • 卫星图像增强
    • 地形图优化
    • 气象图像处理

8.2 注意事项

  1. 增强过程中的注意点:

    • 避免过度增强
    • 保持细节不失真
    • 控制噪声放大
  2. 算法选择建议:

    • 根据图像特点选择
    • 考虑实时性要求
    • 权衡质量和效率

总结

图像增强就像是给照片开了一家"美容院"!通过直方图均衡化、伽马变换、对比度拉伸等"美容项目",我们可以让图像焕发新的活力。在实际应用中,需要根据具体场景选择合适的"美容方案",就像为每个"顾客"定制专属的护理方案一样。

记住:好的图像增强就像是一个经验丰富的"美容师",既要让照片变得更美,又要保持自然!✨

参考资料

  1. Gonzalez R C, Woods R E. Digital Image Processing[M]. 4th Edition
  2. OpenCV官方文档: https://docs.opencv.org/
  3. 更多资源: IP101项目主页

相关文章:

【IP101】图像处理进阶:从直方图均衡化到伽马变换,全面掌握图像增强技术

&#x1f31f; 图像增强魔法指南 &#x1f3a8; 在图像处理的世界里&#xff0c;增强就像是给图片化妆&#xff0c;让它展现出最佳的状态。让我们一起来探索这些神奇的增强术吧&#xff01; &#x1f4da; 目录 基础概念 - 图像增强的"美容院"直方图均衡化 - 光线的…...

【Azure Redis 缓存】关于Azure Cache for Redis 服务在传输和存储键值对(Key/Value)的加密问题

问题描述 Azure Cache for Redis 服务在传输和存储数据时是如何加密呢&#xff1f; 问题回答 一&#xff1a;关于Azure cache for Redis服务在数据传输过程中是如何加密的&#xff1f; 为了确保在Azure cache for Redis和客户端应用程序之间传输的数据安全&#xff0c;需要启用…...

Cursor 被封解决方案

一、注册一个无限邮箱 没事点点广告&#xff0c;让网站活久一点(✪ω✪) 2925邮箱-无限邮2925无限邮箱支持多种客户端收发邮件且数据安全加密多端同步。只需要注册一个账号&#xff0c;就能生成无限多个2925子邮箱账号&#xff0c;同时利用一邮多用功能对多个子邮箱邮件进行集…...

spring上传文件添加水印

1、实现 MultipartFile package com.pojo.common.core.domain;import java.io.ByteArrayInputStream; import java.io.File; import java.io.IOException; import java.io.InputStream;import org.springframework.lang.Nullable; import org.springframework.util.Assert; im…...

CSS分栏布局

分栏布局将区域划分为若干垂直的栏&#xff0c;子元素放置到栏中&#xff0c;填满一个后再填充下一个。如果设置了 column-count 栏数量或 column-width 栏宽度&#xff0c;元素就成为分栏容器。需要注意&#xff0c; column-width 实际上是最小栏宽度。浏览器使用这个值计算栏…...

通过 ModernBERT 实现零样本分类的性能提升

文本分类 是机器学习中最基础的任务之一&#xff0c;拥有悠久的研究历史和深远的实用价值。更重要的是&#xff0c;它是许多实际项目中不可或缺的组成部分&#xff0c;从搜索引擎到生物医学研究都离不开它。文本分类方法被广泛应用于科学论文分类、用户工单分类、社交媒体情感分…...

【AI】Ubuntu 22.04 4060Ti 16G vllm-api部署Qwen3-8B-FP8

下载模型 # 非常重要&#xff0c;否则容易不兼容报错 pip install modelscope -U cd /data/ai/models modelscope download --model Qwen/Qwen3-8B-FP8 --local_dir ./Qwen3-8B-FP8 安装vllm 创建虚拟环境 mkdir vllm cd vllm/ python -m venv venv ource venv/bin/activat…...

QML ProgressBar控件详解

在 QML 中&#xff0c;ProgressBar 是一个常用的进度条控件&#xff0c;用于显示任务的完成进度。以下是 ProgressBar 的详细用法&#xff0c;包括基本用法、自定义样式、动态绑定数据等。 1. 基本用法 1.1 最简单的 ProgressBar import QtQuick.Controls 2.15ProgressBar {w…...

STM32教程:串口USART通讯协议原理及分析(基于STM32F103C8T6最小系统板标准库开发)*详细教程*

前言: 本文主要介绍了单片机的通讯协议和STM32的串口USART通讯的原理及分析。 通信的目的 将一个设备的数据传送到另一个设备,扩展硬件系统。 通信协议 指定通信的规则,通信双方按照协议规则进行数据收发。 STM32常见通讯协议 各通讯特点 USART: TX(发送)、RX(接…...

EDA文件

不同的EDA软件使用不同的文件扩展名和格式&#xff0c;以下是主流工具对应的文件类型&#xff1a; EDA软件文件扩展名说明Altium Designer.PcbDocAltium专属格式&#xff0c;需用原软件打开&#xff0c;可导出为Gerber或STEP文件用于生产。KiCad.kicad_pcbKiCad项目文件&#…...

【C/C++】构造函数与析构函数

&#x1f4d8; C 构造函数与析构函数详解笔记 &#x1f9e0; 为什么需要构造函数与析构函数&#xff1f; 在 C 中&#xff0c;对象创建和销毁过程如果仅靠手动赋值和清理非常容易出错。为此&#xff0c;语言提供了构造函数和析构函数&#xff1a; 构造函数&#xff1a;用于在…...

在Unity AR应用中实现摄像头切换功能

本教程将详细讲解如何在Unity AR Foundation项目中实现前后摄像头切换功能,并提供完整的代码解析。我们将使用AR Foundation的核心组件和简单的UI交互来实现这一功能。 第一部分:环境准备 1.1 所需组件 Unity 2019.4或更高版本 AR Foundation 4.0+ ARCore XR Plugin(Andro…...

Pycharm(十九)深度学习

一、深度学习概述 1.1 什么是深度学习 深度学习是机器学习中的一种特殊方法,它使用称为神经网络的复杂结构,特别是“深层”的神经网络,来学习和做出预测。深度学习特别适合处理大规模和高维度的数据,如图像、声音和文本。深度学习、机器学习和人工智能之间的关系如下图所…...

状态模式 VS 策略模式

在软件开发的世界里&#xff0c;设计模式如同工匠手中的精良工具&#xff0c;能帮助开发者打造出结构清晰、易于维护和扩展的软件系统。状态模式和策略模式便是其中两个常用却容易让人混淆的设计模式。接下来&#xff0c;我们会详细剖析它们的区别、适用场景&#xff0c;并给出…...

如何在 Ubuntu 24.04 本地安装 DeepSeek ?

在本地 Ubuntu 系统上安装 DeepSeek 可以让您在本地使用高级 AI 功能&#xff0c;从而消除对云服务的依赖需求。 What is DeepSeek? DeepSeek 是一个先进的开源人工智能模型&#xff0c;专为自然语言理解和生成而设计。它提供了类似ChatGPT的强大功能。 Prerequisites: A …...

云计算训练营笔记day02(Linux、计算机网络、进制)

Linux 是一个操作系统 Linux版本 RedHat Rocky Linux CentOS7 Linux Ubuntu Linux Debian Linux Deepin Linux 登录用户 管理员 root a 普通用户 nsd a 打开终端 放大: ctrl shift 缩小: ctrl - 命令行提示符 [rootlocalhost ~]# ~ 家目录 /root 当前登录的用户…...

数据库实验10 函数存储

数据库实验10 一、实验目的 掌握函数和存储过程的定义方法&#xff0c;包括标量函数、表值函数、存储过程的语法结构。理解函数和存储过程的作用及原理&#xff0c;区分标量函数与表值函数的应用场景&#xff0c;掌握存储过程的参数传递、逻辑控制和错误处理机制。能够熟练运…...

SQL Server执行安装python环境

安装注意事项 启用python脚本支持 sp_configure external scripts enabled, 1; RECONFIGURE; 安装后接受 Python EULA协议 接受python授权 setup.exe /qs /ACTIONInstall /FEATURESSQL_INST_MR /INSTANCENAME您的实例名 /IACCEPTROPENLICENSETERMS1 /IACCEPTPYTHONLICENSETE…...

ActiveMQ 安全机制与企业级实践(二)

四、企业级实践案例分析 4.1 案例背景介绍 某大型电商企业拥有复杂的分布式系统&#xff0c;涵盖订单管理、库存管理、物流配送、用户服务等多个核心业务模块。在业务快速发展过程中&#xff0c;系统间的通信量呈爆发式增长&#xff0c;为了实现系统的高效解耦和异步通信&…...

ActiveMQ 安全机制与企业级实践(一)

一、引言 在当今数字化时代&#xff0c;企业级应用的架构愈发复杂&#xff0c;各个系统之间的通信和协作变得至关重要。消息队列作为一种高效的异步通信机制&#xff0c;在企业级应用集成中扮演着关键角色。ActiveMQ 作为一款广泛使用的开源消息中间件&#xff0c;以其丰富的功…...

【Python pass 语句】

在 Python 中&#xff0c;pass 语句是一个特殊的空操作&#xff08;no-op&#xff09;语句&#xff0c;它的核心作用是保持程序结构的完整性&#xff0c;同时不执行任何实际操作。以下是详细说明&#xff1a; 一、基础特性 语法占位符&#xff1a;当语法上需要一条语句&#x…...

Maven依赖未生效问题

在你描述的情况下&#xff0c;测试类无法找到 Maven 依赖的 jar 包&#xff0c;可能由以下原因导致&#xff1a; 依赖未正确添加到 pom.xml 检查 pom.xml 文件中是否正确添加了 Elasticsearch 和 JUnit 等相关依赖。例如&#xff0c;对于 Elasticsearch 的 TransportClient 相关…...

NGINX `ngx_http_auth_request_module` 模块详解基于子请求的认证授权方案

一、背景介绍 在 Web 系统中&#xff0c;我们常常需要根据外部服务&#xff08;例如单点登录、API 网关、权限中心&#xff09;的结果来判断用户是否有权限访问某个资源。NGINX 提供的 ngx_http_auth_request_module 模块&#xff0c;正是为这种场景而生。它允许通过向后端发送…...

Qwen3简要介绍(截止20250506)

Qwen3是阿里云推出的一个大语言模型系列&#xff0c;它在多个方面进行了升级和优化。以下是Qwen3的一些主要特点&#xff1a; 模型规模多样&#xff1a;Qwen3提供了一系列不同规模的模型&#xff0c;包括稠密模型&#xff08;0.6B、1.7B、4B、8B、14B、32B&#xff09;以及专家…...

精益数据分析(42/126):移动应用商业模式的深度剖析与实战要点

精益数据分析&#xff08;42/126&#xff09;&#xff1a;移动应用商业模式的深度剖析与实战要点 在创业和数据分析的学习之路上&#xff0c;我们持续探索不同商业模式的奥秘&#xff0c;今天聚焦于移动应用商业模式。我希望和大家一起进步&#xff0c;深入解读《精益数据分析…...

2025.5.6总结

昨天12&#xff1a;30睡觉&#xff0c;结果翻来覆去睡不着&#xff0c;两点半左右才睡着。看了一下最近的睡眠打卡&#xff0c;平均入睡时间是凌晨12&#xff1a;30。 自五一一个人过了5天&#xff0c;我才明白&#xff0c;人是需要社交的&#xff0c;只有在社交中才能找到自我…...

UE5 脚部贴地不穿过地板方案

UE自带的IK RIG和ControlRig技术 【UE5】角色脚部IK——如何让脚贴在不同斜度的地面(设置脚的旋转)_哔哩哔哩_bilibili 实验后这个还是有一部分问题,首先只能保证高度不能穿过,但是脚步旋转还是会导致穿模 IK前,整个模型在斜坡上会浮空 参考制作:https://www.youtube.com/w…...

Spring AI 函数调用(Function Call)系统设计方案

一、系统概述与设计目标 1.1 核心目标 从零构建一个灵活、安全、高效的函数调用系统,使大语言模型能够在对话中调用应用程序中的方法,同时保持良好的开发体验和企业级特性。 1.2 主要功能需求 支持通过注解将普通Java方法标记为可被AI调用的函数自动生成符合LLM要求的函数…...

Jupyter Notebook为什么适合数据分析?

Jupyter Notebook 是一款超实用的 Web 应用程序&#xff0c;在数据科学、编程等诸多领域都发挥着重要作用。它最大的特点就是能让大家轻松创建和共享文学化程序文档。这里说的文学化程序文档&#xff0c;简单来讲&#xff0c;就是把代码、解释说明、数学公式以及数据可视化结果…...

Leetcode Hot 100字母异位词分词

题目描述 思路 根据题意&#xff0c;我们可以得知我们需要将字符统计数一样的字符串&#xff0c;放在一起&#xff0c;并以列表进行返回。因此我们可以通过一个哈希表&#xff0c;把统计相同的放在一起&#xff0c;最终返回即可 代码 class Solution:def groupAnagrams(self…...

用python实现鼠标监听与手势交互

摘要 本文探讨了一种基于Python的数学函数可视化系统的设计与实现&#xff0c;该系统整合了Pynput鼠标事件监听机制、Matplotlib绘图引擎以及PyQt5图形用户界面框架。系统通过人机交互方式实现了函数图像的直观构建与可视化表达&#xff0c;支持多种函数类型的参数化建模与实时…...

UE5 GAS开发P47 游戏标签

FGameplayTag 是 Unreal Engine 中用于标记游戏对象的系统。它允许开发者为游戏对象分配标签&#xff0c;以便在游戏中对其进行分类、识别和操作。 FGameplayTag 结构用于表示单个游戏标签&#xff0c;而 FGameplayTagContainer 则用于表示一组游戏标签。 这些标签可以用于诸…...

C# 实现PLC数据自动化定时采集与存储(无需界面,自动化运行)

C# 实现PLC数据自动化定时采集与存储&#xff08;无需界面&#xff0c;自动化运行&#xff09; 在平时开发中&#xff0c;我们时常会遇到需要后台静默运行的应用场景&#xff0c;这些程序不需要用户的直接操作或界面展示&#xff0c;而是专注于定时任务的执行。比如说&#xf…...

Java实现堆排序算法

1. 堆排序原理图解 堆排序是一种基于二叉堆&#xff08;通常使用最大堆&#xff09;的排序算法。其核心思想是利用堆的性质&#xff08;父节点的值大于或等于子节点的值&#xff09;来高效地进行排序。堆排序分为两个主要阶段&#xff1a;建堆和排序。 堆排序步骤&#xff1a; …...

封装axios,实现取消请求

封装axios import axios from axios// 创建自定义的请求类 class CancelableRequest {constructor() {this.controller new AbortController()}abort() {this.controller.abort()} }// 创建 axios 实例 const service axios.create({baseURL: process.env.VUE_APP_BASE_API,…...

在 Laravel 12 中实现 WebSocket 通信

在 Laravel 12 中实现 WebSocket 通信主要有两种主流方案&#xff1a;‌官方推荐的 Laravel Reverb‌ 和 ‌第三方库&#xff08;如 Soketi/Pusher 或 Workerman/Swoole&#xff09;‌。以下是详细实现步骤&#xff1a; 一、官方方案&#xff1a;Laravel Reverb&#xff08;推…...

iPhone或iPad想要远程投屏到Linux系统电脑,要怎么办?

苹果手机自带AirPlay投屏功能&#xff0c;对于苹果电脑&#xff0c;自然可以随时投屏。但如果电脑是Linux系统&#xff0c;而且还想要远程投屏呢&#xff1f;这时候要怎么将iPhone或iPad投屏到Linux电脑&#xff1f; 方法很简单&#xff0c;用AirDroid Cast的网页版即可。 步骤…...

Ubuntu 22.04 安装配置远程桌面环境指南

在云服务器或远程主机上安装图形化桌面环境,可以极大地提升管理效率和用户体验。本文将详细介绍如何在 Ubuntu 22.04 (Jammy Jellyfish) 系统上安装和配置 Xfce4 桌面环境,并通过 VNC 实现远程访问。 系统环境 操作系统:Ubuntu 22.04 LTS (Jammy Jellyfish)架构:AMD64安装…...

【Redis | 基础总结篇 】

目录 前言&#xff1a; 1.Redis的介绍&#xff1a; 2.Redis的类型与命令&#xff1a; 3.Redis的安装&#xff1a; 3.1.Windows版本 3.2.Linux版本 4.在java中使用Redis&#xff1a; 4.1.介绍 4.2.Jedis 4.3.Spring Data Redis 前言&#xff1a; 本篇主要讲述了Redis的…...

如何通过外网访问内网?对比5个简单的局域网让互联网连接方案

在实际应用中&#xff0c;常常需要从外网访问内网资源&#xff0c;如远程办公访问公司内部服务器、在家访问家庭网络中的设备等。又或者在本地内网搭建的项目应用需要提供互联网服务。以下介绍几种常见的外网访问内网、内网提供公网连接实现方法参考。 一、公网IP路由器端口映…...

iMeta | 临床研究+scRNA-seq的组合思路 | 真实世界新辅助研究,HER2⁺就一定受益?单细胞揭示真正的“疗效敏感克隆”

&#x1f44b; 欢迎关注我的生信学习专栏~ 如果觉得文章有帮助&#xff0c;别忘了点赞、关注、评论&#xff0c;一起学习 近年来&#xff0c;临床医学与单细胞组学的结合开启了全新的研究范式&#xff0c;让临床医生能以“显微镜”般的精度&#xff0c;深入理解疾病机制与疗效…...

国标GB28181视频平台EasyCVR安防系统部署知识:如何解决异地监控集中管理和组网问题

在企业、连锁机构及园区管理等场景中&#xff0c;异地监控集中管控与快速组网需求日益迫切。弱电项目人员和企业管理者亟需整合分散监控资源&#xff0c;实现跨区域统一管理与实时查看。 一、解决方案 案例一&#xff1a;运营商专线方案​ 利用运营商专线&#xff0c;连接各分…...

220V降12V1000mA非隔离芯片WT5110

220V降12V1000mA非隔离芯片WT5110 以下是采用WT5110芯片的非隔离降压电源电路设计&#xff0c;将220V电压转换为12V、1000mA输出&#xff1a; 一、WT5110芯片简介 WT5110是一款用于非隔离降压应用的集成电路&#xff0c;具备宽输入电压范围和高效的转换功能。它可以将高输入电…...

【ES】Elasticsearch字段映射冲突问题分析与解决

在使用Elasticsearch作为搜索引擎时&#xff0c;经常会遇到一些映射(Mapping)相关的问题。本文将深入分析字段映射冲突问题&#xff0c;并通过原生的Elasticsearch API请求来复现和解决这个问题。 问题描述 在实际项目中&#xff0c;我们遇到以下错误&#xff1a; Transport…...

【上位机——MFC】绘图

相关类 CDC类(绘图设备类)&#xff1a;封装了各种绘图相关的函数&#xff0c;以及两个非常重要的成员变量m_hDC和m_hAttribDC CPaintDC类&#xff0c;封装了在WM_PAINT消息中绘图的绘图设备 CClientDC类&#xff0c;封装了在客户区绘图的绘图设备 CGdiObject类(绘图对象类) 封…...

【AI】Ubuntu 22.04 evalscope 模型评测 Qwen3-4B-FP8

安装evalscope mkdir evalscope cd evalscope/ python3 -m venv venv source venv/bin/activate pip install evalscope[app,perf] -U -i https://mirrors.aliyun.com/pypi/simple --trusted-host mirrors.aliyun.compip install tiktoken omegaconf -i https://mirrors.aliyu…...

js var a=如果ForRemove=true,是“normal“,否则为“bold“

你是想根据变量 ForRemove 的布尔值来给变量 a 赋值&#xff0c;如果 ForRemove 为 true&#xff0c;则 a 的值是 "normal"&#xff0c;否则为 "bold"。在 JavaScript 里&#xff0c;你可以使用 if...else 语句或者三元运算符来实现。 方法一&#xff1a;…...

JavaScript性能优化实战:从瓶颈分析到解决方案

前言 在当今快节奏的互联网环境中&#xff0c;用户对网站性能的期望日益提高。 JavaScript作为前端开发的核心语言&#xff0c;其性能直接影响用户体验。本文将深入探讨JavaScript代码中常见的性能瓶颈&#xff0c;并结合实际案例分享优化技巧和工具&#xff0c;帮助开发者提升…...

CyberSentinel AI开源程序 是一个自动化安全监控与AI分析系统

​一、软件介绍 文末提供程序和源码下载 CyberSentinel AI 开源程序是一个强大的自动化安全监控与AI分析系统&#xff0c;旨在帮助安全研究人员和爱好者 实时追踪最新的安全漏洞 (CVE) 和 GitHub 上的安全相关仓库&#xff0c;并利用 人工智能技术进行深度分析&#xff0c;最终…...

C++23 std::generator:用于范围的同步协程生成器 (P2502R2, P2787R0)

文章目录 引言C23新特性概述std::generator基本概念定义作用模板参数 std::generator特性分析与协程的结合范围视图内存管理 std::generator使用示例std::generator的优势与挑战优势挑战 总结 引言 在C的发展历程中&#xff0c;每一个新版本都带来了许多令人期待的新特性和改进…...