【python计算机视觉编程——9.图像分割】
python计算机视觉编程——9.图像分割
- 9.图像分割
- 9.1 图割
- 安装Graphviz
- 下一步:正文
- 9.1.1 从图像创建图
- 9.1.2 用户交互式分割
- 9.2 利用聚类进行分割
- 9.3 变分法
9.图像分割
9.1 图割
可以选择不装Graphviz,因为原本觉得是要用,后面发现好像用不到。不安装可直接跳到下一步
安装Graphviz
-
首先需要先下载Graphviz软件(Download | Graphviz),那些包先不要下载,网上说先下载包再下载软件会报错。在安装过程中,需要注意下图中的一步,其余都是一直下一步就行

-
检查一下环境变量的路径

-
接着在自己创建的虚拟环境下安装包
pip install pydotpluspip install graphviz -
这里需要注意的是,还需要再安装一个包,否则单单安装上面的会报错
pip install python-graphviz -
测试代码
from graphviz import Digraph dot = Digraph(comment='The Round Table') dot.node('A', 'King Arthur') dot.node('B', 'Sir Bedevere the Wise') dot.node('L', 'Sir Lancelot the Brave')dot.edges(['AB', 'AL']) dot.edge('B', 'L', constraint='false') print(dot.source) dot.render('round-table.gv',format='jpg', view=True)

下一步:正文
- 图割:将一个有向图分割成两个互不相交的集合
- 基本思想:相似且彼此相近的像素应该划分到同一区域
图割C(C是图中所有边的集合)的“代价”函数定义为所有割的边的权重求合相加:
E c u t = ∑ ( i , j ) ∈ C w i j E_{cut}=\sum_{(i,j)\in C}w_{ij} Ecut=(i,j)∈C∑wij
w i j w_{ij} wij是图中节点i到节点j的边 ( i , j ) (i,j) (i,j)的权重,并且是对割C所有的边进行求和
我们需要用图来表示图像,并对图进行划分,以使得 E c u t E_{cut} Ecut最小。同时在用图表示图像时,需要额外增加两个节点(源点和汇点),并仅考虑那些将源点和汇点分开的割
寻找最小割等同于在源点和汇点间寻找最大流,这里需要用到python-graph工具包( 注:不是 p i p 下载 ! \color{red}{注:不是pip下载!} 注:不是pip下载!),工具包地址如下:GitHub - pmatiello/python-graph: New official repository: https://github.com/Shoobx/python-graph
下载完后,把文件夹放入导包的根目录

根据路径进行引包,如果引入没有报错,就说明没有问题
from python_graph.core.pygraph.classes.digraph import digraph
from python_graph.core.pygraph.algorithms.minmax import maximum_flow``
这里我是报错了:“jaraco.text"中没有drop_comment, join_continuation, yield_lines函数的问题,然后我在”_jaraco_text.py"文件里找到了这三个函数,索性就直接把他提到根目录上,发现就没报错了


另一个导包路径错误在"digraph.py"和"minmax.py"文件中

接着就可以运行代码了
gr = digraph()
gr.add_nodes([0,1,2,3])
gr.add_edge((0,1), wt=4)
gr.add_edge((1,2), wt=3)
gr.add_edge((2,3), wt=5)
gr.add_edge((0,2), wt=3)
gr.add_edge((1,3), wt=4)
flows,cuts = maximum_flow(gr,0,3)
print('flow is:', flows)
print('cut is:', cuts)

9.1.1 从图像创建图
我们需要利用图像像素作为节点定义一个图,除了像素节点外,还有两个特定的节点——“源”点和“汇”点,来分别代表图像的前景和背景,我们需要做的是将所有像素与源点、汇点链接起来。
- 每个像素节点都有一个从源点的传入边
- 每个像素节点都有一个到汇点的传出边
- 每个像素节点都有一条传入边和传出边连接到它的近邻。
接着需要用朴素贝叶斯分类器进行分类,我们将第8章的BayesClassifier类搬过来
def build_bayes_graph(im,labels,sigma=1e2,kappa=1):""" 从像素四邻域建立一个图,前景和背景(前景用1标记,背景用-1标记,其他的用0标记)由labels决定,并用朴素贝叶斯分类器建模"""m,n = im.shape[:2]# 每行是一个像素的RGB向量vim = im.reshape((-1,3))# 前景和背景(RGB)foreground = im[labels==1].reshape((-1,3))background = im[labels==-1].reshape((-1,3)) train_data = [foreground,background]# 训练朴素贝叶斯分类器bc = BayesClassifier()bc.train(train_data)# 获取所有像素的概率bc_lables,prob = bc.classify(vim)prob_fg = prob[0]prob_bg = prob[1]# 用m*n+2 个节点创建图gr = digraph()gr.add_nodes(range(m*n+2))source = m*n # 倒数第二个是源点sink = m*n+1 # 最后一个节点是汇点# 归一化for i in range(vim.shape[0]):vim[i] = vim[i] / (np.linalg.norm(vim[i]) + 1e-9)# go through all nodes and add edgesfor i in range(m*n):# 从源点添加边gr.add_edge((source,i),wt=prob_fg[i]/(prob_fg[i]+prob_bg[i]))# 向汇点添加边gr.add_edge((i,sink),wt=prob_bg[i]/(prob_fg[i]+prob_bg[i]))# 向相邻节点添加边if i%n != 0: # 左边存在edge_wt = kappa*np.exp(-1.0*sum((vim[i]-vim[i-1])**2)/sigma)gr.add_edge((i,i-1),wt=edge_wt)if (i+1)%n != 0: # 如果右边存在edge_wt = kappa*np.exp(-1.0*sum((vim[i]-vim[i+1])**2)/sigma)gr.add_edge((i,i+1),wt=edge_wt)if i//n != 0: # 如果上方存在edge_wt = kappa*np.exp(-1.0*sum((vim[i]-vim[i-n])**2)/sigma)gr.add_edge((i,i-n),wt=edge_wt)if i//n != m-1: # 如果下方存在edge_wt = kappa*np.exp(-1.0*sum((vim[i]-vim[i+n])**2)/sigma)gr.add_edge((i,i+n),wt=edge_wt)return gr
def gauss(m,v,x):""" Evaluate Gaussian in d-dimensions with independent mean m and variance v at the points in (the rows of) x. http://en.wikipedia.org/wiki/Multivariate_normal_distribution """if len(x.shape)==1:n,d = 1,x.shape[0]else:n,d = x.shape# covariance matrix, subtract meanS = np.diag(1/v)x = x-m# product of probabilitiesy = np.exp(-0.5*np.diag(np.dot(x,np.dot(S,x.T))))# normalize and returnreturn y * (2*np.pi)**(-d/2.0) / (np.sqrt(np.prod(v)) + 1e-6)
写入新函数
def build_bayes_graph(im,labels,sigma=1e2,kappa=1):""" 从像素四邻域建立一个图,前景和背景(前景用1标记,背景用-1标记,其他的用0标记)由labels决定,并用朴素贝叶斯分类器建模"""m,n = im.shape[:2]# 每行是一个像素的RGB向量vim = im.reshape((-1,3))# 前景和背景(RGB)foreground = im[labels==1].reshape((-1,3))background = im[labels==-1].reshape((-1,3)) train_data = [foreground,background]# 训练朴素贝叶斯分类器bc = BayesClassifier()bc.train(train_data)# 获取所有像素的概率bc_lables,prob = bc.classify(vim)prob_fg = prob[0]prob_bg = prob[1]# 用m*n+2 个节点创建图gr = nx.DiGraph()nodes=[]for i in range(m*n+2):nodes.append(str(i))gr.add_nodes_from(nodes)source = m*n # 倒数第二个是源点sink = m*n+1 # 最后一个节点是汇点# 归一化for i in range(vim.shape[0]):vim[i] = vim[i] / (np.linalg.norm(vim[i]) + 1e-9)# go through all nodes and add edgesfor i in range(m*n):# 从源点添加边gr.add_edge(str(source),str(i),capacity=prob_fg[i]/(prob_fg[i]+prob_bg[i]))# 向汇点添加边gr.add_edge(str(i),str(sink),capacity=prob_bg[i]/(prob_fg[i]+prob_bg[i]))# 向相邻节点添加边if i%n != 0: # 左边存在edge_wt = kappa*np.exp(-1.0*sum((vim[i]-vim[i-1])**2)/sigma)gr.add_edge(str(i),str(i-1),capacity=edge_wt)if (i+1)%n != 0: # 如果右边存在edge_wt = kappa*np.exp(-1.0*sum((vim[i]-vim[i+1])**2)/sigma)gr.add_edge(str(i),str(i+1),capacity=edge_wt)if i//n != 0: # 如果上方存在edge_wt = kappa*np.exp(-1.0*sum((vim[i]-vim[i-n])**2)/sigma)gr.add_edge(str(i),str(i-n),capacity=edge_wt)if i//n != m-1: # 如果下方存在edge_wt = kappa*np.exp(-1.0*sum((vim[i]-vim[i+n])**2)/sigma)gr.add_edge(str(i),str(i+n),capacity=edge_wt)return gr
def show_labeling(im,labels):"""显示图像的前景和背景区域。前景labels=1,背景labels=-1,其他labels=0 """imshow(im)contour(labels,[-0.5,0.5])contourf(labels,[-1,-0.5],colors='b',alpha=0.25)contourf(labels,[0.5,1],colors='r',alpha=0.25)#axis('off')xticks([])yticks([])
def cut_graph(gr,imsize):""" Solve max flow of graph gr and return binary labels of the resulting segmentation."""
# print(gr)m,n=imsizesource=m*n # second to last is sourcesink=m*n+1 # last is sink# cut the graphflows,cuts = maximum_flow(gr,source,sink)
# print(cuts)# convert graph to image with labelsres = np.zeros(m*n)for pos,label in list(cuts.items())[:-2]: # 遍历所有节点,忽略源节点和汇节点# 但因为cuts.items()返回的是元组,需先转成列表再进行切片res[pos] = labelreturn res.reshape((m,n))
其中书本中from scipy.misc import imresize模块,已经不存在于imresize中,这里使用Pillow库中的resize函数进行替代 resize_image_pillow
def resize_image_pillow(image_path, output_path, scale_factor):# 打开图像文件with Image.open(image_path) as img:# 计算新的尺寸new_width = int(img.width * scale_factor)new_height = int(img.height * scale_factor)# 使用双线性插值调整图像大小img_resized = img.resize((new_width, new_height), resample=Image.BILINEAR)# 保存调整后的图像
# return img_resizedimg_resized.save(output_path)
import numpy as np
from PIL import Image
from pylab import *# resize_image_pillow('empire.jpg', 'empire.jpg', 0.07)
im=np.array(Image.open('empire.jpg'))
size=im.shape[:2]
labels=np.zeros(size)
labels[3:18,3:18]=-1
labels[-18:-3,-18:-3]=1# 对图进行分割
g = build_bayes_graph(im,labels,kappa=1)
res=cut_graph(g,size)figure()
show_labeling(im,labels)figure()
imshow(res)
gray()
axis('off')show()

9.1.2 用户交互式分割
def create_msr_labels(m, lasso=False):""" Create label matrix for training fromuser annotations. """labels = np.zeros(im.shape[:2])# backgroundlabels[m == 0] = -1labels[m == 64] = -1# foregroundif lasso:labels[m == 255] = 1else:labels[m == 128] = 1return labels# load image and annotation map
im = array(Image.open('empire.jpg'))
m = array(Image.open('empire.bmp'))
# resize
scale = 0.1
im = imresize(im, scale, interp='bilinear')
m = imresize(m, scale, interp='nearest')
# create training labels
labels = create_msr_labels(m, False)
# build graph using annotations
g = build_bayes_graph(im, labels, kappa=2)# cut graph
res = cut_graph(g, im.shape[:2])
# remove parts in background
res[m == 0] = 1
res[m == 64] = 1# plot the result
figure()
imshow(res)
gray()
xticks([])
yticks([])
savefig('labelplot.pdf')
9.2 利用聚类进行分割
def ncut_graph_matrix(im,sigma_d=1e2,sigma_g=1e-2):""" 创建用于归一化割的矩阵,其中 sigma_d 和 sigma_g 是像素距离和像素相似性的权重参数 """m,n = im.shape[:2] N = m*n# 归一化,并创建 RGB 或灰度特征向量if len(im.shape)==3:for i in range(3):im[:,:,i] = im[:,:,i] / im[:,:,i].max()vim = im.reshape((-1,3))else:im = im / im.max()vim = im.flatten()# x,y 坐标用于距离计算xx,yy = meshgrid(range(n),range(m))x,y = xx.flatten(),yy.flatten()# 创建边线权重矩阵W = zeros((N,N),'f')for i in range(N):for j in range(i,N):d = (x[i]-x[j])**2 + (y[i]-y[j])**2 W[i,j] = W[j,i] = exp(-1.0*sum((vim[i]-vim[j])**2)/sigma_g) * exp(-d/sigma_d)return W
from scipy.cluster.vq import *
def cluster(S,k,ndim):""" 从相似性矩阵进行谱聚类 """# 检查对称性if sum(abs(S-S.T)) > 1e-10:print('not symmetric')# 创建拉普拉斯矩阵rowsum = sum(abs(S),axis=0)D = diag(1 / sqrt(rowsum + 1e-6))L = dot(D,dot(S,D))# 计算 L 的特征向量U,sigma,V = linalg.svd(L,full_matrices=False)# 从前 ndim 个特征向量创建特征向量# 堆叠特征向量作为矩阵的列features = array(V[:ndim]).T# k-meansfeatures = whiten(features)centroids,distortion = kmeans(features,k)code,distance = vq(features,centroids)return code,V
在运行下面代码之前,需要安装scikit-image,记得在自己的虚拟环境下安装(我用pip安装不了,后面改用conda,只要在虚拟环境下,用哪个(pip或conda)都是安装在虚拟环境下)
conda install scikit-image
import cv2
import numpy as np
from pylab import *
from PIL import Image
from skimage.transform import resizeim = Image.open('empire.jpg')
m,n = np.array(im).shape[:2]
# 调整图像的尺寸大小为(wid,wid)
wid = 50rim = im.resize((50,50),Image.BILINEAR)
rim = array(rim,'f')
# 创建归一化割矩阵
# print(rim.shape[:2] )
A = ncut_graph_matrix(rim,sigma_d=1,sigma_g=1e-2)
# 聚类
code,V=cluster(A,k=3,ndim=3)
# 变换到原来的图像大小image=code.reshape(wid,wid)
print(image)codeim = resize(image,(m,n),mode='reflect',anti_aliasing=False,order=0)
# 绘制分割结果
figure()
imshow(codeim)
gray()
show()

9.3 变分法
当优化的对象是函数时,该问题称为变分问题,需要使用ROF进行降噪。
denoise函数需要传入以下参数
- im: 输入的噪声图像(灰度图像)。
- U_init: 对 U(去噪图像)的初始猜测。
- tolerance: 收敛的容忍度,用于判断迭代是否结束。
- tau: 步长(或称为步伐),用于控制更新的幅度。
- tv_weight: 总变差正则化项的权重,控制去噪程度。
denoise函数返回参数
- U: 去噪后的图像。
- im - U: 图像的纹理残差,即原始图像中未被去噪部分的残余。
def denoise(im,U_init,tolerance=0.1,tau=0.125,tv_weight=100):""" 这个函数实现了 Rudin-Osher-Fatemi (ROF) 去噪模型,ROF 模型是一个常用的图像去噪方法,基于总变差(Total Variation, TV)正则化来去除噪声,同时保留图像的边缘信息"""m,n=im.shape #获取图像的高度和宽度#初始化U=U_initPx=im # 对偶域的x分量Py=im # 对偶域的y分量error=1while(error>tolerance):Uold=U#原始变量的梯度GradUx=roll(U,-1,axis=1)-U #变量U梯度的x分量GradUy=roll(U,-1,axis=0)-U #变量U梯度的y分量#更新对偶变量PxNew=Px+(tau/tv_weight)*GradUx #更新PxPyNew=Py+(tau/tv_weight)*GradUy #更新PyNormNew=maximum(1,sqrt(PxNew**2+PyNew**2))#计算PxNew和PyNew的范数,确保其最小值为1Px=PxNew/NormNew #更新x分量Py=PyNew/NormNew #更新y分量RxPx=roll(Px,1,axis=1)#计算Px在x方向上的右移RyPy=roll(Py,1,axis=0)#计算Px在y方向上的下移DivP=(Px-RxPx)+(Py-RyPy)#计算Px和Py的梯度U=im+tv_weight*DivP # 更新去噪后的图像Uerror=linalg.norm(U-Uold)/sqrt(n*m)# 计算当前误差return U,im-U #返回去噪后的图像U和噪声图像
因为 scipy.misc.imsave 已被弃用,所以需要用其他库来完成,这里使用Pillow库来保存图像
import numpy as np
from PIL import Image
im = np.array(Image.open('ceramic-houses_t0.png').convert('L'))
U,T=denoise(im,im,tolerance=0.001)
t=0.4# 基于阈值生成二值图像
binary_image = U < t * U.max()# 将布尔数组转换为 uint8 格式(0 或 255)
binary_image_uint8 = (binary_image * 255).astype(np.uint8)# 创建 Image 对象
img = Image.fromarray(binary_image_uint8)# 保存图像为 PDF
img.save('result.pdf')
from pylab import *
gray()
subplot(121)
imshow(U)
subplot(122)
imshow(img)

相关文章:
【python计算机视觉编程——9.图像分割】
python计算机视觉编程——9.图像分割 9.图像分割9.1 图割安装Graphviz下一步:正文9.1.1 从图像创建图9.1.2 用户交互式分割 9.2 利用聚类进行分割9.3 变分法 9.图像分割 9.1 图割 可以选择不装Graphviz,因为原本觉得是要用,后面发现好像用不…...
北斗赋能万物互联:新质生产力的强劲驱动力
在数字化转型的大潮中,中国自主研制的北斗卫星导航系统,作为国家重大空间基础设施,正以前所未有的力量推动着万物互联时代的到来,成为新质生产力发展的重要基石。本文将深入剖析北斗系统如何以其独特的技术优势和广泛应用场景&…...
时序预测 | Matlab实现GA-CNN遗传算法优化卷积神经网络时间序列预测
时序预测 | Matlab实现GA-CNN遗传算法优化卷积神经网络时间序列预测 目录 时序预测 | Matlab实现GA-CNN遗传算法优化卷积神经网络时间序列预测预测效果基本介绍程序设计参考资料 预测效果 基本介绍 时序预测 | Matlab实现GA-CNN遗传算法优化卷积神经网络时间序列预测ÿ…...
如何保证消息不重复消费
在使用消息队列(Message Queue, MQ)时,确保消息不被重复消费是非常重要的,因为重复消费可能导致数据不一致或者业务逻辑出错。要保证消息不被重复消费,可以采取以下几种策略: 1. 消息确认机制 大多数消息…...
HTTP请求工具类
HTTP请求工具类 import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.net.URL;public class HttpUtils {/*** 发送GET请求并获取响应结果* * param url 请求的URL* return 响应结果…...
谷歌的 DataGemma 人工智能是一个统计精灵
谷歌正在扩大其人工智能模型家族,同时解决该领域的一些最大问题。 今天,该公司首次发布了 DataGemma,这是一对开源的、经过指令调整的模型,在缓解幻觉挑战方面迈出了一步,幻觉是指大型语言模型(LLM…...
【Python爬虫系列】_021.异步请求aiohttp
课 程 推 荐我 的 个 人 主 页:👉👉 失心疯的个人主页 👈👈入 门 教 程 推 荐 :👉👉 Python零基础入门教程合集 👈👈虚 拟 环 境 搭 建 :👉👉 Python项目虚拟环境(超详细讲解) 👈👈PyQt5 系 列 教 程:👉👉 Python GUI(PyQt5)文章合集 👈👈...
源码运行springboot2.2.9.RELEASE
1 环境要求 java 8 maven 3.5.2 2 下载springboot源码 下载地址 https://github.com/spring-projects/spring-boot/releases/tag/v2.2.9.RELEASE 3 修改配置 修改spring-boot-2.2.9.RELEASE/pom.xml 修改spring-boot-2.2.9.RELEASE/spring-boot-project/spring-boot-tools…...
王者荣耀改重复名(java源码)
王者荣耀改重复名 项目简介 “王者荣耀改重复名”是一个基于 Spring Boot 的应用程序,用于生成王者荣耀游戏中的唯一名称。通过简单的接口和前端页面,用户可以输入旧名称并获得一个新的、不重复的名称。 功能特点 生成新名称:提供一个接口…...
Python 全栈系列271 微服务踩坑记
说明 这个坑花了10个小时才爬出来 碰到一个现象:将微服务改造为并发后,请求最初很快,然后就出现大量的失败,然后过一会又能用。 过去从来没有碰到这个问题,要么是一些比较明显的资源,或者逻辑bug࿰…...
环境搭建2(游戏逆向)
#include<iostream> #include<windows.h> #include<tchar.h> #include<stdio.h> #pragma warning(disable:4996) //exe应用程序 VOID PrintUI(CONST CHAR* ExeName, CONST CHAR* UIName, CONST CHAR* color, SHORT X坐标, SHORT y坐标, WORD UIwide, W…...
快手自研Spark向量化引擎正式发布,性能提升200%
Blaze 是快手自研的基于Rust语言和DataFusion框架开发的Spark向量化执行引擎,旨在通过本机矢量化执行技术来加速Spark SQL的查询处理。Blaze在快手内部上线的数仓生产作业也观测到了平均30%的算力提升,实现了较大的降本增效。本文将深入剖析blaze的技术原…...
用网卡的ap模式抓嵌入式设备的网络包
嵌入式设备不像pc上,有一些专门的工具比如wareshark来抓包,嵌入式设备中,有的可能集成了tcpdump,可以用来进行简单的抓包,但是不方便分析,况且有的嵌入式设备不一定就集成了tcpdump工具。 关于tcpdump工具…...
centos 7 升级Docker 与Docker-Compose 到最新版本
一 升级docker 可参考docker官方升级 1, 查看docker 信息 docker info 2,查看docker 版本 docker --version 3 升级前 可停止docker : sudo systemctl stop docker 4 查看已安装的docker 并卸载 [rootlocalhost docker]# yum list installed | grep docker docker.x86…...
Docker_启动redis,容易一启动就停掉
现象以及排查过程 最近在使用docker来搭建redis服务,但是在启动redis哨兵容器时,总是发现这个容器启动后立马就停止了。首先想到的是不是服务器资源不够用了导致的这个现象,排查后发现不是资源问题。再者猜测是不是启动报错了,查看…...
微服务中间件之Nacos
Nacos(Dynamic Naming and Configuration Service)是阿里巴巴开源的一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台。它提供了服务注册与发现、配置管理以及服务健康监测等核心功能,旨在帮助开发人员更轻松地构建和管理微服…...
C++: 类和对象(上)
📔个人主页📚:秋邱-CSDN博客☀️专属专栏✨:C🏅往期回顾🏆:从C语言过渡到C🌟其他专栏🌟:C语言_秋邱 面向过程和面向对象 C 语言被认为是面向过程的编程…...
Unity程序基础框架
概述 单例模式基类 没有继承 MonoBehaviour 继承了 MonoBehaviour 的两种单例模式的写法 缓存池模块 (确实挺有用) using System.Collections; using System.Collections.Generic; using UnityEngine;/// <summary> /// 缓存池模块 /// 知识点 //…...
TiDB 数据库核心原理与架构_Lesson 01 TiDB 数据库架构概述课程整理
作者: 尚雷5580 原文来源: https://tidb.net/blog/beeb9eaf 注:本文基于 TiDB 官网 董菲老师 《TiDB 数据库核心原理与架构(101) 》系列教程之 《Lesson 01 TiDB 数据库架构概述》内容进行整理和补充。 课程链接:…...
计算机毕业设计Python深度学习垃圾邮件分类检测系统 朴素贝叶斯算法 机器学习 人工智能 数据可视化 大数据毕业设计 Python爬虫 知识图谱 文本分类
基于朴素贝叶斯的邮件分类系统设计 摘要:为了解决垃圾邮件导致邮件通信质量被污染、占用邮箱存储空间、伪装正常邮件进行钓鱼或诈骗以及邮件分类问题。应用Python、Sklearn、Echarts技术和Flask、Lay-UI框架,使用MySQL作为系统数据库,设计并实…...
uniapp 对接腾讯云IM群组成员管理(增删改查)
UniApp 实战:腾讯云IM群组成员管理(增删改查) 一、前言 在社交类App开发中,群组成员管理是核心功能之一。本文将基于UniApp框架,结合腾讯云IM SDK,详细讲解如何实现群组成员的增删改查全流程。 权限校验…...
使用van-uploader 的UI组件,结合vue2如何实现图片上传组件的封装
以下是基于 vant-ui(适配 Vue2 版本 )实现截图中照片上传预览、删除功能,并封装成可复用组件的完整代码,包含样式和逻辑实现,可直接在 Vue2 项目中使用: 1. 封装的图片上传组件 ImageUploader.vue <te…...
【Go】3、Go语言进阶与依赖管理
前言 本系列文章参考自稀土掘金上的 【字节内部课】公开课,做自我学习总结整理。 Go语言并发编程 Go语言原生支持并发编程,它的核心机制是 Goroutine 协程、Channel 通道,并基于CSP(Communicating Sequential Processes࿰…...
BCS 2025|百度副总裁陈洋:智能体在安全领域的应用实践
6月5日,2025全球数字经济大会数字安全主论坛暨北京网络安全大会在国家会议中心隆重开幕。百度副总裁陈洋受邀出席,并作《智能体在安全领域的应用实践》主题演讲,分享了在智能体在安全领域的突破性实践。他指出,百度通过将安全能力…...
UR 协作机器人「三剑客」:精密轻量担当(UR7e)、全能协作主力(UR12e)、重型任务专家(UR15)
UR协作机器人正以其卓越性能在现代制造业自动化中扮演重要角色。UR7e、UR12e和UR15通过创新技术和精准设计满足了不同行业的多样化需求。其中,UR15以其速度、精度及人工智能准备能力成为自动化领域的重要突破。UR7e和UR12e则在负载规格和市场定位上不断优化…...
全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比
目录 引言 VPN技术概述 GRE VPN 3.1 GRE封装结构 3.2 GRE的应用场景 GRE over IPsec 4.1 GRE over IPsec封装结构 4.2 为什么使用GRE over IPsec? IPsec VPN 5.1 IPsec传输模式(Transport Mode) 5.2 IPsec隧道模式(Tunne…...
学习STC51单片机32(芯片为STC89C52RCRC)OLED显示屏2
每日一言 今天的每一份坚持,都是在为未来积攒底气。 案例:OLED显示一个A 这边观察到一个点,怎么雪花了就是都是乱七八糟的占满了屏幕。。 解释 : 如果代码里信号切换太快(比如 SDA 刚变,SCL 立刻变&#…...
蓝桥杯 冶炼金属
原题目链接 🔧 冶炼金属转换率推测题解 📜 原题描述 小蓝有一个神奇的炉子用于将普通金属 O O O 冶炼成为一种特殊金属 X X X。这个炉子有一个属性叫转换率 V V V,是一个正整数,表示每 V V V 个普通金属 O O O 可以冶炼出 …...
R 语言科研绘图第 55 期 --- 网络图-聚类
在发表科研论文的过程中,科研绘图是必不可少的,一张好看的图形会是文章很大的加分项。 为了便于使用,本系列文章介绍的所有绘图都已收录到了 sciRplot 项目中,获取方式: R 语言科研绘图模板 --- sciRplothttps://mp.…...
怎么让Comfyui导出的图像不包含工作流信息,
为了数据安全,让Comfyui导出的图像不包含工作流信息,导出的图像就不会拖到comfyui中加载出来工作流。 ComfyUI的目录下node.py 直接移除 pnginfo(推荐) 在 save_images 方法中,删除或注释掉所有与 metadata …...
