OpenCV基础(1)

目录

安装OpenCV

读取图像

显示图像

cv2.waitKey()函数

cv2.destroyAllWindows()函数

保存图像

读取视频

开启摄像头

图像处理

像素处理

二值图像及灰度图像

彩色图像及通道处理

调整图像大小

感兴趣区域

掩模

掩模基础及构造

掩模作为函数参数

色彩处理

色彩空间基础

GRAY色彩空间

HSV色彩空间

色调H

饱和度S

明度V

色彩空间转换

获取皮肤范围


安装OpenCV

WIN+R输入cmd打开命令运行窗口,输入以下指令:

pip install opencv-python
pip install opencv-contrib-python

安装成功后会显示以下界面

读取图像

OpenCV提供了函数cv2.imread()来读取图像,语法格式如下:

image = cv2.imread( filename[, flags] )

其中:

  • retval 是返回值,其值是读取到的图像。若未读取到图像,则返回“None”。
  • filename 表示要读取的图像的完整文件名。
  • flags 是读取标记。该标记用来控制读取文件的类型,其主要值如下表 所示。表 中 的第 1 列值与第 3 列数值是等价的,在设置参数时,既可以使用第 1 列的值,也可以使 用第 3 列的数值。

import cv2 
lena=cv2.imread("lena.bmp") 
print(lena)

显示图像

函数cv2.imshow()用来显示图像,语法格式为

cv2.imshow( winname, mat )

其中:

  • winname 是窗口名称。
  • mat 是要显示的图像。

这里介绍一下访问路径的方式:

  • 绝对路径:使用完整的路径名访问文件,如“E:\lesson\lena.jpg”
  • 相对路径:从当前路径开始的路径。假如当前路径为E:\lesson,使用“lena=cv2.imread("lena.jpg")”语句读取文件lena.jpg时,实际上读取的是“E:\lesson\lena.jpg”。

cv2.waitKey()函数

函数 cv2.waitKey()用来等待按键,当用户按下按键后,该语句会被执行,并获取返回值,
其语法格式为
cv2.waitKey( [delay] )

delay表示延时时长,当改值为负数或0时,表示无限等待。默认为0

cv2.destroyAllWindows()函数

函数 cv2.destroyAllWindows()用来释放(销毁)所有窗口,其语法格式为
 cv2.destroyAllWindows( )
import cv2 
lena=cv2.imread("lena.bmp") 
cv2.imshow("demo1", lena ) 
cv2.imshow("demo2", lena ) 
cv2.waitKey() 
cv2.destroyAllWindows()

保存图像

OpenCV 提供了函数 cv2.imwrite()来保存图像,该函数的语法格式为
image = cv2.imwrite( filename, img[, params] )

其中:

  • retval 是返回值。若保存成功,则返回逻辑值真(True);否则,返回逻辑值假(False)。
  • filename 是要保存的目标文件的完整路径名,包含文件扩展名。
  • img 是被保存图像的名称。
import cv2 
lena=cv2.imread("lena.bmp") 
r=cv2.imwrite("result.bmp",lena)

读取视频

函数cv2.VideoCapture()可读取视频,其语法格式为

cap = cv2.VideoCapture(视频源)

这里的视频源可以是:

  • 一个表示设备索引的整数(例如,0 表示第一个摄像头)。
  • 一个表示视频文件的文件路径字符串。
如果你想打开第一个摄像头,你可以这样写:
cap = cv2.VideoCapture(0)
如果你想打开一个视频文件,可以这样写:
cap = cv2.VideoCapture('path_to_your_video.mp4')

使用cv2.VideoCappture捕获视频时,通常的流程是:

  1. 创建cv2.VideoCappture对象。
  2. 使用循环读取视频的每一帧。
  3. 对每一帧进行处理。
  4. 显示帧(如果需要)。
  5. 释放 cv2.VideoCappture对象并关闭窗口。
import cv2
cap = cv2.VideoCapture("test.mp4")
while True:success, img = cap.read()cv2.imshow("Result", img)if cv2.waitKey(1) & 0xFF == ord('q'):break

开启摄像头

import cv2
frameWidth = 640
frameHeight = 480
cap = cv2.VideoCapture(0)
cap.set(3, frameWidth) #设置宽度
cap.set(4, frameHeight) #设置高度
cap.set(10,150) #设置亮度
while True:success, img = cap.read()cv2.imshow("Result", img)if cv2.waitKey(1) & 0xFF == ord('q'):break
cap.release()
cv2.destroyAllWindows()

图像处理

像素处理

图像是由多个像素点堆叠而成,像素处理是对图像处理的基本操作,可以通过索引对图像内的元素进行访问和处理。OpenCV中像素数据类型为无符号的8位二进制数,范围在[0, 255],0表示黑色,255表示白色(这里可以理解为亮度,数值越大就越亮).

二值图像及灰度图像

二值图像表示只有黑白(0和255),而灰度图像表示由多种不同数值的像素堆叠([0,255])。可以将二值图像理解为特殊的灰度图,因此后面主要对灰度图进行说明。

可以将图像理解为一个矩阵,在 OpenCV 中,图像就是 NumPy 库中的数组 ,一个灰度图像是一个二维数组,可以通过索引访问其中的像素值。例如,可以使用 image[0,0]访问图像 image 第 0 行第 0 列位置上的像素点,第 0 行第 0 列位于图像的左上角,其中第 1 个索引“0”表示第 0 行,第 2 个索引“0”表示第 0 列,如下图所示。

示例:读取一个灰度图像,并对其像素进行访问、修改
import cv2img = cv2.imread(r"D:\Anaconda3\Pytorch\opencvbegin\mycat.png")
cv2.imshow("before", img)
print("img[50,90]原始值:", img[50, 90])
img[10:100, 80:100] = 255
print("img[50,90]修改值:", img[50, 90])
cv2.imshow("after", img)
cv2.waitKey()
cv2.destroyAllWindows()

程序使用切片方式将图像 img 中第 10 行到第 99 行与第 80 列到第 99 列交叉区域内的像素值设置为 255。从图像 img 来看,该交叉区域被设置为白色。

彩色图像及通道处理

彩色图像是由红色(R)、绿色(G)、蓝色(B)等三种颜色组成,而这也就是三基色。

在计算机中,RGB 模式是一种被广泛采用的模式,该模式采用 R(Red,红色)、G(Green,
绿色)、B(Blue,蓝色)三个分量来表示不同颜色。R、G、B 分别对应三种颜色分量的大小,
每个分量值的范围都为[0, 255]。通过组合不同的颜色分量就会得到不同的彩色图像。
通常情况下,在计算机中存储 RGB 模式的像素点时,不是把三个色彩分量的值保存在一起,
而是单独存放每个色彩分量的值。RGB 色彩空间中存在 R 通道、G 通道和 B 通道三个通道。
每个色彩通道值的范围都为[0, 255],我们用这三个色彩通道的组合表示颜色。
需要注意的是,OpenCV 中的通道是按照 B 通道→G 通道→R 通道的顺序存储的。
针对 RGB 图像,可以分别拆分出其 R 通道、G 通道、B 通道。在 OpenCV 中,通过索引可以直接将各个通道从图像内提取出来。例如,针对 OpenCV 内的 BGR 图像 img,可用如下语句分别从中提取 B 通道、G 通道、R 通道:
b = img[ : , : , 0 ] 
g = img[ : , : , 1 ] 
r = img[ : , : , 2 ]
除了使用索引,还可以使用函数 cv2.split() 来拆分图像的通道。例如,可以使用如下语句拆
分彩色 BGR 图像 img ,得到 B 通道图像 b G 通道图像 g R 通道图像 r
b,g,r=cv2.split(img) 
上述语句与如下语句是等价的:
b=cv2.split(img)[0] 
g=cv2.split(img)[1] 
r=cv2.split(img)[2]
import cv2image = cv2.imread(r"D:\Anaconda3\Pytorch\opencvbegin\dog.jpg")
red_channel = image[:, :, 2]
green_channel = image[:, :, 1]
blue_channel = image[:, :, 0]
cv2.imshow('original', image)
cv2.imshow('Red Channel', red_channel)
cv2.imshow('Green Channel', green_channel)
cv2.imshow('blue Channel', blue_channel)
cv2.waitKey()
cv2.destroyAllWindows()

对彩色图像既然可以拆分那就当然也可以合并了。函数 cv2.merge()可以实现通道合并。例如,使用函数 cv2.merge()将 B 通道图像 b、G 通道图像 g 和 R 通道图像 r 这三幅通道图像合并为一幅 BGR 的三通道彩色图像,实现的语句为

bgr=cv2.merge([b,g,r])

调整图像大小

用函数 cv2.resize()实现对图像的缩放,该函数的具体形式为
dst = cv2.resize( src, dsize[, fx[, fy[, interpolation]]] )

其中:

  • dst 代表输出的目标图像。
  • src 代表需要缩放的原始图像。
  • dsize 代表输出图像大小。
  • fx 代表水平方向的缩放比例。
  • fy 代表垂直方向的缩放比例。
  • interpolation 代表插值方式。
cv2.resize()函数中,目标图像的大小可以通过参数 dsize 或者参数 fx 和 fy 来指定,具体如下。
● 情况 1:通过参数 dsize 指定。
在指定参数 dsize 的值后,参数 fx 和 fy 的值将不会起作用,目标图像直接由参数 dsize 决定大小。需要注意的是,dsize 内第 1 个参数对应缩放后图像的宽度(width,即列数 cols,与参数 fx
类似),第 2 个参数对应缩放后图像的高度(height,即行数 rows,与参数 fy 类似)。
● 情况 2:通过参数 fx 和 fy 指定。 如果参数 dsize 的值是 None,那么目标图像的大小将由参数 fx 和 fy 决定。此时,目标图像的大小为
dsize=Size(round(fx*src.cols),round(fy*src.rows))

插值这里不做过多说明,后面会出文章进行讲解。敬请期待吧!

import cv2img = cv2.imread(r"D:\Anaconda3\Pytorch\opencvbegin\dog.jpg")
rows, cols = img.shape[:2]
size = (int(cols * 0.9), int(rows * 0.5))
rst = cv2.resize(img, size)
cv2.imshow("original", img)
cv2.imshow("after", rst)
print("img.shape=", img.shape)
print("rst.shape=", rst.shape)
cv2.waitKey()
cv2.destroyAllWindows()

感兴趣区域

在图像处理过程中,我们可能会对图像的某一个特定区域感兴趣,该区域被称为感兴趣区
域( Region of Interest ROI )。在设定 ROI 后,可以对该区域进行整体操作。
ROI 示意图如图 示,假设当前图像的名称为 img ,图中的数字分别表示行号和列号,则右图 中的 ROI (黑色区域)可以表示为 img[200:400, 200:400]
a=img[200:400,200:400] 
img[200:400,600:800]=a

import cv2
a=cv2.imread("dog.jpg")
face=a[220:370,250:350]
cv2.imshow("original",a)
cv2.imshow("face",face)
cv2.waitKey()
cv2.destroyAllWindows()

掩模

图像掩模是指,用选定的图像、图形或物体遮挡待处理的图像(全部或局部),从而控制图像处理的区域。

掩模基础及构造

为了方便理解,可以将掩模图像看作一块玻璃板,玻璃板上的白色区域是透明的,黑色区域是不透明的。掩模运算就是将该玻璃板覆盖在原始图像上,透过玻璃板显示出来的部分就是掩模运算的结果图像。在运算中,只有被掩模指定的部分参与运算,其余部分不参与运算。
在构造掩模图像时,通常先构造一个像素值都是 0 的数组,再将数组中指定区域的像素值设定为255(或 1 或其他非 0 值)。
将掩模图像与原始图像相乘,可以得到掩模图像指定的图像区域。例如,乘法运算“mask*原始图像”使得原始图像中与 mask 中像素值 0(背景)对应位置上的像素值被处理为 0(背景);与 mask 中像素值 1(前景)对应位置上的像素值保持不变(前景)。
import cv2
import numpy as np
o=cv2.imread("dog.jpg",1)
h,w,c=o.shape
m=np.zeros((h,w,c),dtype=np.uint8)
m[100:400,200:400]=1
m[100:500,100:200]=1
result=m*o
cv2.imshow("o",o)
cv2.imshow("mask",m*255) # m*255,确保能显示
cv2.imshow("result",result)
cv2.waitKey()
cv2.destroyAllWindows()

掩模作为函数参数

计算结果=cv2.add(参数 1,参数 2,掩模)
当使用掩模参数时,操作只会在掩模值为非空的像素点上执行,并将其他像素点的像素值置
为 0。 
import cv2
import numpy as npo = cv2.imread("dog.jpg")
t = cv2.imread("lucky.jpg")
h, w, c = o.shape
t = cv2.resize(t, (w, h))
m = np.zeros((h, w), dtype=np.uint8)
m[100:400, 200:400] = 255
m[100:450, 100:200] = 255
r = cv2.add(o, t, mask=m)
cv2.imshow("Original", o)
cv2.imshow("Text", t)
cv2.imshow("Mask", m)
cv2.imshow("Result", r)
cv2.waitKey(0)
cv2.destroyAllWindows()

色彩处理

RGB 色彩空间是一种比较常见的色彩空间,除此之外比较常见的色彩空间还包括 GRAY 色彩空间(灰度图像)、YCrCb 色彩空间、HSV 色彩空间、HLS 色彩空间、CIEL*a*b*色彩空间、CIEL*u*v*色彩空间、Bayer 色彩空间等。
不同的色彩空间是图像的不同表示形式。每个色彩空间都有自己擅长处理的问题,要针对处理的问题,选用不同的色彩空间。

色彩空间基础

这个部分我们主要介绍GRAY和HSV色彩空间。

GRAY色彩空间

当图像由 RGB 色彩空间转换至 GRAY 色彩空间时,其处理方式如下:

当图像由 GRAY 色彩空间转换至 RGB 色彩空间(或 BGR 色彩空间)时,最终所有通道的
值都将是相同的,其处理方式如下:
R = GRAY
G = GRAY
B = GRAY

注意:GRAY转换时也代表着通道数目的转换,灰度图一般是单通道图像([0,255]),而RGB是3通道图像。

HSV色彩空间

HSV主要包含色调、饱和度、明度三要素。

色调H

色调指光的颜色。在HSV 色彩空间中,色调 H 的取值范围是[0,360],色调值为 0 表示红色,色调值为 300 表示品红色。8 位位图内每个像素点能表示的值有 28 =256 个,所以在 8 位位图内表示 HSV 图像时要把色调在[0,360]范围内的值映射到[0,255]范围内。OpenCV 直接把色调的值除以 2,得到介于[0,180]的值,以适应 8 位二进制数(256 个灰度级)的存储和表示范围。

饱和度S
饱和度指色彩的鲜艳程度,表示色彩的相对纯净度。饱和度取决于色彩中灰色的占比,灰色占比越小,饱和度越高;灰色占比越大,饱和度越低。
饱和度等于所选颜色的纯度值和该颜色最大纯度值之间的比值,取值范围为[0,1]。当饱和度的值为 0 时,只有灰度。进行色彩空间转换后,为了适应 8 位位图的 256 个灰度级,需要将新色彩空间内的数值映射至[0,255]范围内。也就是说,要将饱和度的值从[0,1]映射到[0,255]。
明度V
明度指人眼感受到的色彩的明亮程度,反映的是人眼感受到的光的明暗程度。对于彩色图像来讲,明度值越高,图像越明亮;明度值越低,图像越暗淡。明度的范围与饱和度的范围一致,都是[0,1]。同样,明度值在 OpenCV 内也被映射到[0,255]。

色彩空间转换

cv2.cvtColor()函数实现色彩空间的转换,语法格式为
dst = cv2.cvtColor( src, code [, dstCn] )

其中:

  • dst 表示输出图像,与原始输入图像具有相同的数据类型和深度。
  • src 表示原始输入图像。可以是 8 位无符号图像、16 位无符号图像,或者单精度浮点数 图像等。
  • code 是色彩空间转换码,表 3-6 展示了部分常见的 code 值。
  • dstCn 是目标图像的通道数。如果参数为默认值 0,那么通道数自动通过原始输入图像和
  • code 得到。

获取皮肤范围

HSV 色彩空间中,H 通道(色相 Hue 通道)对应不同的颜色。换个角度理解,颜色的差异主要取决于 H 通道值。所以,通过筛选 H 通道值,能够筛选出特定的颜色。例如,在一幅HSV 图像中,如果通过控制仅将 H 通道内的值为 240(在 OpenCV 内被调整为 120)的像素点显示出来,那么就会只显示蓝色部分图像。
函数 cv2.inRange()判断图像内像素点的像素值是否在指定的范围内,其语法格式为
dst = cv2.inRange( src, lowerb, upperb )

其中:

  • dst 表示输出结果,大小和 src 一致。
  • src 表示要检查的数组或图像。
  • lowerb 表示范围下界。
  • upperb 表示范围上界。
  • 若 src 值处于该指定区间内,则 dst 中对应位置上的值为 255。
  • 若 src 值不处于该指定区间内,则 dst 中对应位置上的值为 0。
肤色范围划定为
  • 色调值为[0,33]。
  • 饱和度值为[10, 255]。
  • 明度值为[80,255]。
import cv2
import numpy as np
img=cv2.imread("77.png")
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
min_HSV = np.array([0 ,10,80], dtype = "uint8")
max_HSV = np.array([33, 255, 255], dtype = "uint8")
mask = cv2.inRange(hsv, min_HSV, max_HSV)
reusult = cv2.bitwise_and(img,img, mask= mask)
cv2.imshow("img",img)
cv2.imshow("reusult",reusult)
cv2.waitKey()
cv2.destroyAllWindows()

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/41391.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

CSRF漏洞攻击

05-CSRF 1 CSRF概述 1.1 概述 CSRF (Cross-Site Request Forgery) 跨站请求伪造,也可称为一键式攻击 (one-click-attack),通常缩写为 CSRF 或者 XSRF。 CSRF 攻击是一种挟持用户在当前已登录的浏览器上发送恶意请求的攻击方法。相对于XSS利用用户对指…

wsl安装Linux系统到指定位置

默认情况下,wsl安装的系统,会安装到系统C盘,长期下去,很容易把C盘的空间消耗完,从而影响系统的正常运行,所以我建议是将wsl所有的系统都安装到其它磁盘中,便于维护。 1、导出镜像 通过wsl -l -v 查看当前已安装的系统版本。 导出到当前目录位置,也可以指定目录位置。 w…

docker集群部署主从mysql

搭建一个mysql集群,1主2从,使用docker容器 一、创建docker的mysql镜像 下次补上,因为现在很多网络不能直接pull,操作下次补上。 二、创建mysql容器 创建容器1 docker run -it -d --name mysql_1 -p 7001:3306 --net mynet --…

《昇思25天学习打卡营第10天|使用静态图加速》

文章目录 今日所学:一、背景介绍1. 动态图模式2. 静态图模式 三、静态图模式的使用场景四、静态图模式开启方式1. 基于装饰器的开启方式2. 基于context的开启方式 总结: 今日所学: 在上一集中,我学习了保存与加载的方法&#xff…

昇思25天学习打卡营第6天|简单的深度学习模型实战 - 函数式自动微分

自动微分(Automatic Differentiation)是什么?微分是函数在某一处的导数值,自动微分就是使用计算机程序自动求解函数在某一处的导数值。自动微分可用于计算神经网络反向传播的梯度大小,是机器学习训练中不可或缺的一步。 这些公式难免让人头大…

论文浅尝 | 从最少到最多的提示可在大型语言模型中实现复杂的推理

笔记整理:王泽元,浙江大学博士 链接:https://openreview.net/forum?idWZH7099tgfM 1. 动机 尽管深度学习已经取得了巨大的成功,但它与人类智慧仍然存在一些明显差距。这些差距包括以下几个方面:1)学习新任…

【代码大全2 选读】看看骨灰级高手消灭 if-else 逻辑的瑞士军刀长啥样

文章目录 1 【写在前面】2 【心法】这把瑞士军刀长啥样3 【示例1】确定某个月份的天数(Days-in-Month Example)4 【示例2】确定保险费率(Insurance Rates Example)5 【示例3】灵活的消息格式(Flexible-Message-Format …

14-27 剑和诗人 1 – 请称呼我AI工程师

​​​​​ 仅初创企业的收入就超过 10 亿美元,随着 Gen AI 的早期成功迹象,每家有远见的科技公司都在竞相将 Gen AI 功能融入其产品、客户支持机器人和营销中。作为一种技术,AI 正处于与 90 年代末互联网相似的阶段,甚至完全相同…

【unity实战】Unity中使用A*寻路+有限状态机制作一个俯视角敌人AI

最终效果 文章目录 最终效果前言A*寻路插件介绍下载导入AI插件生成寻路网格节点的类型障碍物寻路测试A*只打印报错信息 代码控制寻路动画配置敌人状态机各种状态脚本效果完结 前言 前面做过有限状态机制作一个敌人AI:【unity实战】在Unity中使用有限状态机制作一个…

vxe-table合并行数据;element-plus的el-table动态合并行

文章目录 一、vxe-table合并行数据1.代码 二、使用element-plus的el-table动态合并行2.代码 注意&#xff1a;const fields 是要合并的字段 一、vxe-table合并行数据 1.代码 <vxe-tableborderresizableheight"500":scroll-y"{enabled: false}":span-m…

信创-办公软件应用工程师认证

随着国家对信息技术自主创新的战略重视程度不断提升&#xff0c;信创产业迎来前所未有的发展机遇。未来几年内&#xff0c;信创产业将呈现市场规模扩大、技术创新加速、产业链完善和国产化替代加速的趋势。信创人才培养对于推动产业发展具有重要意义。应加强高校教育、建立人才…

【信息学奥赛】CSP-J/S初赛07 排序算法及其他算法在初赛中的考察

本专栏&#x1f449;CSP-J/S初赛内容主要讲解信息学奥赛的初赛内容&#xff0c;包含计算机基础、初赛常考的C程序和算法以及数据结构&#xff0c;并收集了近年真题以作参考。 如果你想参加信息学奥赛&#xff0c;但之前没有太多C基础&#xff0c;请点击&#x1f449;专栏&#…

C++|海康摄像头实时预览时设置音量大小

使用海康API设置音量的函数是&#xff1a;NET_DVR_OpenSound。 在实际代码中我遇到了以下问题&#xff1a; 1&#xff1a;调用NET_DVR_OpenSound接口一直返回失败&#xff0c;错误是调用顺序出错。 2&#xff1a;音量设置不成功。 对于以上两种问题&#xff0c;我相信很多人…

FineBI在线学习资源-数据处理

FineBI在线学习资源汇总&#xff1a; 学习资源 视频课程 帮助文档 问答 数据处理学习文档&#xff1a; 相关资料&#xff1a; 故事背景概述-https://help.fanruan.com/finebi6.0/doc-view-1789.html 基础表处理-https://help.fanruan.com/finebi6.0/doc-view-1791.html …

六西格玛绿带培训如何告别“走过场”?落地生根

近年来&#xff0c;六西格玛绿带培训已经成为了众多企业提升管理水平和员工技能的重要途径。然而&#xff0c;不少企业在实施六西格玛绿带培训时&#xff0c;往往陷入形式主义的泥潭&#xff0c;导致培训效果大打折扣。那么&#xff0c;如何避免六西格玛绿带培训变成“走过场”…

【重磅】万能模型-直接能换迪丽热巴的模型

万能模型&#xff0c;顾名思义&#xff0c;不用重新训练src&#xff0c;直接可以用的模型&#xff0c;适应大部分原视频脸 模型用法和正常模型一样&#xff0c;但可以跳过训练阶段&#xff01;直接到合成阶段使用该模型 本模型没有做Xseg&#xff0c;对遮挡过多的画面不会自动适…

【C++】 解决 C++ 语言报错:Double Free or Corruption

文章目录 引言 双重释放或内存破坏&#xff08;Double Free or Corruption&#xff09;是 C 编程中常见且严重的内存管理问题。当程序尝试多次释放同一块内存或对已经释放的内存进行操作时&#xff0c;就会导致双重释放或内存破坏错误。这种错误不仅会导致程序崩溃&#xff0c…

谷粒商城学习-07-虚拟机网络设置

文章目录 一&#xff0c;找到配置文件Vagrantfile二&#xff0c;查询虚拟机网卡地址1&#xff0c;查看虚拟机网络配置2&#xff0c;查看宿主机网络配置 三&#xff0c;修改配置文件下的IP配置四&#xff0c;重新启动虚拟机即可生效五&#xff0c;Vagrantfile 的作用1&#xff0…

Java项目:基于SSM框架实现的校园快递代取管理系统【ssm+B/S架构+源码+数据库+毕业论文】

一、项目简介 本项目是一套基于SSM框架实现的校园快递代取管理系统 包含&#xff1a;项目源码、数据库脚本等&#xff0c;该项目附带全部源码可作为毕设使用。 项目都经过严格调试&#xff0c;eclipse或者idea 确保可以运行&#xff01; 该系统功能完善、界面美观、操作简单、…

Solo 开发者周刊 (第12期):连接独立开发者,共享开源智慧

这里会整合 Solo 社区每周推广内容、产品模块或活动投稿&#xff0c;每周五发布。在这期周刊中&#xff0c;我们将深入探讨开源软件产品的开发旅程&#xff0c;分享来自一线独立开发者的经验和见解。本杂志开源&#xff0c;欢迎投稿。 产品推荐 1、Soju————一个现代的书签…