02- OpenCV绘制图形及图像算术变换 (OpenCV基础) (机器视觉)
知识重点
- OpenCV用的最多的色彩空间是HSV. 方便OpenCV做图像处理
- img2 = img.view() # 浅拷贝
- img3 = img.copy() # 深拷贝
- split(mat) 分割图像的通道: b, g, r = cv2.split(img) # b, g, r 都是数组
- merge((ch1, ch2, ch3)) 融合多个通道
- cvtColor(img, colorspace): 颜色转换的关键API
- cv2.line(img, pt1, pt2, color, thickness, lineType, shift) 画直线
-
cv2.rectangle() 画矩形
-
cv2.circle() 画圆
-
cv2.ellipse() 画椭圆
-
绘制中文 opencv本身不支持, 因为没有中文字体.我们可以借助pillow来实现绘制中文
-
new_img = cv2.add(new_cat, dog) 图像的加法运算, 图片大小需要一致
-
new_img = cv2.subtract(new_cat, dog) 图像的减法运算
-
cv2.imshow('img', np.hstack((new_cat, dog, new_img))) # 图片显示
-
cv2.addWeighted(src1, alpha, src2, beta, gamma) # 图像融合
-
bitwise_not(img) 非操作的效果就相当于是用 [255 - img]
2. OpenCV基础知识和绘制图形
2.1 OpenCV的色彩空间
- 最常见的色彩空间就是RGB, 人眼也是基于RGB的色彩空间去分辨颜色的.
- OpenCV默认使用的是BGR. BGR和RGB色彩空间的区别在于图片在色彩通道上的排列不同.
- 显示图片的时候需要注意适配图片的色彩空间和显示环境的色彩空间.比如传入的图片是BGR色彩空间, 显示环境是RBG空间, 就会出现颜色混乱的情况.
2.1.1 HSV, HSL和YUV
-
OpenCV用的最多的色彩空间是HSV.
-
Hue: 色相, 即色彩, 如红色, 蓝色. 用角度度量,取值范围为0°~360°,从红色开始按逆时针方向计算,红色为0°,绿色为120°,蓝色为240°
-
Saturation: 饱和度, 表示颜色接近光谱色的程度。一种颜色,可以看成是某种光谱色与白色混合的结果。其中光谱色所占的比例愈大,颜色接近光谱色的程度就愈高,颜色的饱和度也就愈高。饱和度高,颜色则深而艳。光谱色的白光成分为0,饱和度达到最高。通常取值范围为0%~100%,值越大,颜色越饱和。
-
Value: 明度. 明度表示颜色明亮的程度,对于光源色,明度值与发光体的光亮度有关;对于物体色,此值和物体的透射比或反射比有关。通常取值范围为0%(黑)到100%(白)。
为什么要使用HSV?
- 方便OpenCV做图像处理. 比如根据hue的值就可以判断背景颜色.
HSL和HSV差不多: Hue: 色相, Saturation: 饱和度, Lightness: 亮度, H(色相)完全一致, 但二者的S(饱和度)不一样, L和B(明度)也不一样 。
YUV,是一种颜色编码方法。常使用在各个视频处理组件中。 YUV在对照片或视频编码时,考虑到人类的感知能力,允许降低色度的带宽。“Y”表示明亮度,也就是灰阶值,“U”和“V”表示的则是色度,作用是描述影像色彩及饱和度,用于指定像素的颜色。最大的优点在于只需占用极少的带宽。
2.1.2 色彩空间的转换
-
cvtColor(img, colorspace): 颜色转换的关键API
import cv2
def callback(value):passcv2.namedWindow('color', cv2.WINDOW_NORMAL)
cv2.resizeWindow('mouse', 640, 480)
img = cv2.imread('./cat.jpeg')# 常见的颜色空间转换
colorspaces = [cv2.COLOR_BGR2RGBA, cv2.COLOR_BGR2BGRA, cv2.COLOR_BGR2GRAY, cv2.COLOR_BGR2HSV, cv2.COLOR_BGR2YUV]
cv2.createTrackbar('curcolor', 'color', 0, 4, callback)while True:index = cv2.getTrackbarPos('curcolor', 'color')#颜色空间转换APIcvt_img = cv2.cvtColor(img, colorspaces[index])cv2.imshow('color', cvt_img)key = cv2.waitKey(10)if key & 0xFF == ord('q'):breakcv2.destroyAllWindows()
2.2 OpenCV的重要数据结构--Mat
- Mat 是OpenCV在C++语言中用来表示图像数据的一种数据结构.在python中转化为numpy的ndarray .
- Mat由header和data组成, header中记录了图片的维数, 大小, 数据类型等数据 .
- 在python中Mat数据对应numpy的ndarray, 使用numpy提供的深浅拷贝方法即可实现Mat的拷贝
import cv2
import numpy as npimg = cv2.imread('./cat.jpeg')img2 = img.view() # 浅拷贝
img3 = img.copy() # 深拷贝
img[10:100, 10:100] = [0, 0, 255]cv2.imshow('img', img)
cv2.imshow('img2', img2)
cv2.imshow('img3', img3)cv2.waitKey(0)
cv2.destroyAllWindows()
- split(mat) 分割图像的通道: b, g, r = cv2.split(img) # b, g, r 都是数组
- merge((ch1, ch2, ch3)) 融合多个通道 .
import cv2
import numpy as npimg = np.zeros((480, 640, 3), np.uint8)
b,g,r = cv2.split(img)
b[10:100, 10:100] = 255
g[10:100, 10:100] = 255img2 = cv2.merge((b, g, r))
cv2.imshow('img', img)
cv2.imshow('b', b)
cv2.imshow('g', g)
cv2.imshow('img2', img2)cv2.waitKey(0)
cv2.destroyAllWindows()
2.3 绘制图形
利用OpenCV提供的绘制图形API可以轻松在图像上绘制各种图形, 比如直线, 矩形, 圆, 椭圆等图形.
-
cv2.line(img, pt1, pt2, color, thickness, lineType, shift) : 画直线
-
img: 在哪个图像上画线
-
pt1, pt2: 开始点, 结束点. 指定线的开始与结束位置
-
color: 颜色
-
thickness: 线宽
-
lineType: 线型.线型为-1, 4, 8, 16, 默认为8
-
shift: 坐标缩放比例 .
-
-
rectangle() 参数同上 画矩形
-
circle(img, center, radius, color[, thickness[, lineType[, shift]]]) 括号内参数表示可选参数. 画圆
-
ellipse(img, 中心点, 长宽的一半, 角度, 从哪个角度开始, 从哪个角度结束,...) 画椭圆
-
polylines(img, pts, isClosed, color[, thickness[, lineType[, shift]]]) 画多边形
-
fillPoly 填充多边形
-
putText(img, text, org, fontFace, fontScale, color[, thickness[, lineType[, bottomLeftOrigin]]]) 绘制文本
-
text 要绘制的文本
-
org 文本在图片中的左下角坐标
-
fontFace 字体类型即字体
-
fontScale 字体大小
-
import cv2
import numpy as npimg = np.zeros((480, 640, 3), np.uint8)
# cv2.line(img, (10, 20), (300, 400), (0, 0, 255), 5, 4)
# cv2.line(img, (80, 100), (380, 480), (0, 0, 255), 5, 16)# 画矩形
# cv2.rectangle(img, (10,10), (100, 100), (0, 0, 255), -1)# 画圆
# cv2.circle(img, (320, 240), 100, (0, 0, 255))
# cv2.circle(img, (320, 240), 5, (0, 0, 255), -1)# 画椭圆
# cv2.ellipse(img, (320, 240), (100, 50), 15, 0, 360, (0, 0, 255), -1)#画多边形
# pts = np.array([(300, 10), (150, 100), (450, 100)], np.int32)
# cv2.polylines(img, [pts], True, (0, 0, 255))#填充多边形
# cv2.fillPoly(img, [pts], (255, 255, 0))
cv2.putText(img, "Hello OpenCV!", (10, 400), cv2.FONT_HERSHEY_TRIPLEX, 3, (255,0,0))
cv2.imshow('draw', img)
cv2.waitKey(0)
cv2.destroyAllWindows()
- 绘制中文 opencv本身不支持, 因为没有中文字体.我们可以借助pillow来实现绘制中文
# 安装pillow
import cv2
import numpy as np
from PIL import ImageFont, ImageDraw, Imageimg = np.full((200, 200, 3), fill_value=255, dtype=np.uint8)
# 导入字体文件.
font_path = 'msyhbd.ttc'
font = ImageFont.truetype(font_path, 15)
img_pil = Image.fromarray(img)
draw = ImageDraw.Draw(img_pil)
draw.text((10, 150), '绘制中文', font=font, fill=(0, 255, 0, 0))
img = np.array(img_pil)# 中文会显示问号
cv2.putText(img, '中文', (10, 100), cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 0, 0), 1)cv2.imshow('img', img)
cv2.waitKey(0)
cv2.destroyAllWindows()
3.图像的算术与位运算
3.1 图像的算术运算
3.1.1 图像的加法运算
- add() opencv使用add来执行图像的加法运算
- 图片就是矩阵, 图片的加法运算就是矩阵的加法, 要求加法运算的两张图shape必须是相同的.
# 加法运算
import cv2
import numpy as np# 读取图片
cat = cv2.imread('./cat.jpeg')
dog = cv2.imread('./dog.jpeg')
print('原图大小:',cat.shape,dog.shape) # 原图大小: (480, 640, 3) (360, 499, 3)# 图像相加,加法操作需要两张图片大小一致,通道数一致
# 可以通过ndarray 的切片方式取出相同的形状
# 猫更大一些,从猫里面切出狗图片大小
new_cat = cat[:360, :499]
print(new_cat.shape)
new_img = cv2.add(new_cat,dog)
cv2.imshow('img', np.hstack((new_cat, dog, new_img)))# cv2.imshow('new_img:',new_img)
cv2.waitKey(0)
cv2.destroyAllWindows()
# 图片和单个数字相加进行运算
# 每个和100 进行加法运算, 超出255 的数字, 会被截断, 相当于 n% 256import cv2
dog = cv2.imread('./dog.jpeg')
dog += 10
cv2.imshow('dog', dog)cv2.waitKey(0)
cv2.destroyAllWindows()
3.1.2 图像的减法运算
-
subtract()
-
opencv使用subtract来执行减法运算, 图像对应位置的元素相减, 如果减完小于0, 统一变成0.
# 减法运算
import cv2
import numpy as np# 读取图片
cat = cv2.imread('./cat.jpeg')
dog = cv2.imread('./dog.jpeg')
print('原图大小:',cat.shape,dog.shape)# 图像相加,加法操作需要两张图片大小一致,通道数一致
# 可以通过ndarray 的切片方式取出相同的形状
# 猫更大一些,从猫里面切出狗图片大小
new_cat = cat[:360, :499]
print(new_cat.shape)# 减法 subtract
new_img = cv2.subtract(new_cat,dog)# 乘法 multiply
# new_img = cv2.multiply(new_cat,dog)# 除法 divide
# new_img = cv2.divide(new_cat,dog)cv2.imshow('img', np.hstack((new_cat, dog, new_img)))
cv2.waitKey(0)
cv2.destroyAllWindows()
3.1.3 图像的融合
-
cv2.addWeighted(src1, alpha, src2, beta, gamma)
-
图片的融合操作相当于对图片进行线性运算 w1* x1 + w2 * x2 + b. 其中alpha是第一个权重参数, beta是第二个权重参数, gamma是偏差.
# 图像的融合 不是简单的加法,相当于简单的线性运算
import cv2
import numpy as np# 读取图片
cat = cv2.imread('./cat.jpeg')
dog = cv2.imread('./dog.jpeg')new_cat = cat[0:360, 0:499]
new_img = cv2.addWeighted(new_cat, 0.3, dog, 0.8, 0)cv2.imshow('img', np.hstack((new_cat, dog, new_img)))
cv2.waitKey(0)
cv2.destroyAllWindows()
3.2 OpenCV的位运算
3.2.1 非操作
-
bitwise_not(img) 非操作的效果就相当于是用 255 - img
import cv2
import numpy as npcat = cv2.imread('./cat.jpeg')
dog = cv2.imread('./dog.jpeg')
cat = cat[:360, :499]cat_not = cv2.bitwise_not(cat)
cat_not_not = cv2.bitwise_not(cat_not)
cv2.imshow('not', np.hstack((cat, cat_not, cat_not_not)))
print(cat[:3, :3])
print(cat_not[:3, :3])
print(cat_not_not[:3, :3])cv2.waitKey(0)
cv2.destroyAllWindows()
3.2.2 与运算
-
bitwise_and(img1, img2) 与运算, 图片对应位置元素进行与操作. 表现出来的效果就是黑和黑与还是黑, 白和白与还是白. # 先转换为二进制,再进行或运算, 值变小(都为1 为1,同时满足)
import cv2
import numpy as np
# 读取图片
cat = cv2.imread('./cat.jpeg')
dog = cv2.imread('./dog.jpeg')# 与操作
new_cat = cat[0:360, 0:499]
# 两个图片对应位置进行与操作
cat_and = cv2.bitwise_and(new_cat, dog)# 结果显示
cv2.imshow('and', np.hstack(((new_cat, cat_and))))
cv2.waitKey(0)
cv2.destroyAllWindows()
3.2.3 或和异或
-
bitwise_or 或运算 对应元素做或运算
-
bitwise_xor 异或运算 对应元素做异或运算
import cv2
import numpy as np
# 读取图片
cat = cv2.imread('./cat.jpeg')
# dog = cv2.imread('./dog.jpeg')new_cat = cat[0:360, 0:499]
# 两个图片对应位置进行或操作
cat_xor = cv2.bitwise_xor(new_cat, dog)
cat_or = cv2.bitwise_or(new_cat, dog)cv2.imshow('or', np.hstack(((new_cat, cat_or, cat_xor))))
cv2.waitKey(0)
cv2.destroyAllWindows()
3.3 添加水印项目实例
- 将需要添加水印的元素图片在位置的值用 mask 遮住 .
# 1,引入图片
# 2,设计log
# 3,规划log位置\添加位置底色转换为黑色
# 4, 利用add操作
# 导入图片
import cv2
import numpy as np
dog = cv2.imread('./dog.jpeg')# 创建log
logo = np.zeros((140, 140, 3), np.uint8)
# 绘制logo
logo[10:70, 10:70] = [0,0,255]
logo[70:130, 70:130] = [255, 0, 0]# 掩码 :mask
mask = np.zeros((140, 140), np.uint8)
mask[10:70, 10:70] = 255
mask[70:130, 70:130] = 255
m = cv2.bitwise_not(mask)# 选择log添加位置
roi = dog[0:140, 0:140]
# roi 与m 进行与操作,先roi和roi 做与运算,
# 然后结果再和 mask做与运算, 如果结果为true,显示原图
tmp = cv2.bitwise_and(roi, roi, mask = m)
dst = cv2.add(tmp, logo)# 在dog 上还原
dog[:140, :140] = dst
cv2.imshow('dog', dog)
cv2.waitKey(0)
cv2.destroyAllWindows()
- 添加文字水印
import cv2
import numpy as np
from PIL import ImageFont, ImageDraw, Imageimg = cv2.imread('./cat.jpeg')
font_path = 'simhei.ttf'
font = ImageFont.truetype(font_path, 30)
img_pil = Image.fromarray(img)
draw = ImageDraw.Draw(img_pil)
row, col, channel = img.shape
draw.text((col-160, row-80), '弑神不弑神', font=font, fill=(255, 255, 255, 255))
img_logo = np.array(img_pil)cv2.imshow('img_logo', img_logo)
cv2.waitKey(0)
cv2.destroyAllWindows()
相关文章:

02- OpenCV绘制图形及图像算术变换 (OpenCV基础) (机器视觉)
知识重点 OpenCV用的最多的色彩空间是HSV. 方便OpenCV做图像处理img2 img.view() # 浅拷贝img3 img.copy() # 深拷贝split(mat) 分割图像的通道: b, g, r cv2.split(img) # b, g, r 都是数组merge((ch1, ch2, ch3)) 融合多个通道cvtColor(img, colorspace): 颜…...

猜数字大小 II
力扣链接 力扣 题目描述: 我们正在玩一个猜数游戏,游戏规则如下: 我从 1 到 n 之间选择一个数字。你来猜我选了哪个数字。如果你猜到正确的数字,就会 赢得游戏 。如果你猜错了,那么我会告诉你,我选的数…...

CCNP350-401学习笔记(251-300题)
251、 Which IPv6 OSPF network type is applied to interface Fa0/0 of R2 by default? A. multipointB. broadcast C. Ethernet D. point-to-point 252、Which EIGRP feature allows the use of leak maps? A. neighborB. Stub C. offset-list D. address-family 253、W…...

掌握MySQL分库分表(二)Mysql数据库垂直分库分表、水平分库分表
文章目录垂直分表拆分方法举例垂直分库水平分表水平分库小结垂直角度(表结构不一样)水平角度(表结构一样)垂直分表 需求:商品表字段太多,每个字段访问频次不⼀样,浪费了IO资源,需要…...

算法训练营 day50 动态规划 单词拆分 多重背包理论基础
算法训练营 day50 动态规划 单词拆分 多重背包理论基础 单词拆分 139. 单词拆分 - 力扣(LeetCode) 给你一个字符串 s 和一个字符串列表 wordDict 作为字典。请你判断是否可以利用字典中出现的单词拼接出 s 。 注意:不要求字典中出现的单词…...

一文3000字用Postman从0到1实现UI自动化测试
“阅读本文大概需要4分钟。Postman不是做接口测试的吗?为什么还能做UI自动化测试呢? 其实,只要你了解Selenium的运行原理,就可以理解为什么Postman也能实现UI自动化测试了。 Selenium底层原理 运行代码,启动浏览器后…...
2023年美国大学生数学建模C题:预测Wordle结果建模详解+模型代码(一)
目录 前言 一、题目理解 背景 解析 字段含义: 建模要求 二、建模思路...

spring-boot 整合 前端框架 React 增删改查(附源码)
看了很多 关于 SpringBoot 增删改查 的文章 ,但是 React 前端框架这块似乎没什么人玩,一般都是Vue进行整合 ,所以想写一篇关于 React 整合 SpringBoot 增删改查的项目 React 学习区域 React中文教程: https://www.php.cn/doc/react/tutorial/…...

未来的城市:智慧城市定义、特征、应用、场景
智慧城市是通过连接一个地区的物理、经济和社会基础设施,以创新、有效和高效的方式应用和实施技术来发展城市的概念,以改善服务并实现更好的生活质量。智慧城市是一个将信息和通信技术融入日常治理的城市区域,旨在实现效率、改善公共服务、增…...

Qt线程池QThreadPool使用示例
目录前言1.线程池原理介绍2.QThreadPool详细介绍反复执行同一个任务设置线程过期时间线程数量信息3.QThreadPool示例4.总结前言 线程池顾名思义就是同时管理多个线程的"池子",它是一种并发处理技术,在程序中使用线程池能够提高线程的使用效率…...

【Spring】难理解的Aop编程 | 入门?
作者:狮子也疯狂 专栏:《spring开发》 坚持做好每一步,幸运之神自然会驾凌在你的身上 目录一. 🦁 前言二. 🦁 常见概念2.1 常见术语2.2 AOP入门Ⅰ. 🐇 功能场景Ⅱ. 🐇 实现过程2.3 通知类型Ⅰ.…...

2 月 25 日,论道京城 | 云原生开源项目应用实践报名开启
在数字化转型的浪潮中,云原生已经逐渐成为人们关注的焦点。开源社区作为云原生技术创新的根据地,为云原生的产业发展打造了丰富的技术生态圈,也在广泛的实践中源源不断地创造着新的机遇。想知道云原生存储技术实现了怎样的突破吗?…...
第五、六章 贪心算法、回溯算法
贪心算法 适合于贪心算法求解的问题具有:贪心选择性质、最优子结构性质。 贪心算法可以获取到问题的局部最优解,不一定能获取到全局最优解。 贪心算法总是作出在当前看来最好的选择;并且每次贪心选择都能将问题化简为一个更小的与原问题具有…...

k8s-kubectl命令
文章目录一、kubectl 基本命令1、陈述式资源管理方法:2、声明式资源管理办法二、基本信息查看三、项目的生命周期创建kubectl run命令四、金丝雀发布(Canary Release)——陈述式管理方法五、声明式管理方法kubectl create 和 kubectl apply区别一、kubectl 基本命令 1、陈述式…...

36、基于51单片机频率计 LCD 1602显示系统设计
摘要 数字频率计是一种基本的测量仪器。它被广泛应用于航天、电子、测控等领域,还被应用在计算机及各种数学仪表中。一般采用的是十进制数字,显示被测信号频率。基本功能是测量正弦信号,方波信号以及其他各种单位时间内变坏的物理量。由于其…...

【vue】elemente-ui table toggleRowSelection 默认选择无效[已解决]
项目场景: 点击按钮,弹出一个弹出框,内部出现一个table表,表内数据是动态获取,同时得勾选上几个table表的数据,类似以下的图 问题描述 点击按钮显示弹出框,加载table中的数据,默…...
SpringMVC DispatcherServlet源码(5) HttpMessageConverter扩展
前文通过阅读源码,深入分析了DispatcherServlet及相关组件的工作流程,本文不再阅读源码,介绍一下扩展HttpMessageConverter的方式。 HttpMessageConverter工作方式及扩展方式 前文介绍过,HttpMessageConverter是读写请求体和响应…...
day16_API
今日内容 上课同步视频:CuteN饕餮的个人空间_哔哩哔哩_bilibili 同步笔记沐沐霸的博客_CSDN博客-Java2301 零、 复习昨日 一、作业 二、String 三、StringBuffer&StringBuilder 四、日期 零、 复习昨日 见晨考 一、String String代表字符串,类,java程序中的所有字符串&…...

十二月券商金工精选
✦研报目录✦ ✦简述✦ 按发布时间排序 华宝证券 主动暴露的得与失—从Barra框架到私募指增因子分析方法 发布日期:2022-12-01 关键词:股票、Barra、风险暴露、指数增强 主要内容:本文针对私募指数增强产品的策略流程,设计…...
JUnit
Junit 简介 JUnit是一个开源的java单元测试框架,它是XUnit测试体系架架构的一种体现 是Java语言事实上的标准单元测试库真正的优势来自于JUnit所采作用的思想和技术,而不是框架本身。推动了单元测试、测试先行的编程和测试驱动的开发JUnit衍生了许多xUn…...

SpringBoot-17-MyBatis动态SQL标签之常用标签
文章目录 1 代码1.1 实体User.java1.2 接口UserMapper.java1.3 映射UserMapper.xml1.3.1 标签if1.3.2 标签if和where1.3.3 标签choose和when和otherwise1.4 UserController.java2 常用动态SQL标签2.1 标签set2.1.1 UserMapper.java2.1.2 UserMapper.xml2.1.3 UserController.ja…...

【Redis技术进阶之路】「原理分析系列开篇」分析客户端和服务端网络诵信交互实现(服务端执行命令请求的过程 - 初始化服务器)
服务端执行命令请求的过程 【专栏简介】【技术大纲】【专栏目标】【目标人群】1. Redis爱好者与社区成员2. 后端开发和系统架构师3. 计算机专业的本科生及研究生 初始化服务器1. 初始化服务器状态结构初始化RedisServer变量 2. 加载相关系统配置和用户配置参数定制化配置参数案…...

Vue2 第一节_Vue2上手_插值表达式{{}}_访问数据和修改数据_Vue开发者工具
文章目录 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染2. 插值表达式{{}}3. 访问数据和修改数据4. vue响应式5. Vue开发者工具--方便调试 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染 准备容器引包创建Vue实例 new Vue()指定配置项 ->渲染数据 准备一个容器,例如: …...

2025季度云服务器排行榜
在全球云服务器市场,各厂商的排名和地位并非一成不变,而是由其独特的优势、战略布局和市场适应性共同决定的。以下是根据2025年市场趋势,对主要云服务器厂商在排行榜中占据重要位置的原因和优势进行深度分析: 一、全球“三巨头”…...
【生成模型】视频生成论文调研
工作清单 上游应用方向:控制、速度、时长、高动态、多主体驱动 类型工作基础模型WAN / WAN-VACE / HunyuanVideo控制条件轨迹控制ATI~镜头控制ReCamMaster~多主体驱动Phantom~音频驱动Let Them Talk: Audio-Driven Multi-Person Conversational Video Generation速…...

人工智能(大型语言模型 LLMs)对不同学科的影响以及由此产生的新学习方式
今天是关于AI如何在教学中增强学生的学习体验,我把重要信息标红了。人文学科的价值被低估了 ⬇️ 转型与必要性 人工智能正在深刻地改变教育,这并非炒作,而是已经发生的巨大变革。教育机构和教育者不能忽视它,试图简单地禁止学生使…...

push [特殊字符] present
push 🆚 present 前言present和dismiss特点代码演示 push和pop特点代码演示 前言 在 iOS 开发中,push 和 present 是两种不同的视图控制器切换方式,它们有着显著的区别。 present和dismiss 特点 在当前控制器上方新建视图层级需要手动调用…...

【网络安全】开源系统getshell漏洞挖掘
审计过程: 在入口文件admin/index.php中: 用户可以通过m,c,a等参数控制加载的文件和方法,在app/system/entrance.php中存在重点代码: 当M_TYPE system并且M_MODULE include时,会设置常量PATH_OWN_FILE为PATH_APP.M_T…...

C++ 设计模式 《小明的奶茶加料风波》
👨🎓 模式名称:装饰器模式(Decorator Pattern) 👦 小明最近上线了校园奶茶配送功能,业务火爆,大家都在加料: 有的同学要加波霸 🟤,有的要加椰果…...

车载诊断架构 --- ZEVonUDS(J1979-3)简介第一篇
我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 做到欲望极简,了解自己的真实欲望,不受外在潮流的影响,不盲从,不跟风。把自己的精力全部用在自己。一是去掉多余,凡事找规律,基础是诚信;二是…...