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

使用OpenCV 和 Dlib 实现人脸融合技术

文章目录

    • 引言
    • 一、技术概述
    • 二、环境准备
    • 三、关键代码解析
      • 1. 人脸关键点定义
      • 2. 获取人脸掩模
      • 3. 计算仿射变换矩阵
      • 4. 检测并提取人脸关键点
      • 5. 颜色校正
    • 四、完整流程
    • 五、效果展示
    • 六、总结

引言

本文将介绍如何使用Python、OpenCV和dlib库实现人脸融合技术,将一张人脸的特征无缝融合到另一张人脸上。

一、技术概述

人脸融合是一种将两张人脸的特征进行智能融合的技术,主要包含以下几个关键步骤:

  1. 人脸关键点检测
  2. 人脸对齐和仿射变换
  3. 人脸区域分割和融合
  4. 颜色校正

二、环境准备

import cv2
import numpy as np
import dlib

需要安装以下库:

  • OpenCV (pip install opencv-python)
  • NumPy (pip install numpy)
  • dlib (pip install dlib)

还需要下载dlib的预训练模型shape_predictor_68_face_landmarks.dat
链接在下方:
shape_predictor_68_face_landmarks.dat

三、关键代码解析

1. 人脸关键点定义

JAW_POINTS = list(range(0,17))  # 下巴轮廓点
RIGHT_BROW_POINTS = list(range(17,22))  # 右眉毛
LEFT_BROW_POINTS = list(range(22,27))  # 左眉毛
NOSE_POINTS = list(range(27,35))  # 鼻子
RIGHT_EYE_POINTS = list(range(36,42))  # 右眼
LEFT_EYE_POINTS = list(range(42,48))  # 左眼
MOUTH_POINTS = list(range(48,61))  # 嘴巴
FACE_POINTS = list(range(17,68))  # 全脸# 合并关键点集
POINTS = [LEFT_BROW_POINTS + RIGHT_EYE_POINTS + LEFT_EYE_POINTS + RIGHT_BROW_POINTS + NOSE_POINTS + MOUTH_POINTS]
POINTStupLe = tuple(POINTS)

2. 获取人脸掩模

def getFacemask(im, keyPoints):# 创建与图像同尺寸的全零矩阵im = np.zeros(im.shape[:2], dtype=np.float64)# 为每个面部区域创建凸包并填充for p in POINTS:points = cv2.convexHull(keyPoints[p])cv2.fillConvexPoly(im, points, color=1)# 转换为3通道并应用高斯模糊im = np.array([im, im, im]).transpose(1, 2, 0)im = cv2.GaussianBlur(im, (25, 25), 0)return im

这段代码的作用是根据给定的关键点(keyPoints)在图像上生成一个面部遮罩(face mask),并对其进行高斯模糊处理。下面是逐步解释:


(1)初始化空白图像

im = np.zeros(im.shape[:2], dtype=np.float64)
  • 创建一个与输入图像 im 大小相同的全黑(值为0)的单通道浮点型图像。

(2)绘制凸包填充区域

for p in POINTS:points = cv2.convexHull(keyPoints[p])cv2.fillConvexPoly(im, points, color=1)
  • 遍历 POINTS(可能是面部关键点的集合,比如眼睛、嘴巴等区域)。
  • 对每组关键点 keyPoints[p] 计算凸包(cv2.convexHull),得到一个凸多边形。
  • cv2.fillConvexPoly 在单通道图像 im 上填充这些凸多边形,填充值为 1(白色)。

(3) 扩展为三通道并模糊

im = np.array([im, im, im]).transpose(1, 2, 0)
  • 将单通道图像复制为三通道(RGB),通过 transpose 调整维度顺序为 (height, width, 3)
im = cv2.GaussianBlur(im, (25, 25), 0)
  • 对三通道图像应用高斯模糊(核大小为 25x25,标准差为 0 表示自动计算)。

(4)返回值

  • 返回模糊后的三通道遮罩图像,值范围是 [0, 1](原填充区域为 1,其余为 0,模糊后边缘过渡平滑)。

3. 计算仿射变换矩阵

def getM(points1, points2):points1 = points1.astype(np.float64)points2 = points2.astype(np.float64)# 中心化和归一化c1 = np.mean(points1, axis=0)c2 = np.mean(points2, axis=0)points1 -= c1points2 -= c2s1 = np.std(points1)s2 = np.std(points2)points1 /= s1points2 /= s2# 奇异值分解计算旋转矩阵U, S, Vt = np.linalg.svd(points1.T * points2)R = (U * Vt).Treturn np.hstack(((s2/s1)*R, c2.T-(s2/s1)*R*c1.T))

这段代码的作用是计算两组点集(points1points2)之间的相似变换矩阵(Similarity Transformation Matrix),用于将 points1 映射到 points2 的坐标系中。相似变换包括缩放(scale)、旋转(rotation)和平移(translation),但不包括倾斜或剪切变换。


(1)数据预处理(归一化)

points1 = points1.astype(np.float64)  
points2 = points2.astype(np.float64)  
  • 将输入的点集转换为 float64 类型,避免整数运算带来的精度问题。
c1 = np.mean(points1, axis=0)  
c2 = np.mean(points2, axis=0)  
points1 -= c1  
points2 -= c2  
  • 计算两组点的均值 c1c2(相当于中心点)。
  • 将点集中心化(减去均值),使得它们的中心都位于 (0, 0),方便后续计算旋转和缩放。
s1 = np.std(points1)  
s2 = np.std(points2)  
points1 /= s1  
points2 /= s2  
  • 计算两组点的标准差 s1s2(衡量点的分布范围)。
  • 对点集进行缩放归一化(除以标准差),使它们的尺度一致(类似于 Z-score 标准化)。

(2)计算旋转矩阵(SVD 分解)

U, S, Vt = np.linalg.svd(points1.T @ points2)  
R = (U @ Vt).T  
  • points1.T @ points2 进行奇异值分解(SVD),得到 USVt
  • 旋转矩阵 R 的计算方式为 R = U @ Vt,并转置(.T)使其适用于列向量变换。
  • 这一步的目的是找到最优旋转,使得 points1points2 对齐。

(3)计算完整的相似变换矩阵

return np.hstack(((s2/s1)*R, c2.T-(s2/s1)*R*c1.T))  
  • (s2/s1)*R:缩放因子 s2/s1 乘以旋转矩阵 R,表示 points1 需要缩放 s2/s1 倍并旋转 R 才能匹配 points2 的尺度。
  • c2.T - (s2/s1)*R @ c1.T:计算平移向量,使得变换后的 points1 中心 c1 能对齐 points2 的中心 c2
  • np.hstack:将缩放旋转部分和平移部分水平拼接,形成完整的 3×3 相似变换矩阵(如果是 2D 点,则是 2×3 矩阵,最后一行为 [0, 0, 1] 的齐次坐标形式)。

(4)数学表示
最终的变换矩阵 M 可以表示为:
在这里插入图片描述

其中:

  • ( s = \frac{s2}{s1} )(缩放因子)
  • ( R )(旋转矩阵)
  • ( t = c2 - s \cdot R \cdot c1 )(平移向量)

(5)注意事项

  • 输入 points1points2 必须是 相同数量 的点(如 68 个人脸关键点)。
  • 如果点集分布差异过大(如极端遮挡),SVD 可能无法得到正确的旋转矩阵。
  • 该变换不适用于仿射或透视变换(仅适用于相似变换,即旋转 + 缩放 + 平移)。

4. 检测并提取人脸关键点

def getKeyPoints(im):rects = detector(im, 1)shape = predictor(im, rects[0])s = np.matrix([[p.x, p.y] for p in shape.parts()])return s

这段代码的作用是检测输入图像 im 中的人脸,并提取人脸关键点(facial landmarks)。它使用了 dlib 库的预训练人脸检测器和关键点预测器。以下是逐步解析:


(1)人脸检测

rects = detector(im, 1)
  • detector
    这是一个 dlib 的预训练人脸检测器(通常是 dlib.get_frontal_face_detector() 返回的对象)。
  • 输入
    im 是输入图像(需为灰度图或 RGB 图)。
    1 表示对图像进行上采样一次(提高检测小脸的能力)。
  • 输出
    rects 是一个列表,包含检测到的所有人脸矩形框(dlib.rectangle 对象)。
    rects[0] 表示选择第一张检测到的人脸(假设图像中只有一张人脸)。

(2)关键点检测

shape = predictor(im, rects[0])
  • predictor
    这是一个 dlib 的预训练人脸关键点检测器(通常是 dlib.shape_predictor 加载的模型,如 shape_predictor_68_face_landmarks.dat)。
  • 输入
    im 是原始图像,rects[0] 是检测到的人脸矩形框。
  • 输出
    shape 是一个包含人脸关键点的对象(68 个点,涵盖五官轮廓)。

(3)关键点格式转换

s = np.matrix([[p.x, p.y] for p in shape.parts()])
  • shape.parts()
    返回所有关键点的列表(dlib.point 对象),每个点有 xy 属性。
  • 列表推导式
    将关键点转换为 (x, y) 坐标的列表,例如 [[x1, y1], [x2, y2], ...]
  • np.matrix
    将列表转换为 NumPy 矩阵(形状为 68×2,68 个点,每个点 2D 坐标)。

(4)返回值

  • s
    返回一个 68×2 的矩阵,表示 68 个人脸关键点的坐标(例如,第 0 点是下巴,第 27 点是鼻尖等)。

5. 颜色校正

def normalColor(a, b):ksize = (111, 111)aGauss = cv2.GaussianBlur(a, ksize, 0)bGauss = cv2.GaussianBlur(b, ksize, 0)weight = aGauss / bGausswhere_are_inf = np.isinf(weight)weight[where_are_inf] = 0return b * weight

这段代码的作用是 对图像 b 进行颜色校正,使其颜色分布与图像 a 相似,通常用于图像融合或颜色迁移任务。以下是逐步解析:


(1) 高斯模糊处理

ksize = (111, 111)  # 高斯核大小(非常大,用于提取低频颜色信息)
aGauss = cv2.GaussianBlur(a, ksize, 0)  # 对图像a进行高斯模糊
bGauss = cv2.GaussianBlur(b, ksize, 0)  # 对图像b进行高斯模糊
  • 高斯模糊
    使用一个非常大的核(111×111)对输入图像 ab 进行模糊,目的是提取图像的低频颜色信息(即整体色调,忽略细节)。
  • 为什么用大核?
    核越大,模糊程度越高,越能保留图像的全局颜色特征而非局部纹理。

(2) 计算颜色权重

weight = aGauss / bGauss  # 计算颜色调整权重
  • 权重计算
    通过 aGauss / bGauss 得到一个比例矩阵 weight,表示 ab 在低频颜色上的差异。
    • 如果 aGaussbGauss 亮(例如 aGauss=200bGauss=100),则 weight=2,表示需要将 b 的对应区域变亮。
    • 如果 aGaussbGauss 暗(例如 aGauss=50bGauss=100),则 weight=0.5,表示需要将 b 的对应区域变暗。

(3) 处理除零和无穷大

where_are_inf = np.isinf(weight)  # 找到无穷大的位置
weight[where_are_inf] = 0         # 将无穷大替换为0
  • 问题
    bGauss 中某些像素值为0时,aGauss / 0 会导致 weight 出现无穷大(inf)。
  • 解决
    通过 np.isinf 找到这些位置,并强制设为 0(即不调整这些像素的颜色)。

(4) 应用颜色校正

return b * weight
  • 输出
    将原始图像 b 与权重 weight 逐像素相乘,得到颜色校正后的图像。
    • 例如,b 的某个像素值为 [100, 150, 200]weight[1.2, 0.8, 1.0],则输出像素为 [120, 120, 200]

(5)注意事项

  1. 输入范围
    ab 应为浮点型([0, 1])或整型([0, 255]),需保持一致。
  2. 核大小调整
    ksize 越大,颜色迁移越全局化;越小则保留更多局部对比(但可能引入噪声)。
  3. 除零问题
    如果 bGauss 有大片黑色区域(值为0),会导致权重失效,需提前检查图像内容。

(6)数学本质
该操作近似于对图像 b 的每个颜色通道进行 逐像素的线性变换
在这里插入图片描述

其中低频分量通过高斯模糊提取。


四、完整流程

  1. 加载图像并检测关键点
a = cv2.imread("chendulin.jpg")
b = cv2.imread("linyuner.jpg")detector = dlib.get_frontal_face_detector()
predictor = dlib.shape_predictor("shape_predictor_68_face_landmarks.dat")aKeyPoints = getKeyPoints(a)
bKeyPoints = getKeyPoints(b)
  1. 生成人脸掩模
aMask = getFacemask(a, aKeyPoints)
bMask = getFacemask(b, bKeyPoints)
  1. 计算变换矩阵并应用
M = getM(aKeyPoints[POINTStupLe], bKeyPoints[POINTStupLe])
bMaskWarp = cv2.warpAffine(bMask, M, dsize, borderMode=cv2.BORDER_TRANSPARENT,flags=cv2.WARP_INVERSE_MAP)
  1. 融合人脸区域
mask = np.max([aMask, bMaskWarp], axis=0)
bWarp = cv2.warpAffine(b, M, dsize,borderMode=cv2.BORDER_TRANSPARENT,flags=cv2.WARP_INVERSE_MAP)
  1. 颜色校正和最终融合
bcolor = normalColor(a, bWarp)
out = a * (1.0 - mask) + bcolor * mask

五、效果展示

如图,我们选择一张林允儿和陈都灵的照片进行换脸,效果显示如下:
在这里插入图片描述

六、总结

  1. 关键点检测:使用dlib的68点人脸检测模型精确定位面部特征
  2. 人脸对齐:通过仿射变换将源人脸与目标人脸对齐
  3. 区域融合:使用高斯模糊的掩模实现平滑过渡
  4. 颜色校正:保持目标图像的光照和肤色一致性

通过这篇博客,我们详细讲解了基于Python的人脸融合技术实现。希望这能帮助你理解计算机视觉中人脸处理的基本原理和方法。

理想的风会吹进现实,熬过的夜也会变成光。加油各位!🚀🚀🚀

相关文章:

使用OpenCV 和 Dlib 实现人脸融合技术

文章目录 引言一、技术概述二、环境准备三、关键代码解析1. 人脸关键点定义2. 获取人脸掩模3. 计算仿射变换矩阵4. 检测并提取人脸关键点5. 颜色校正 四、完整流程五、效果展示六、总结 引言 本文将介绍如何使用Python、OpenCV和dlib库实现人脸融合技术,将一张人脸…...

Codeforces Round 1022 (Div. 2)

Problem - A - Codeforces 看这数据量&#xff0c;算出每个排列来&#xff0c;是不现实的&#xff0c;需要找找规律 来看找规律代码 #include <bits/stdc.h> using namespace std;int main() {int t;cin >> t;while (t--){int n;cin >> n;vector<int&g…...

uniapp 震动功能实现

项目场景&#xff1a; 提示&#xff1a;这里简述项目相关背景&#xff1a; 在项目中有时候需要一些功能&#xff0c;比如震动 描述 提示&#xff1a;这里描述项目中遇到的问题&#xff1a; 在移动应用中&#xff0c;震动反馈是提升用户体验的重要方式。uniapp 提供了两种震…...

uniapp 搭配 uCharts

在插件市场导入插件到项目中 <view class"charts-box-main"> <qiun-data-charts type"area" :opts"opts" :chartData"chartData" /> </view> data&#xff08;&#…...

Kubernetes(k8s)学习笔记(八)--KubeSphere定制化安装

1执行下面的命令修改上一篇中yaml文件来实现定制化安装devops kubectl edit cm -n kubesphere-system ks-installer 主要是将devops几个配置由False改为True 然后使用下面的命令查看安装日志 kubectl logs -n kubesphere-system $(kubectl get pod -n kubesphere-system -l …...

阿里云codeup以及本地gitclone+http

cmd命令行乱码问题、解决 chcp 65001 git代码提交 git add . git commit -m init git push origin master...

Spring Boot 多数据源事务管理

在 Spring Boot 中&#xff0c;当需要操作多个数据源时&#xff0c;事务管理会变得更加复杂。因为默认的 DataSourceTransactionManager 只支持单数据源事务&#xff0c;跨数据源的事务需要使用 分布式事务&#xff08;Distributed Transaction&#xff09; 或 柔性事务&#x…...

4.系统定时器基本定时器

目录 系统定时器 系统定时器&#xff08;systick&#xff09;--内核 系统定时器结构 系统滴答定时器寄存器--内核 定时周期的确定公式 配置滴答定时器 系统定时器应用 应用1.定时器构造时间点任务&#xff0c;解决while循环阻塞问题 应用2.定时器构造精准的ms延时 应…...

lvgl多语言设置

搭建开发环境 安装node.js 安装node.js&#xff0c;点击进入官网地址 安装lv_i18n lv_i18n项目地址&#xff1a;Github&#xff1a;https://github.com/lvgl/lv_i18ngit运行命令安装lv_i18n&#xff1a;npm i lv_i18n -g。测试命令&#xff1a;lv_i18n -h 搭建过程报错 …...

ICode国际青少年编程竞赛—Python—4级训练场—复杂嵌套循环

ICode国际青少年编程竞赛—Python—4级训练场—复杂嵌套循环 icode练习时遇到卡顿没有思路时怎么办&#xff0c;题目也很难找到不会的那道题&#xff5e;针对这个问题&#xff0c;我们开发了通过“步数”、“积木行数”来快速定位到你不会的题目&#xff5e; 题目会持续更新…...

【Windows】怎么解决Win 10家庭版WMI Provider Host占用CPU过高的问题?-篇一【2025.05.07】

本文面向两种用户&#xff0c;普通小白和windows开发程序员。 对于小白&#xff0c;目标就是阻止wmi对资源的高占用。解决方法有以下几步&#xff1a; 查出谁在调用这个wmiprvse.exe winR 组合键打开运行&#xff0c;输入命令services.msc&#xff0c;回车或确认。 找到如下蓝色…...

Matlab 多策略改进蜣螂优化算法及其在CEC2017性能

1、内容简介 Matlab214-多策略改进蜣螂优化算法及其在CEC2017性能 可以交流、咨询、答疑 2、内容说明 对蜣螂优化算法&#xff08;Dung Beetle Algorithm&#xff0c;DBA&#xff09;进行多种策略改进&#xff0c;以提高其在CEC2017基准测试中的表现。 蜣螂优化算法是一种仿…...

深度学习中常见的矩阵变换函数汇总(持续更新...)

1. 转置操作 (Transpose) 概念&#xff1a;将矩阵的行和列互换应用场景&#xff1a; 在卷积神经网络中转换特征图维度矩阵乘法运算前的维度调整数据预处理过程中的特征重排 原始矩阵 A [[1, 2, 3], 转置后 A^T [[1, 4],[4, 5, 6]] [2, 5],[3, 6]]代码…...

react+ts中函数组件父子通信方式

1. 父组件通过 Props 向子组件传递数据 这是最常见也是最基本的父子组件通信方式。父组件通过 props 将数据或回调函数传递给子组件。 示例代码&#xff1a; // 子组件接收来自父组件的数据 interface ChildProps {message: string; }const ChildComponent: React.FC<Chi…...

string--OJ3

链接: li1 #include <iostream> using namespace std;int main() {string a;getline(cin, a);cout << a.size() - a.find_last_of(" ")-1;{}}链接: li2 class Solution { public:bool isPalindrome(string s) {for (int i 0; i < s.size(); i){i…...

项目文档归档的最佳实践有哪些?

项目文档归档的最佳实践包括&#xff1a;明确归档标准与流程、使用集中式文档管理系统、实施严格的版本控制、定期审查与更新文档库。其中&#xff0c;明确归档标准与流程尤为关键&#xff0c;确保团队成员能统一理解并遵守文档管理规范。这包括明确文档命名规则、分类标准、归…...

C语言学习之字符函数和字符串函数

在C语言前面的内容中&#xff0c;我们学习到的库函数主要还是针对输入输出以及数字相关的内容&#xff0c;今天我们来学习一下有关于字符相关的函数&#xff0c;来对字符和字符串进行操作。 目录 字符分类函数 字符转换函数 以下的函数到strtok函数使用均需要包含头文件 st…...

自编码器(Autoencoder)

自编码器 是一种无监督学习的神经网络&#xff0c;主要用于数据的压缩和重构。它的核心思想是通过一个编码器将输入数据编码成一个低维表示&#xff08;编码&#xff09;&#xff0c;然后再通过一个解码器将这个低维表示重构回原始数据。自编码器的目标是让重构后的数据尽可能…...

黄金分割法(0.618 法)

黄金分割法简介 黄金分割法属于区间缩小法&#xff0c;通过逐步缩小包含极值的区间长度&#xff0c;逼近极值点。在每一次迭代中&#xff0c;使用黄金分割点 0.618 将区间分为两部分&#xff0c;比较这两点处的函数值&#xff0c;舍弃较差区间&#xff0c;从而逐渐逼近最优解。…...

电商双11美妆数据分析实验总结

数据分析方法与应用 数据分类与绘图 数据分类方法&#xff1a;通过指定列名和函数&#xff08;如SUM&#xff09;来分类数据&#xff0c;确保数据集中包含所需列&#xff0c;否则会报错。 嵌套柱形图应用&#xff1a;嵌套柱形图用于展示多层次分类的数据&#xff0c;如按店名和…...

TB6600HG是一款PWM(脉宽调制)斩波型单芯片双极性正弦波微步进电机驱动集成电路。

该驱动器支持电机的正向和反向旋转控制&#xff0c;并具有多种激励模式&#xff0c;包括2相、1-2相、W1-2相、2W1-2相和4W1-2相。 使用这款驱动器&#xff0c;只需时钟信号即可驱动2相双极性步进电机&#xff0c;且振动小、效率高。 主要特点&#xff1a; 单芯片双极性正弦波…...

java每日精进 5.07【框架之数据权限】

数据权限&#xff0c;实现指定用户可以操作指定范围的数据。 数据权限不支持指定用户只能查看数据的某些字段&#xff1b; 权限可以分成三类&#xff1a;功能权限、数据权限、字段权限。 目前可以使用数据脱敏实现一定程度的字段权限控制&#xff1b; 1.数据权限实现步骤 1.1插…...

2:点云处理—3D相机开发

1.包含相机库目录 1.include D:\中科\Ainstec3DViewer\AinstecCamSDK\AinstecCamSDK_CPP\include 2.lib D:\中科\Ainstec3DViewer\AinstecCamSDK\AinstecCamSDK_CPP\lib\win 3.release D:\中科\Ainstec3DViewer\AinstecCamSDK\AinstecCamSDK_CPP\bin 4.示例程序 D:\中科\A…...

MySQL 中的 MVCC 是什么?

MySQL 中的 MVCC&#xff08;Multi-Version Concurrency Control&#xff0c;多版本并发控制&#xff09; 是一种用于实现高并发读写操作的机制&#xff0c;它通过维护数据的多个版本来解决读写冲突&#xff0c;从而在保证事务隔离性的同时&#xff0c;减少锁的使用&#xff0c…...

JC/T 2187-2013 铝波纹芯复合铝板检测

铝波纹芯复合铝板是指以铝波纹板为芯材&#xff0c;双面粘接铝板的复合板材&#xff0c;如下图所示&#xff0c;铝波纹芯复合板具有轻质&#xff0c;环保&#xff0c;吸音&#xff0c;隔热&#xff0c;防火等性能&#xff0c;被广泛应用于机场&#xff0c;医院&#xff0c;体育…...

数字乡村综合管理与服务平台软件需求规格说明文档

数字乡村综合管理与服务平台 软件需求规格文档 文件版本&#xff1a;1.3 版本 文件状态&#xff1a;修改完成 文件作者&#xff1a;7组全体成员 完成日期&#xff1a;2025年5月7日 文章目录 a. 引言a.1 目的a.2 文档约定a.3 预期读者与涉众分析a.4 产品的范围a.5 参考文献…...

Linux常用命令33——sudo授权普通用户执行管理员命令

在使用Linux或macOS日常开发中&#xff0c;熟悉一些基本的命令有助于提高工作效率&#xff0c;sudo命令来自英文词组super user do的缩写&#xff0c;中文译为“超级用户才能干的事”&#xff0c;其功能是授权普通用户执行管理员命令。使用su命令变更用户身份虽然好用&#xff…...

Redis--哈希类型

目录 一、Hash 哈希 1.2 常用命令 1.2.1 HSET 1.2.2 HGET 1.2.3 HEXISTS 1.2.4 HDEL 1.2.5 HKEYS 1.2.6 HVALS 1.2.7 HGETALL 1.2.8 HMGET 1.2.9 HLEN 1.2.10 HSETNX 1.2.11 HINCRBY 1.2.12 HINCRBYFLOAT 1.3 内部编码 一、Hash 哈希 几乎所有的主流编程语言都提…...

数据结构——排序(万字解说)初阶数据结构完

目录 1.排序 2.实现常见的排序算法 2.1 直接插入排序 ​编辑 2.2 希尔排序 2.3 直接选择排序 2.4 堆排序 2.5 冒泡排序 2.6 快速排序 2.6.1 递归版本 2.6.1.1 hoare版本 2.6.1.2 挖坑法 2.6.1.3 lomuto前后指针 2.6.1.4 时间复杂度 2.6.2 非递归版本 2.7 归并排序…...

东方泵业,室外消火栓泵 2#故障灯亮,报警生响

东方泵业&#xff0c;室外消火栓泵 2#故障&#xff0c; 图纸上显示有一个热继电器&#xff0c;过热了&#xff0c;然后它不会自动复位&#xff0c;需要手动复位&#xff0c;手动点一下那个蓝色的按钮&#xff0c;然后警报就解除了...

vue3:十二、图形看板- 基础准备+首行列表项展示

文章主要实现了看板页面的搭建;将看板页面加入左侧菜单;首行列表项的实现 一、效果展示 展示四个数据列表,四个列表颜色各不相同,列表左侧有颜色边线(同标题颜色、图标颜色一致);展示的数字有一个从0到当前数据逐渐增长的一个动画效果 二、图形看板的准备工作 1、创建视…...

基于开源链动2+1模式AI智能名片S2B2C商城小程序的分销价格管控机制研究

摘要&#xff1a;本文聚焦开源链动21模式AI智能名片S2B2C商城小程序在分销体系中的价格管控机制&#xff0c;通过解析其技术架构与商业模式&#xff0c;揭示平台如何通过"去中心化裂变中心化管控"双轨机制实现价格统一。研究显示&#xff0c;该模式通过区块链存证技术…...

指定Docker镜像源,使用阿里云加速异常解决

yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo异常贴图 yum-config-manager&#xff1a;找不到命令 因为系统默认没有安装这个命令&#xff0c;这个命令在yum-utils 包里&#xff0c;可以通过命令yum -y install yum-util…...

java基础-数组

1.数组的声明和初始化&#xff1a; &#xff08;1&#xff09;静态初始化&#xff1a; import java.util.Arrays;public class Main {public static void main(String[] args) {int[] ids {1,2,3,4,5};System.out.println(Arrays.toString(ids));} } &#xff08;2&#xf…...

CSS手动布局

CSS支持单独设置某个元素的布局&#xff0c;最主要的属性是 position &#xff0c;它有以下几个值&#xff1a; static静态位置&#xff08;默认值&#xff09;。元素采用正常流布局&#xff0c;此时元素的位置偏移属性&#xff08; top 、 right 、 bottom 、 left 和 z-inde…...

什么是智能合约?区块链上的自动化契约

智能合约是运行在区块链上的计算机程序或交易协议。与传统的纸质合同不同&#xff0c;智能合约将合同条款直接编码到程序中&#xff0c;并在满足预设条件时自动执行。它们旨在实现无需第三方介入的可信交易&#xff0c;具有自动化、透明、不可篡改和高效等特点。 智能合约的起…...

webRtc之指定摄像头设备绿屏问题

摘要&#xff1a;最近发现&#xff0c;在使用navigator.mediaDevices.getUserMedia({ deviceId: ‘xxx’}),指定设备的时候&#xff0c;video播放总是绿屏&#xff0c;发现关闭浏览器硬件加速不会出现&#xff0c;但显然这不是一个最好的方案; 播放后张这样 修复后 上代码 指定…...

正则表达式非捕获分组?:

一个使用 Java 正则表达式的具体例子&#xff0c;展示了 (ab) 和 (?:ab) 的不同&#xff1a; 示例 1&#xff1a;使用 (ab)&#xff08;捕获分组&#xff09; import java.util.regex.*; public class RegexExample { public static void main(String[] args) { …...

Linux系统Shell脚本之shell数组、正则表达式、及AWK

目录 一.shell数组 1.数组分类 2.定义数组的方法 二.正则表达式 1. 元字符 2.表示次数 3.位置锚定 4.分组 5.扩展正则表达式 三.文本三剑客之AWK 1.awk 2.使用格式 3、处理动作 4.选项 5.处理模式 6.awk常见的内置变量 7.if条件判断 一.shell数组 1.数组分类 …...

在 ESP-IDF 中使用 .a 静态库调用

1. 准备静态库文件 将你的 .a 文件&#xff08;如 libmylib.a&#xff09;放置在工程目录中&#xff0c;推荐放在 components 子目录下&#xff1a; your_project/ ├── CMakeLists.txt ├── main/ └── components/└── my_lib/├── include/ # 头文件│ …...

​​大疆无人机“指点飞行模式”​​(TapFly)

在大疆无人机的功能中&#xff0c;​​“指点飞行模式”​​&#xff08;TapFly&#xff09;是一种​​通过点击屏幕目标点&#xff0c;让无人机自动规划路径并飞向指定位置​​的智能飞行模式。用户无需手动操控摇杆&#xff0c;只需在 App 地图或实时画面上点击目标位置&…...

力扣 : 781. 森林中的兔子

781. 森林中的兔子 - 力扣&#xff08;LeetCode&#xff09; 同一个数字的可以分为一组 &#xff0c; 3就是有3个人和我自己相同 也就是4个人&#xff0c;所以相同的数字可以分为 / (num1) 向上取整 class Solution { public:int numRabbits(vector<int>& answer…...

LVS中的DR模式,直接路由模式

DR模式工作原理介绍 请求经过调度器&#xff0c;响应由real server 直接响应给客户端。 如上图所示&#xff0c;real server想要正常访问互联网&#xff0c;后端的real server的网关就得写网络中真实的网关。 DR模式的核心要素&#xff1a;【重点】 1.请求经过调度器&…...

iTwin 数据报表(只是简单的原型不代表实现)

大概想法是 前端从schema和class中选中感兴趣的property内容生成ecsql语句传递给后端后端解析ecsql并提供公开接口给各个分析工具&#xff0c;如excel&#xff0c;poewerBI等&#xff08;Odata或者直接选择来自网站&#xff09;再由分析工具做进一步的处 还未想好的点 如何存…...

【无标题】如何在sheel中运行Spark

启动hdfs集群&#xff0c;打开hadoop100:9870&#xff0c;在wcinput目录下上传一个包含很多个单词的文本文件。 启动之后在spark-shell中写代码。 // 读取文件&#xff0c;得到RDD val rdd1 sc.textFile("hdfs://hadoop100:8020/wcinput/words.txt") // 将单词进行…...

Spark 处理过程转换:算子与行动算子详解

在大数据处理领域&#xff0c;Apache Spark 凭借其强大的分布式计算能力脱颖而出&#xff0c;成为处理海量数据的利器。而 Spark 的核心处理过程&#xff0c;主要通过转换算子和行动算子来实现。本文将深入探讨 Spark 中的转换算子和行动算子&#xff0c;帮助读者更好地理解和应…...

Docker编排工具---Compose的概述及使用

目录 一、Compose工具的概述 二、Compose的常用命令 1、列出容器 2、查看访问日志 3、输出绑定的公共端口 4、重新构建服务 5、启动服务 6、停止服务 7、删除已停止服务的容器 8、创建和启动容器 9、在运行的容器中执行命令 10、指定一个服务启动容器的个数 11、其…...

Matlab实现绘制任意自由曲线

Matlab实现绘制任意自由曲线&#xff0c;实现Photoshop中的钢笔路径功能&#xff0c;用光顺连接的B样条/贝塞尔曲线实现&#xff0c;鼠标点击生成控制点&#xff0c;拖动形成任意曲线。 可描绘多路径&#xff0c;也可旋转、平移、缩放。经调试可用。 ByangtiaoSculpt/Byangti…...

如何保证Kafka生产者的消息顺序性? (单分区内有序,需确保同一Key的消息发送到同一分区)

Kafka 生产者消息顺序性保障方案 1. 核心实现原理 消息顺序性保障公式&#xff1a; 同一 Key → 同一 Partition → 严格顺序写入2. 关键配置参数 Properties props new Properties(); props.put("acks", "all"); // 确保消息持久化 props.put("ma…...

[D1,2] 贪心刷题

文章目录 摆动序列最大子数组合买卖股票跳跃游戏跳跃2 摆动序列 不像是贪心&#xff0c;只要抓住摆动这个点&#xff0c;前一个上升&#xff0c;那下一个就要下降&#xff0c;记录上一次的状态为1的话&#xff0c;那下一次就要更新为-1&#xff0c;如果上一次为1&#xff0c;这…...