图像分割恢复方法
传统的图像分割方法主要依赖于图像的灰度值、纹理、颜色等特征,通过不同的算法将图像分割成多个区域。这些方法通常可以分为以下几类:
1.基于阈值的方法
2.基于边缘的方法
3.基于区域的方法
4.基于聚类的方法
下面详细介绍这些方法及其示例代码。
1. 基于阈值的方法
基于阈值的方法是最简单的图像分割方法之一,通过设定一个或多个阈值,将图像分为前景和背景。
示例代码(全局阈值)
import cv2
import numpy as np
from matplotlib import pyplot as plt# 读取灰度图像
image = cv2.imread('image.jpg', cv2.IMREAD_GRAYSCALE)# 应用全局阈值分割
_, thresh = cv2.threshold(image, 127, 255, cv2.THRESH_BINARY)# 显示结果
plt.subplot(1, 2, 1)
plt.title('Original Image')
plt.imshow(image, cmap='gray')plt.subplot(1, 2, 2)
plt.title('Global Thresholding')
plt.imshow(thresh, cmap='gray')plt.show()
示例代码(Otsu’s 阈值)
_, otsu_thresh = cv2.threshold(image, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)plt.subplot(1, 2, 1)
plt.title('Original Image')
plt.imshow(image, cmap='gray')plt.subplot(1, 2, 2)
plt.title('Otsu Thresholding')
plt.imshow(otsu_thresh, cmap='gray')plt.show()
2. 基于边缘的方法
基于边缘的方法通过检测图像中的边缘,将图像分割成不同的区域。
示例代码(Canny 边缘检测)
edges = cv2.Canny(image, 100, 200)plt.subplot(1, 2, 1)
plt.title('Original Image')
plt.imshow(image, cmap='gray')plt.subplot(1, 2, 2)
plt.title('Edge Detection')
plt.imshow(edges, cmap='gray')plt.show()
3. 基于区域的方法
基于区域的方法通过区域生长、区域合并等算法,根据像素相似性将图像分割成不同的区域。
示例代码(区域生长)
import cv2
import numpy as np
from matplotlib import pyplot as pltdef region_growing(img, seed):h, w = img.shapesegmented_img = np.zeros_like(img)stack = [seed]while len(stack) > 0:x, y = stack.pop()if segmented_img[x, y] == 0 and img[x, y] > 128:segmented_img[x, y] = 255if x > 0:stack.append((x - 1, y))if x < h - 1:stack.append((x + 1, y))if y > 0:stack.append((x, y - 1))if y < w - 1:stack.append((x, y + 1))return segmented_img# 读取灰度图像
image = cv2.imread('image.jpg', cv2.IMREAD_GRAYSCALE)seed = (100, 100) # 种子点
segmented_img = region_growing(image, seed)plt.subplot(1, 2, 1)
plt.title('Original Image')
plt.imshow(image, cmap='gray')
plt.subplot(1, 2, 2)
plt.title('Region Growing')
plt.imshow(segmented_img, cmap='gray')
plt.show()
4. 基于聚类的方法
基于聚类的方法通过聚类算法(如K均值聚类)将图像中的像素分为不同的簇,从而实现图像分割。
示例代码(K均值聚类)
import cv2
import numpy as np
from matplotlib import pyplot as plt# 读取图像并转换为二维数据
image = cv2.imread('image.jpg')
Z = image.reshape((-1, 3))
Z = np.float32(Z)# 定义K均值参数
criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 10, 1.0)
K = 3
ret, label, center = cv2.kmeans(Z, K, None, criteria, 10, cv2.KMEANS_RANDOM_CENTERS)# 转换回uint8数据类型,并重塑回原始图像
center = np.uint8(center)
res = center[label.flatten()]
segmented_image = res.reshape((image.shape))# 显示结果
plt.subplot(1, 2, 1)
plt.title('Original Image')
plt.imshow(cv2.cvtColor(image, cv2.COLOR_BGR2RGB))plt.subplot(1, 2, 2)
plt.title('Segmented Image (K = 3)')
plt.imshow(cv2.cvtColor(segmented_image, cv2.COLOR_BGR2RGB))plt.show()
5. 基于图论的方法
基于图论的方法通过将图像看作一个图,其中像素是图的节点,边的权重表示像素之间的相似性。常见的图论方法有图割算法(Graph Cut)和分水岭算法(Watershed)。
分水岭算法步骤
- 预处理:为了减小噪声影响,通常对图像进行平滑处理。
- 计算梯度:使用梯度运算子(如Sobel算子)计算图像的梯度,得到梯度幅值图。
- 标记前景和背景:通过一些方法(如阈值分割或形态学操作)对前景和背景进行标记。
- 应用分水岭算法:基于标记的前景和背景,对图像应用分水岭算法进行分割。
详细代码实现
以下是一个详细的Python代码示例,展示如何使用OpenCV实现分水岭算法进行图像分割:
import cv2
import numpy as np
from matplotlib import pyplot as plt# 读取图像
image = cv2.imread('image.jpg')
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)# 1. 预处理:平滑图像,减小噪声
blurred = cv2.GaussianBlur(gray, (5, 5), 0)# 2. 计算梯度
grad_x = cv2.Sobel(blurred, cv2.CV_64F, 1, 0, ksize=3)
grad_y = cv2.Sobel(blurred, cv2.CV_64F, 0, 1, ksize=3)
gradient = cv2.addWeighted(grad_x, 0.5, grad_y, 0.5, 0)# 3. 二值化
_, binary = cv2.threshold(gradient, 50, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)# 4. 形态学操作,去除小块噪声
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))
closed = cv2.morphologyEx(binary, cv2.MORPH_CLOSE, kernel, iterations=2)# 5. 距离变换
dist_transform = cv2.distanceTransform(closed, cv2.DIST_L2, 5)
_, sure_fg = cv2.threshold(dist_transform, 0.7 * dist_transform.max(), 255, 0)
sure_fg = np.uint8(sure_fg)
unknown = cv2.subtract(closed, sure_fg)# 6. 标记前景和背景
_, markers = cv2.connectedComponents(sure_fg)# 增加1,以便背景为1
markers = markers + 1# 未知区域标记为0
markers[unknown == 255] = 0# 7. 应用分水岭算法
markers = cv2.watershed(image, markers)
image[markers == -1] = [0, 0, 255]# 显示结果
plt.subplot(2, 2, 1), plt.imshow(cv2.cvtColor(image, cv2.COLOR_BGR2RGB)), plt.title('Original Image')
plt.subplot(2, 2, 2), plt.imshow(gradient, cmap='gray'), plt.title('Gradient')
plt.subplot(2, 2, 3), plt.imshow(closed, cmap='gray'), plt.title('Closed')
plt.subplot(2, 2, 4), plt.imshow(markers, cmap='gray'), plt.title('Markers')
plt.show()
代码解释
1.读取图像和预处理:
- 读取图像并转换为灰度图。
- 使用高斯模糊平滑图像,减小噪声。
2.计算梯度:
- 使用Sobel算子计算图像的梯度。
- 将x方向和y方向的梯度组合在一起,得到梯度幅值图。
3.二值化:
- 使用全局阈值(Otsu方法)对梯度图进行二值化。
4.形态学操作:
- 使用闭运算去除小块噪声,填补前景对象中的小孔。
5.距离变换:
- 计算前景对象的距离变换。
- 根据距离变换结果,确定前景对象的中心区域。
6.标记前景和背景:
- 使用连通组件标记前景区域。
- 增加1,使背景标记为1,前景标记为2,3,4,……
7.应用分水岭算法:
- 将未标记的未知区域标记为0。
- 应用分水岭算法进行图像分割,标记边缘区域为-1。
显示结果:
- 使用Matplotlib显示原始图像、梯度图、形态学处理结果和分水岭标记结果。
通过以上步骤,可以实现对图像的分水岭分割。该方法在处理复杂形状和具有噪声的图像时表现较好。
另外一个分水岭分割代码:
import cv2
import numpy as np
from matplotlib import pyplot as plt#获取背景
# 1. 通过二值法得到黑白图片
# 2. 通过形态学获取背景img = cv2.imread('water_coins.jpeg')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)ret, thresh =cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)#开运算
kernel = np.ones((3,3), np.int8)
open1 = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel, iterations = 2)#膨胀
bg = cv2.dilate(open1, kernel, iterations = 1)#获取前景物体
dist = cv2.distanceTransform(open1, cv2.DIST_L2, 5)ret, fg = cv2.threshold(dist,0.7*dist.max(), 255, cv2.THRESH_BINARY)# plt.imshow(dist, cmap='gray')
# plt.show()
# exit()#获取未知区域
fg = np.uint8(fg)
unknow = cv2.subtract(bg, fg)#创建连通域
ret, marker = cv2.connectedComponents(fg)marker = marker + 1
marker[unknow==255] = 0#进行图像分割
result = cv2.watershed(img, marker)img[result == -1] = [0, 0, 255]cv2.imshow("img", img)
cv2.imshow("unknow", unknow)
cv2.imshow("fg", fg)
cv2.imshow("bg", bg)
cv2.imshow("thresh", thresh)
cv2.waitKey()
下面是图片:
6. 基于直方图的方法
基于直方图的方法利用图像的灰度或颜色直方图进行分割,如图像分割中的Mean-Shift算法。
示例代码(直方图均衡化)
import cv2
from matplotlib import pyplot as plt# 读取灰度图像
image = cv2.imread('image.jpg', cv2.IMREAD_GRAYSCALE)# 应用直方图均衡化
equalized_image = cv2.equalizeHist(image)# 显示结果
plt.subplot(1, 2, 1)
plt.title('Original Image')
plt.imshow(image, cmap='gray')plt.subplot(1, 2, 2)
plt.title('Histogram Equalization')
plt.imshow(equalized_image, cmap='gray')plt.show()
7. 基于pyrMeanShiftFiltering分割
pyrMeanShiftFiltering示例代码
import cv2
import numpy as npimg = cv2.imread('key.png')mean_img = cv2.pyrMeanShiftFiltering(img, 20, 30)imgcanny = cv2.Canny(mean_img, 150, 300)contours, _ = cv2.findContours(imgcanny, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)cv2.drawContours(img, contours, -1, (0, 0, 255), 2)cv2.imshow('img', img)
cv2.imshow('mean_img', mean_img)
cv2.imshow('canny', imgcanny)
cv2.waitKey()
7. 基于GrabCut算法进行前景分割
GrabCut示例代码
import cv2
import numpy as npclass App:flag_rect = Falserect=(0, 0, 0, 0)startX = 0startY = 0def onmouse(self, event, x, y, flags, param):if event == cv2.EVENT_LBUTTONDOWN:self.flag_rect = Trueself.startX = xself.startY = yprint("LBUTTIONDOWN")elif event == cv2.EVENT_LBUTTONUP:self.flag_rect = Falsecv2.rectangle(self.img, (self.startX, self.startY),(x, y),(0, 0, 255), 3)self.rect = (min(self.startX, x), min(self.startY, y), abs(self.startX - x), abs(self.startY -y))print("LBUTTIONUP")elif event == cv2.EVENT_MOUSEMOVE:if self.flag_rect == True:self.img = self.img2.copy()cv2.rectangle(self.img, (self.startX, self.startY),(x, y),(255, 0, 0), 3)print("MOUSEMOVE") print("onmouse")def run(self):print("run...")cv2.namedWindow('input')cv2.setMouseCallback('input', self.onmouse)self.img = cv2.imread('./flower.png')self.img2 = self.img.copy()self.mask = np.zeros(self.img.shape[:2], dtype=np.uint8)self.output = np.zeros(self.img.shape, np.uint8)while(1):cv2.imshow('input', self.img)cv2.imshow('output', self.output)k = cv2.waitKey(100)if k == 27:breakif k == ord('g'):bgdmodel = np.zeros((1, 65), np.float64)fgdmodel = np.zeros((1, 65), np.float64)cv2.grabCut(self.img2, self.mask, self.rect,bgdmodel, fgdmodel,1, cv2.GC_INIT_WITH_RECT)mask2 = np.where((self.mask==1)|(self.mask==3), 255, 0).astype('uint8')self.output = cv2.bitwise_and(self.img2, self.img2, mask=mask2) App().run()
这段代码允许用户通过鼠标在图像上绘制矩形框,并通过GrabCut算法进行前景分割。在运行过程中,用户可以通过鼠标操作绘制矩形,并通过按下g键触发分割算法。
8.视频背景分割:
视频背景分割有三种方法:
- cv2.bgsegm.createBackgroundSubtractorMOG()
- cv2.createBackgroundSubtractorMOG2()
- cv2.bgsegm.createBackgroundSubtractorGMG()
1.cv2.bgsegm.createBackgroundSubtractorMOG()基于高斯混合模型(Mixture of Gaussians, MOG)的背景减法器。它是OpenCV中的一个较早实现版本。
特点:
- 使用高斯混合模型来表示背景。
- 对于每个像素,使用多个高斯分布来建模。
- 更适合静态背景和较慢的场景变化。
特点:
使用高斯混合模型来表示背景。
对于每个像素,使用多个高斯分布来建模。
更适合静态背景和较慢的场景变化。
2.cv2.createBackgroundSubtractorMOG2()这个函数创建了MOG2背景减法器,是对MOG的改进版本。它是OpenCV中默认和推荐的背景减法方法。
特点:
- 改进的高斯混合模型,能够自动调整模型中的高斯分布数量。
- 更加鲁棒,能够更好地处理光照变化和场景中的噪声。
- 提供阴影检测功能。
3.cv2.bgsegm.createBackgroundSubtractorGMG()这个函数创建了基于统计渐变的背景减法器(GMG)。
特点:
- 使用逐像素贝叶斯分段和统计渐变。
- 需要一定数量的初始帧来建立背景模型。
- 对于处理动态背景和复杂场景非常有效,但初始化较慢。
import cv2
import numpy as npcap = cv2.VideoCapture('./vtest.avi')
#mog = cv2.bgsegm.createBackgroundSubtractorMOG()
# mog = cv2.createBackgroundSubtractorMOG2()
mog = cv2.bgsegm.createBackgroundSubtractorGMG()while(True):ret, frame = cap.read()fgmask = mog.apply(frame)cv2.imshow('img',fgmask)k = cv2.waitKey(10) if k ==27:breakcap.release()
cv2.destroyAllWindows()
9.图像恢复算法
图像恢复算法用于从损坏或降质的图像中恢复原始图像。常用的方法包括:
- 区域增长法(Region Growing):基于区域扩展修复缺失部分。
- 纹理合成法(Texture Synthesis):使用相邻区域的纹理填补缺失部分。
- 深度学习方法:如基于GAN的图像修复方法。
代码示例
import cv2
import numpy as np
img = cv2.imread('inpaint.png')
mask = cv2.imread('inpaint_mask.png', 0)
dst = cv2.inpaint(img, mask, 5, cv2.INPAINT_TELEA)
cv2.imshow('dst', dst)
cv2.imshow('img', img)
cv2.waitKey()
- inpaint_mask.png:
- inpaint.png:
相关文章:

图像分割恢复方法
传统的图像分割方法主要依赖于图像的灰度值、纹理、颜色等特征,通过不同的算法将图像分割成多个区域。这些方法通常可以分为以下几类: 1.基于阈值的方法 2.基于边缘的方法 3.基于区域的方法 4.基于聚类的方法 下面详细介绍这些方法及其示例代码。 1. 基…...

Ultralytics:YOLO11使用教程
Ultralytics:YOLO11使用教程 前言相关介绍前提条件实验环境安装环境项目地址LinuxWindows YOLO11使用教程进行目标检测进行实例分割进行姿势估计进行旋转框检测进行图像分类 参考文献 前言 由于本人水平有限,难免出现错漏,敬请批评改正。更多…...

前缀和算法——优选算法
个人主页:敲上瘾-CSDN博客 个人专栏:游戏、数据结构、c语言基础、c学习、算法 一、什么是前缀和? 前缀和是指从数组的起始位置到某一位置(或矩阵的某个区域)的所有元素的和。这种算法通过预处理数组或矩阵,…...

YOLO11改进|注意力机制篇|引入HAT超分辨率重建模块
目录 一、HAttention注意力机制1.1HAttention注意力介绍1.2HAT核心代码 二、添加HAT注意力机制2.1STEP12.2STEP22.3STEP32.4STEP4 三、yaml文件与运行3.1yaml文件3.2运行成功截图 一、HAttention注意力机制 1.1HAttention注意力介绍 HAT模型 通过结合卷积特征提取与多尺度注意…...

老牛也想吃嫩草,思科为何巨资投入云初创CoreWeave?
【科技明说 | 科技热点关注】 当我看到前些天思科(Cisco)的新闻时笑了。业内朋友对我说,老牛也想吃嫩草,人之常情尔,都是为了好好活着。 作为全球著名的网络产品巨头,思科Cisco论是遭遇到何种市场与行业巨变ÿ…...
Spring Boot 事务管理入门
在 Spring Boot 应用中,事务管理是一个至关重要的方面,它确保了数据的一致性和完整性。本文将深入探讨 Spring Boot 中事务管理的机制、使用方法以及注意事项,并提供丰富的示例代码。 其它教程: mysql事务详解 一、事务基础概念…...

20年408数据结构
第一题: 解析:这种题可以先画个草图分析一下,一下就看出来了。 这里的m(7,2)对应的是这图里的m(2,7),第一列存1个元素,第二列存2个元素,第三列存3个元素,第四列存4个元素,第五列存5个元素&#…...

4反馈、LC、石英、RC振荡器
1什么是振荡器? 我们看看振荡器在无线通信中扮演什么角色? 1)无线通信的波是指电磁波。 2)电磁波的频率高于100KHz才能在空气中传播。 3)空气中的高频电磁波的相位和振幅可以排列组合包含信息。 4)无…...
go 的 timer reset
在 Go 语言 1.23 版本之前,与Timer(定时器)关联的通道是异步的(有缓冲,容量为 1)。这意味着即使在调用Timer.Stop(停止定时器)或Timer.Reset(重置定时器)并返…...
每日一面 day03
Q:介绍一下MySQL的三种日志(redo,undo,bin) Redo Log 和 Undo Log 是存储引擎 InnoDB 层面实现的,Bin Log 是 MySQL 层面实现的。 下面是三种日志的简要介绍: Redo Log:保证事务的…...

ssm基于SSM框架的餐馆点餐系统的设计+VUE
系统包含:源码论文 所用技术:SpringBootVueSSMMybatisMysql 免费提供给大家参考或者学习,获取源码请私聊我 需要定制请私聊 目 录 摘要 I Abstract II 1绪论 1 1.1研究背景与意义 1 1.1.1研究背景 1 1.1.2研究意义 1 1.2国内外研究…...

多人播报配音怎么弄?简单4招分享
想象一下,你手中的小说突然间活了起来,每个角色都有了自己的声音和情感。 这就是多人配音的魅力所在。它让文字跃然纸上,赋予了故事新的生命。 那么,如何制作一部引人入胜的小说呢?多人配音怎么制作的呢?…...

《Windows PE》4.1导入表
导入表顾名思义,就是记录外部导入函数信息的表。这些信息包括外部导入函数的序号、名称、地址和所属的DLL动态链接库的名称。Windows程序中使用的所有API接口函数都是从系统DLL中调用的。当然也可能是自定义的DLL动态链接库。对于调用方,我们称之为导入函…...
计算机专业大学生应该如何规划大学四年?
计算机专业的大学生在学习过程中应该注重以下几个方面,以确保他们在快速变化的技术领域中保持竞争力: 基础知识: 数学基础:离散数学、线性代数、概率论等数学课程对于理解算法和数据结构至关重要。编程基础:学习至少一…...
R知识图谱1—tidyverse玩转数据处理120题
以下是本人依据张老师提供的tidyverse题库自行刷题后的tidyverse Rmd文件,部分解法参考张老师提示,部分解法我本人灵感提供 数据下载来源https://github.com/zhjx19/tidyverse120/tree/main/data 参考https://github.com/MaybeBio/R_cheatsheet/tree/mai…...

【赵渝强老师】K8s中的有状态控制器StatefulSet
在K8s中,StatefulSets将Pod部署成有状态的应用程序。通过使用StatefulSets控制器,可以为Pod提供持久存储和持久的唯一性标识符。StatefulSets控制器与Deployment控制器不同的是,StatefulSets控制器为管理的Pod维护了一个有粘性的标识符。无论…...

机器学习笔记(持续更新)
使用matplotlib绘图: import matplotlib.pyplot as plt fig, axplt.subplots() #创建一个图形窗口 plt.show() #不绘制任何内容,直接显示空图 重复值处理: 重复值处理代码: import pandas as pd data pd.DataFrame({学号: [1…...
Nginx 配置之server块
在 Nginx 配置中使用两个 server 块是为了处理 HTTP 和 HTTPS 请求的不同需求。具体来说: 第一个 server 块: 监听 80 端口(HTTP)。将所有 HTTP 请求重定向到 HTTPS(443 端口)。 第二个 server 块ÿ…...

魅族Lucky 08惊艳亮相:极窄四等边设计引领美学新风尚
在这个智能手机设计趋于同质化的时代,魅族以其独特的设计理念和创新技术,再次为市场带来了一股清新之风。 近日,魅族全新力作——Lucky 08手机正式曝光,其独特的“极窄物理四等边”设计瞬间吸引了众多消费者的目光,而…...
自动化的抖音
文件命名 main.js var uiModule require("ui_module.js"); if (!auto.service) {toast("请开启无障碍服务");auto.waitFor();} var isRunning true; var swipeCount 0; var targetSwipeCount random(1, 10); var window uiModule.createUI(); uiMo…...

基于FPGA的PID算法学习———实现PID比例控制算法
基于FPGA的PID算法学习 前言一、PID算法分析二、PID仿真分析1. PID代码2.PI代码3.P代码4.顶层5.测试文件6.仿真波形 总结 前言 学习内容:参考网站: PID算法控制 PID即:Proportional(比例)、Integral(积分&…...
java 实现excel文件转pdf | 无水印 | 无限制
文章目录 目录 文章目录 前言 1.项目远程仓库配置 2.pom文件引入相关依赖 3.代码破解 二、Excel转PDF 1.代码实现 2.Aspose.License.xml 授权文件 总结 前言 java处理excel转pdf一直没找到什么好用的免费jar包工具,自己手写的难度,恐怕高级程序员花费一年的事件,也…...
JVM垃圾回收机制全解析
Java虚拟机(JVM)中的垃圾收集器(Garbage Collector,简称GC)是用于自动管理内存的机制。它负责识别和清除不再被程序使用的对象,从而释放内存空间,避免内存泄漏和内存溢出等问题。垃圾收集器在Ja…...

转转集团旗下首家二手多品类循环仓店“超级转转”开业
6月9日,国内领先的循环经济企业转转集团旗下首家二手多品类循环仓店“超级转转”正式开业。 转转集团创始人兼CEO黄炜、转转循环时尚发起人朱珠、转转集团COO兼红布林CEO胡伟琨、王府井集团副总裁祝捷等出席了开业剪彩仪式。 据「TMT星球」了解,“超级…...
Nginx server_name 配置说明
Nginx 是一个高性能的反向代理和负载均衡服务器,其核心配置之一是 server 块中的 server_name 指令。server_name 决定了 Nginx 如何根据客户端请求的 Host 头匹配对应的虚拟主机(Virtual Host)。 1. 简介 Nginx 使用 server_name 指令来确定…...

[10-3]软件I2C读写MPU6050 江协科技学习笔记(16个知识点)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16...

2025年渗透测试面试题总结-腾讯[实习]科恩实验室-安全工程师(题目+回答)
安全领域各种资源,学习文档,以及工具分享、前沿信息分享、POC、EXP分享。不定期分享各种好玩的项目及好用的工具,欢迎关注。 目录 腾讯[实习]科恩实验室-安全工程师 一、网络与协议 1. TCP三次握手 2. SYN扫描原理 3. HTTPS证书机制 二…...

[ACTF2020 新生赛]Include 1(php://filter伪协议)
题目 做法 启动靶机,点进去 点进去 查看URL,有 ?fileflag.php说明存在文件包含,原理是php://filter 协议 当它与包含函数结合时,php://filter流会被当作php文件执行。 用php://filter加编码,能让PHP把文件内容…...

Vue ③-生命周期 || 脚手架
生命周期 思考:什么时候可以发送初始化渲染请求?(越早越好) 什么时候可以开始操作dom?(至少dom得渲染出来) Vue生命周期: 一个Vue实例从 创建 到 销毁 的整个过程。 生命周期四个…...
小木的算法日记-多叉树的递归/层序遍历
🌲 从二叉树到森林:一文彻底搞懂多叉树遍历的艺术 🚀 引言 你好,未来的算法大神! 在数据结构的世界里,“树”无疑是最核心、最迷人的概念之一。我们中的大多数人都是从 二叉树 开始入门的,它…...