Python-OpenCV中的图像处理
Python-OpenCV中的图像处理
- 颜色空间转换
- 物体跟踪
- 获取HSV的值
- 几何变换
- 图像缩放
- 图像平移
- 图像旋转
- 仿射变换
- 透视变换
- 图像阈值
- 单阈值
- 自适应阈值
- Otsu's二值化
颜色空间转换
在 OpenCV 中有超过 150 中进行颜色空间转换的方法。但是你以后就会
发现我们经常用到的也就两种: BGR G r a y 和 B G R Gray 和 BGR Gray和BGRHSV。
注意:在 OpenCV 的 HSV 格式中, H(色彩/色度)的取值范围是 [0, 179],
S(饱和度)的取值范围 [0, 255], V(亮度)的取值范围 [0, 255]。但是不
同的软件使用的值可能不同。所以当你需要拿 OpenCV 的 HSV 值与其他软
件的 HSV 值进行对比时,一定要记得归一化。
- cv2.cvtColor(img, flag)
- cv2.inRange()
import numpy as np
import cv2
from matplotlib import pyplot as pltimg1 = cv2.imread('./resource/image/opencv-logo.png', cv2.IMREAD_COLOR)
img2 = cv2.imread('./resource/image/opencv-logo.png', cv2.IMREAD_COLOR)
gray = cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY)
hsv = cv2.cvtColor(img1, cv2.COLOR_BGR2HSV)
rgb = cv2.cvtColor(img1, cv2.COLOR_BGR2RGB)imgh = np.hstack((img1, img2))
imgv = np.vstack((img1, img2))
cv2.imshow('hsv', hsv)
cv2.imshow('gray', gray)plt.subplot(221), plt.imshow(imgh), plt.title('hstack')
plt.subplot(222), plt.imshow(imgv), plt.title('vstack')
plt.subplot(223), plt.imshow(hsv), plt.title('hsv')
plt.subplot(224), plt.imshow(gray), plt.title('gray')
plt.show()

物体跟踪
现在我们知道怎样将一幅图像从 BGR 转换到 HSV 了,我们可以利用这
一点来提取带有某个特定颜色的物体。在 HSV 颜色空间中要比在 BGR 空间
中更容易表示一个特定颜色。在我们的程序中,我们要提取的是一个蓝色的物
体。下面就是就是我们要做的几步:
• 从视频中获取每一帧图像
• 将图像转换到 HSV 空间
• 设置 HSV 阈值到蓝色范围。
• 获取蓝色物体,当然我们还可以做其他任何我们想做的事,比如:在蓝色
物体周围画一个圈。
import numpy as np
import cv2# cv2.cvtColor(img, flag)
# cv2.inRange()# 打印颜色转换flag
flags =[ i for i in dir(cv2) if i.startswith('COLOR_')]
print(flags)# OpenCV支持超过150种颜色转换的方法,常用:BGR<->GRAY 和 BGR<->HSV
# OpenCV的HSV格式中,H(色彩/色度)的取值范围是[0, 179], S(饱和度)的取值范围[0, 255], V(亮度)的取值范围[0, 255]
# 不同软件取值范围可能不同,使用时需要做归一化# 物体跟踪,跟踪一个蓝色物体,步骤:
# 1.从视频中获取一帧图像
# 2.将图像转换到HSV空间
# 3.设置HSV阀值到蓝色范围
# 4.获取蓝色物体,或其他处理cap = cv2.VideoCapture(0)while True:# 获取图像帧(ret, frame) = cap.read()# 转换到HSV颜色空间hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)# 设定蓝色的阀值lower_blue = np.array([110, 50, 50])upper_blue = np.array([130, 255, 255])# 根据阀值构建掩膜mask = cv2.inRange(hsv, lower_blue, upper_blue)mask_blue = cv2.medianBlur(mask, 7) # 中值滤波# 查找轮廓contours, hierarchy = cv2.findContours(mask_blue, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)# print(contours, hierarchy)for cnt in contours:(x, y, w, h) = cv2.boundingRect(cnt)cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2)font = cv2.FONT_HERSHEY_SIMPLEXcv2.putText(frame, "Blue", (x, y - 5), font, 0.7, (0, 255, 0), 2)# 对原图和掩膜进行位运算res =cv2.bitwise_and(frame, frame, mask=mask)# 显示图像cv2.imshow('frame', frame)cv2.imshow('mask', mask)cv2.imshow('res', res)k = cv2.waitKey(5)&0xFFif k == 27:breakcap.release()
cv2.destroyAllWindows()

获取HSV的值
import numpy as np
import cv2blue = np.uint8([[[255, 0, 0]]])
hsv_blue = cv2.cvtColor(blue, cv2.COLOR_BGR2HSV)
print('blue bgr:', blue)
print('blue hsv:', hsv_blue)green = np.uint8([[[0,255,0]]])
hsv_green = cv2.cvtColor(green, cv2.COLOR_BGR2HSV)
print('green bgr:', green)
print('green hsv:', hsv_green)red = np.uint8([[[0,0,255]]])
hsv_red = cv2.cvtColor(red, cv2.COLOR_BGR2HSV)
print('red bgr:',red)
print('red hsv:',hsv_red)
blue bgr: [[[255 0 0]]]
blue hsv: [[[120 255 255]]]
green bgr: [[[ 0 255 0]]]
green hsv: [[[ 60 255 255]]]
red bgr: [[[ 0 0 255]]]
red hsv: [[[ 0 255 255]]]
几何变换
对图像进行各种几个变换,例如移动,旋转,仿射变换等。
图像缩放
- cv2.resize()
- cv2.INTER_AREA
- v2.INTER_CUBIC
- v2.INTER_LINEAR
res = cv2.resize(img, None, fx=2, fy=2, interpolation=cv2.INTER_CUBIC)
或
height, width = img.shape[:2]
res = cv2.resize(img, (2width, 2height), interpolation=cv2.INTER_CUBIC)
import numpy as np
import cv2# 图像缩放
img = cv2.imread('./resource/image/1.jpg')# 缩放 时推荐使用cv2.INTER_AREA
# 扩展 时推荐使用cv2.INTER_CUBIC(慢) 或 cv2.INTER_LINEAR(默认使用)
# 原图放大两倍
res = cv2.resize(img, None, fx=2, fy=2, interpolation=cv2.INTER_CUBIC)# 或
#height, width = img.shape[:2]
#res = cv2.resize(img, (2*width, 2*height), interpolation=cv2.INTER_CUBIC)while True:cv2.imshow('res', res)cv2.imshow('img', img)if cv2.waitKey(1)&0xFF == 27:break
cv2.destroyAllWindows()
图像平移
OpenCV提供了使用函数cv2.warpAffine()实现图像平移效果,该函数的语法为
- cv2.warpAffine(src, M, (cols, rows))
- src:输入的源图像
- M:变换矩阵,即平移矩阵,M = [[1, 0, tx], [0, 1, ty]] 其中,tx和ty分别代表在x和y方向上的平移距离。
- (cols, rows):输出图像的大小,即变换后的图像大小
平移就是将对象换一个位置。如果你要沿( x, y)方向移动,移动的距离
是( tx, ty),你可以以下面的方式构建移动矩阵:
M = [ 1 0 t x 0 1 t y ] M=\left[ \begin{matrix} 1&0&t_x\\ 0 &1 &t_y \end{matrix} \right] M=[1001txty]
import cv2
import numpy as npimg = cv2.imread('./resource/opencv/image/messi5.jpg')# 获取图像的行和列
rows, cols = img.shape[:2]# 定义平移矩阵,沿着y轴方向向下平移100个像素点
# M = np.float32([[1, 0, 0], [0, 1, 100]])# 定义平移矩阵,沿着x轴方向向右平移50个像素点,沿着y轴方向向下平移100个像素点
M = np.float32([[1, 0, -50], [0 ,1, 100]])# 执行平移操作
result = cv2.warpAffine(img, M, (cols, rows))# 显示结果图像
cv2.imshow('result', result)
cv2.waitKey(0)

图像旋转
- cv2.getRotationMatrix2D()
对一个图像旋转角度 θ, 需要使用到下面形式的旋转矩阵:
M = [ c o s θ − s i n θ s i n θ c o s θ ] M=\left[ \begin{matrix} cosθ&-sinθ \\sinθ&cosθ \end{matrix} \right] M=[cosθsinθ−sinθcosθ]
import numpy as np
import cv2# 图像旋转 缩放
img = cv2.imread('./resource/opencv/image/messi5.jpg', cv2.IMREAD_GRAYSCALE)
rows,cols = img.shape# 这里的第一个参数为旋转中心,第二个为旋转角度,第三个为旋转后的缩放因子
# 可以通过设置旋转中心,缩放因子,以及窗口大小来防止旋转后超出边界的问题
M = cv2.getRotationMatrix2D((cols/2, rows/2), 45, 0.6)
print(M)# 第三个参数是输出图像的尺寸中心
dst = cv2.warpAffine(img, M, (2*cols, 2*rows))
while (1):cv2.imshow('img', dst)if cv2.waitKey(1)&0xFF == 27:break
cv2.destroyAllWindows()

dst = cv2.warpAffine(img, M, (1cols, 1rows))

仿射变换
在仿射变换中,原图中所有的平行线在结果图像中同样平行。为了创建这
个矩阵我们需要从原图像中找到三个点以及他们在输出图像中的位置。然后
cv2.getAffineTransform 会创建一个 2x3 的矩阵,最后这个矩阵会被传给
函数 cv2.warpAffine。
import numpy as np
import cv2
from matplotlib import pyplot as plt# 仿射变换
img = cv2.imread('./resource/opencv/image/messi5.jpg', cv2.IMREAD_COLOR)
rows, cols, ch = img.shape
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGBA)pts1 = np.float32([[50,50],[200,50],[50,200]])
pts2 = np.float32([[10,100], [200,50], [100,250]])# 行,列,通道数
M = cv2.getAffineTransform(pts1, pts2)
dts = cv2.warpAffine(img, M, (cols, rows))plt.subplot(121), plt.imshow(img), plt.title('Input')
plt.subplot(122), plt.imshow(dts), plt.title('Output')
plt.show()

透视变换
对于视角变换,我们需要一个 3x3 变换矩阵。在变换前后直线还是直线。
要构建这个变换矩阵,你需要在输入图像上找 4 个点,以及他们在输出图
像上对应的位置。这四个点中的任意三个都不能共线。这个变换矩阵可以有
函数 cv2.getPerspectiveTransform() 构建。然后把这个矩阵传给函数
cv2.warpPerspective()
import numpy as np
import cv2
from matplotlib import pyplot as plt# 透视变换
img = cv2.imread('./resource/opencv/image/sudoku.png', cv2.IMREAD_COLOR)
rows,cols,ch = img.shape
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)pts1 = np.float32([[60,80],[368,65],[28,387],[389,390]])
pts2 = np.float32([[0,0],[300,0],[0,300],[300,300]])M = cv2.getPerspectiveTransform(pts1, pts2)
dst = cv2.warpPerspective(img, M, (400, 400))plt.subplot(121), plt.imshow(img), plt.title('Input')
plt.subplot(122), plt.imshow(dst), plt.title('Output')
plt.show()

图像阈值
单阈值
与名字一样,这种方法非常简单。但像素值高于阈值时,我们给这个像素
赋予一个新值(可能是白色),否则我们给它赋予另外一种颜色(也许是黑色)。这个函数就是 cv2.threshhold()。这个函数的第一个参数就是原图像,原图像应该是灰度图。第二个参数就是用来对像素值进行分类的阈值。第三个参数
就是当像素值高于(有时是小于)阈值时应该被赋予的新的像素值。 OpenCV
提供了多种不同的阈值方法,这是有第四个参数来决定的。这些方法包括:
- cv2.THRESH_BINARY
- cv2.THRESH_BINARY_INV
- cv2.THRESH_TRUNC
- cv2.THRESH_TOZERO
- cv2.THRESH_TOZERO_INV
import numpy as np
import cv2
from matplotlib import pyplot as plt# 单阈值
img = cv2.imread('./resource/opencv/image/colorscale_bone.jpg', cv2.IMREAD_GRAYSCALE)ret,thresh1 = cv2.threshold(img, 127, 255, cv2.THRESH_BINARY)
ret,thresh2 = cv2.threshold(img, 127, 255, cv2.THRESH_BINARY_INV)
ret,thresh3 = cv2.threshold(img, 127, 255, cv2.THRESH_TRUNC)
ret,thresh4 = cv2.threshold(img, 127, 255, cv2.THRESH_TOZERO)
ret,thresh5 = cv2.threshold(img, 127, 255, cv2.THRESH_TOZERO_INV)titles = ['original', 'binary', 'binary-inv', 'trunc', 'tozero', 'tozero-inv']
images = [img, thresh1, thresh2, thresh3, thresh4, thresh5]for i in range(6):plt.subplot(2,3,i+1), plt.imshow(images[i], 'gray'),plt.title(titles[i])plt.xticks([]),plt.yticks([])plt.show()

自适应阈值
在前面的部分我们使用是全局阈值,整幅图像采用同一个数作为阈值。当
时这种方法并不适应与所有情况,尤其是当同一幅图像上的不同部分的具有不
同亮度时。这种情况下我们需要采用自适应阈值。此时的阈值是根据图像上的
每一个小区域计算与其对应的阈值。因此在同一幅图像上的不同区域采用的是
不同的阈值,从而使我们能在亮度不同的情况下得到更好的结果。
这种方法需要我们指定三个参数,返回值只有一个。
- Adaptive Method- 指定计算阈值的方法。
– cv2.ADPTIVE_THRESH_MEAN_C:阈值取自相邻区域的平
均值
– cv2.ADPTIVE_THRESH_GAUSSIAN_C:阈值取值相邻区域
的加权和,权重为一个高斯窗口。 - Block Size - 邻域大小(用来计算阈值的区域大小)。
- C - 这就是是一个常数,阈值就等于的平均值或者加权平均值减去这个常
数。
import numpy as np
import cv2
from matplotlib import pyplot as plt# 自适应阀值
img = cv2.imread('./resource/opencv/image/sudoku.png', cv2.IMREAD_GRAYSCALE)# 中值滤波
img = cv2.medianBlur(img, 5)(ret, th1) = cv2.threshold(img, 127, 255, cv2.THRESH_BINARY)# 自适应阀值 11 为block size, 2为C值
th2 = cv2.adaptiveThreshold(img, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 11, 2)
th3 = cv2.adaptiveThreshold(img, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 11, 2)titles = ['original image', 'global thresholding(v=127)', 'Adaptive mean thresholding', 'adaptive gaussian thresholding']
images =[img, th1, th2, th3]for i in range(4):plt.subplot(2,2,i+1), plt.imshow(images[i], 'gray')plt.title(titles[i])plt.xticks([]), plt.yticks([])plt.show()

Otsu’s二值化
在使用全局阈值时,我们就是随便给了一个数来做阈值,那我们怎么知道
我们选取的这个数的好坏呢?答案就是不停的尝试。如果是一副双峰图像(简
单来说双峰图像是指图像直方图中存在两个峰)呢?我们岂不是应该在两个峰
之间的峰谷选一个值作为阈值?这就是 Otsu 二值化要做的。简单来说就是对
一副双峰图像自动根据其直方图计算出一个阈值。(对于非双峰图像,这种方法
得到的结果可能会不理想)。
这里用到到的函数还是 cv2.threshold(),但是需要多传入一个参数
( flag): cv2.THRESH_OTSU。这时要把阈值设为 0。然后算法会找到最
优阈值,这个最优阈值就是返回值 retVal。如果不使用 Otsu 二值化,返回的
retVal 值与设定的阈值相等。
下面的例子中,输入图像是一副带有噪声的图像。第一种方法,我们设
127 为全局阈值。第二种方法,我们直接使用 Otsu 二值化。第三种方法,我
们首先使用一个 5x5 的高斯核除去噪音,然后再使用 Otsu 二值化。看看噪音
去除对结果的影响有多大吧。
import numpy as np
import cv2
from matplotlib import pyplot as pltimg = cv2.imread('./resource/opencv/image/Template_Matching_Correl_Result_2.jpg', cv2.IMREAD_GRAYSCALE)(ret1,th1) = cv2.threshold(img, 127, 255, cv2.THRESH_BINARY)
(ret2,th2) = cv2.threshold(img, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)# (5,5)为高斯核的大小,0为标准差
blur = cv2.GaussianBlur(img, (5,5), 0) # 高斯滤波# 阀值一定要设为0
(ret3, th3) = cv2.threshold(blur, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)images = [img, 0, th1,img, 0, th2,img, 0, th3]
titles = ['original noisy image', 'histogram', 'global thresholding(v=127)','original noisy image','histogram',"otsu's thresholding",'gaussian giltered image','histogram',"otus's thresholding"]for i in range(3):plt.subplot(3,3,i*3+1), plt.imshow(images[i*3], 'gray')plt.title(titles[i*3]), plt.xticks([]), plt.yticks([])plt.subplot(3,3,i*3+2),plt.hist(images[i*3].ravel(),256)plt.title(titles[i*3+1]),plt.xticks([]),plt.yticks([])plt.subplot(3,3,i*3+3),plt.imshow(images[i*3+2],'gray')plt.title(titles[i*3+2]),plt.xticks([]),plt.yticks([])
plt.show()

相关文章:
Python-OpenCV中的图像处理
Python-OpenCV中的图像处理 颜色空间转换物体跟踪获取HSV的值几何变换图像缩放图像平移图像旋转仿射变换透视变换 图像阈值单阈值自适应阈值Otsus二值化 颜色空间转换 在 OpenCV 中有超过 150 中进行颜色空间转换的方法。但是你以后就会 发现我们经常用到的也就两种࿱…...
分清性能测试,负载测试,压力测试这三个的区别
做测试一年多来,虽然平时的工作都能很好的完成,但最近突然发现自己在关于测试的整体知识体系上面的了解很是欠缺,所以,在工作之余也做了一些测试方面的知识的补充。不足之处,还请大家多多交流,互相学习。 …...
前端架构师岗位的工作职责(合集)
前端架构师岗位的工作职责1 职责: 1.制定前端的标准和规范,并推广和应用,提高团队的开发效率; 2.前端架构的框架或核心模块的设计与实现; 3.在前端架构、设计与开发上对团队进行足够的指导; 4.在日常的系统设计与优化上与服务端团队紧密合…...
使用 Amazon ECS Anywhere 在边缘部署 Amazon IoT Greengrass
1.概述 亚马逊云科技提供了完备的IoT服务能力,涵盖设备服务、连接和控制服务以及云端分析服务,是快速构建安全可靠、可扩展的 IoT 平台的常见选择。Amazon IoT Greengrass 边缘运行时和云服务,可帮助您在设备上构建、部署和管理 IoT 应用。A…...
pytorch Stream 多流处理
CUD Stream https://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html#c-language-extensions 中指出在kenel的调用函数中最后一个可选参数表示该核函数处在哪个流之中。 - 参数Dg用于定义整个grid的维度和尺寸,即一个grid有多少个block。为dim3类型。…...
微信小程序选项卡切换(滑动切换,点击切换)
效果如下:可点击切换,滑动切换 代码如下 这个可以在项目用 index.wxml <view classtopTabSwiper><view classtab {{currentData 0 ? "tabBorer" : ""}} data-current "0" bindtapcheckCurrent>选项一&…...
安路FPGA的赋值报错——移位处理,加括号
authordaisy.skye的博客_CSDN博客-嵌入式,Qt,Linux领域博主 在使用移位符号用来当作除以号使用时,发现如下问题 其中 cnt_8K 为偶数和奇数时输出的数据不一样 reg [10:0] cnt_8K; reg [10:0] ram1_addra; always(posedge clk_16M) begin if(ram_out_flag )begin if(…...
GO学习之 接口(Interface)
GO系列 1、GO学习之Hello World 2、GO学习之入门语法 3、GO学习之切片操作 4、GO学习之 Map 操作 5、GO学习之 结构体 操作 6、GO学习之 通道(Channel) 7、GO学习之 多线程(goroutine) 8、GO学习之 函数(Function) 9、GO学习之 接口(Interface) 文章目录 GO系列前言一、什么是…...
ansible常见模块的运用
ansible常见模块的运用 一:Ansible简介二:ansible 环境安装部署管理端安装 ansibleansible 目录结构配置主机清单配置密钥对验证 三:ansible 命令行模块1.command 模块在远程主机执行命令,不支持管道,重定向…...
合宙Air724UG LuatOS-Air script lib API--patch
patch Table of Contents patch patch.safeJsonDecode(s) (local函数 无法被外部调用) patch 模块功能:Lua补丁 patch.safeJsonDecode(s) (local函数 无法被外部调用) 封装自定义的json.decode接口 参数 名称 传入值类型 释义 s string json格式的字符串 返回值 t…...
pytorch求导
pytorch求导的初步认识 requires_grad tensor(data, dtypeNone, deviceNone, requires_gradFalse)requires_grad是torch.tensor类的一个属性。如果设置为True,它会告诉PyTorch跟踪对该张量的操作,允许在反向传播期间计算梯度。 x.requires_grad 判…...
Java基础异常详解
Java基础异常详解 文章目录 Java基础异常详解编译时异常(Checked Exception):运行时异常(Unchecked Exception): Java中的异常是用于处理程序运行时出现的错误或异常情况的一种机制。 异常本身也是一个类。 异常分为…...
vue3+vue-i18n 监听语言的切换
最近在用 vue3 做一个后台管理系统,之前是只考虑中文,现在加了个需求是多语言。 本来也不是太难的需求,但是我用的并不熟悉,并且除了页面展示不同的语言,需求是在切换语言的时候在几个页面中需要做出一些自定义的行为&…...
【考研复习】24王道数据结构课后习题代码|2.3线性表的链式表示
文章目录 总结01 递归删除结点02 删除结点03 反向输出04 删除最小值05 逆置06 链表递增排序07 删除区间值08 找公共结点09 增序输出链表10 拆分链表--尾插11 拆分链表--头插12 删除相同元素13 合并链表14 生成含有公共元素的链表C15 求并集16 判断子序列17 判断循环链表是否对称…...
娇滴滴的一朵花(Python实现)
目录 1 娇滴滴的她 2 Python代码实现 1 娇滴滴的她 娇滴滴。双眉敛破春山色。春山色。 为君含笑,为君愁蹙。多情别後无消息。 此时更有谁知得。谁知得。夜深无寐,度江横笛。 2 Python代码实现 import turtle from turtle import * turtle.title(春天送她一朵小花)…...
Android AccessibilityService研究
AccessibilityService流程分析 AccessibilityService开启方式AccessibilityService 开启原理 AccessibilityService开启方式 . 在Framework里直接添加对应用app 服务component。 loadSetting(stmt, Settings.Secure.ACCESSIBILITY_ENABLED,1); loadSetting(stmt, Settings.Se…...
华为OD机试(含B卷)真题2023 算法分类版,58道20个算法分类,如果距离机考时间不多了,就看这个吧,稳稳的
目录 一、数据结构1、线性表2、优先队列3、滑动窗口4、二叉树5、并查集6、栈 二、算法1、基础算法2、字符串3、图4、动态规划5、数学 三、漫画算法2:小灰的算法进阶参与方式 很多小伙伴问我,华为OD机试算法题太多了,知识点繁杂,如…...
JMeter命令行执行+生成HTML报告
1、为什么用命令行模式 使用GUI方式启动jmeter,运行线程较多的测试时,会造成内存和CPU的大量消耗,导致客户机卡死; 所以一般采用的方式是在GUI模式下调整测试脚本,再用命令行模式执行; 命令行方式支持在…...
学习Boost二:从附录3来看编码习惯
附录C 关键字浅谈 在C11标准中(C11.2.12)总共定义了73个关键字(keyword)、2个“准”关键字(identifiers with special meaning)和11个操作符替代字(alternative representation)[1]。…...
STM32基础入门学习笔记:核心板 电路原理与驱动编程
文章目录: 一:LED灯操作 1.LED灯的点亮和熄灭 延迟闪烁 main.c led.c led.h BitAction枚举 2.LED呼吸灯(灯的强弱交替变化) main.c delay.c 3.按键控制LED灯 key.h key.c main.c 二:FLASH读写程序(有…...
内存分配函数malloc kmalloc vmalloc
内存分配函数malloc kmalloc vmalloc malloc实现步骤: 1)请求大小调整:首先,malloc 需要调整用户请求的大小,以适应内部数据结构(例如,可能需要存储额外的元数据)。通常,这包括对齐调整,确保分配的内存地址满足特定硬件要求(如对齐到8字节或16字节边界)。 2)空闲…...
Day131 | 灵神 | 回溯算法 | 子集型 子集
Day131 | 灵神 | 回溯算法 | 子集型 子集 78.子集 78. 子集 - 力扣(LeetCode) 思路: 笔者写过很多次这道题了,不想写题解了,大家看灵神讲解吧 回溯算法套路①子集型回溯【基础算法精讲 14】_哔哩哔哩_bilibili 完…...
Cinnamon修改面板小工具图标
Cinnamon开始菜单-CSDN博客 设置模块都是做好的,比GNOME简单得多! 在 applet.js 里增加 const Settings imports.ui.settings;this.settings new Settings.AppletSettings(this, HTYMenusonichy, instance_id); this.settings.bind(menu-icon, menu…...
Spring是如何解决Bean的循环依赖:三级缓存机制
1、什么是 Bean 的循环依赖 在 Spring框架中,Bean 的循环依赖是指多个 Bean 之间互相持有对方引用,形成闭环依赖关系的现象。 多个 Bean 的依赖关系构成环形链路,例如: 双向依赖:Bean A 依赖 Bean B,同时 Bean B 也依赖 Bean A(A↔B)。链条循环: Bean A → Bean…...
VM虚拟机网络配置(ubuntu24桥接模式):配置静态IP
编辑-虚拟网络编辑器-更改设置 选择桥接模式,然后找到相应的网卡(可以查看自己本机的网络连接) windows连接的网络点击查看属性 编辑虚拟机设置更改网络配置,选择刚才配置的桥接模式 静态ip设置: 我用的ubuntu24桌…...
c++第七天 继承与派生2
这一篇文章主要内容是 派生类构造函数与析构函数 在派生类中重写基类成员 以及多继承 第一部分:派生类构造函数与析构函数 当创建一个派生类对象时,基类成员是如何初始化的? 1.当派生类对象创建的时候,基类成员的初始化顺序 …...
密码学基础——SM4算法
博客主页:christine-rr-CSDN博客 专栏主页:密码学 📌 【今日更新】📌 对称密码算法——SM4 目录 一、国密SM系列算法概述 二、SM4算法 2.1算法背景 2.2算法特点 2.3 基本部件 2.3.1 S盒 2.3.2 非线性变换 编辑…...
echarts使用graphic强行给图增加一个边框(边框根据自己的图形大小设置)- 适用于无法使用dom的样式
pdf-lib https://blog.csdn.net/Shi_haoliu/article/details/148157624?spm1001.2014.3001.5501 为了完成在pdf中导出echarts图,如果边框加在dom上面,pdf-lib导出svg的时候并不会导出边框,所以只能在echarts图上面加边框 grid的边框是在图里…...
路由基础-路由表
本篇将会向读者介绍路由的基本概念。 前言 在一个典型的数据通信网络中,往往存在多个不同的IP网段,数据在不同的IP网段之间交互是需要借助三层设备的,这些设备具备路由能力,能够实现数据的跨网段转发。 路由是数据通信网络中最基…...
【Redis】Redis从入门到实战:全面指南
Redis从入门到实战:全面指南 一、Redis简介 Redis(Remote Dictionary Server)是一个开源的、基于内存的键值存储系统,它可以用作数据库、缓存和消息代理。由Salvatore Sanfilippo于2009年开发,因其高性能、丰富的数据结构和广泛的语言支持而广受欢迎。 Redis核心特点:…...
