当前位置: 首页 > news >正文

【OpenCV入门】第一部分——图像处理基础

本文结构

  • 图像处理的基本操作
    • 读取图像
      • imread()
    • 显示图像
      • imshow()
      • waitKey()
      • destroyAllWindows()
    • 保存图像
      • imwrite()
    • 获取图像属性
  • 像素
    • 确定像素的位置
    • 获取像素的BGR值
    • 修改像素的BGR值
  • 色彩空间
    • GRAY色彩空间
      • cvtColor()——从BGR色彩空间转换到GRAY色彩空间
    • HSV色彩空间
      • 从BGR色彩空间转换到HSV色彩空间
  • 通道
    • 拆分通道
      • 拆分一幅BGR图像中的通道
      • 拆分一幅HSV图像中的通道
    • 合并通道
    • 综合运用拆分通道和合并通道
    • alpha通道

图像处理的基本操作

图像处理包括4个基本操作:读取图像显示图像保存图像获取图像属性

读取图像

imread()

image = cv2.imread(filename,flags)
  • filename:目标图像的完整路径名。
  • flags:图像的颜色类型的标记,有0和1两个值,其中1为默认值。当读取一幅彩色图像时,如果想要得到一幅彩色图像,那么flags的值为1(此时flags的值可以省略);想要得到一幅灰度图像则为0。
  • image:是imread()方法的返回值,返回的是读取到的彩色图像或者灰度图像。

其实就是读取了一个存在filename路径的图片,然后用image去表示这个图片而已(image只是一个举例,你爱叫啥叫啥),flags是0还是1取决于你想要彩图还是灰白图。

实例1: 读取当前项目目录下的图像
在PyCharm中的Demos项目下,有一幅名为1.jpg的图像。
现在先使用imread()方法读取1.jpg,再使用print()方法打印1.jpg。代码如下所示:

import cv2 # 导入库image = cv2.imread("1.jpg",1) # 读取1.jpg,等价于image = cv2.imread("1.jpg")
print(image) # 打印1.jpg

部分结果如下:
图中输出的数字是1.jpg的部分像素值。图中输出的数字是1.jpg的部分像素值。

如果图像存储在电脑C盘中,示例代码如下:

import cv2 #opencv读取的格式是BGRimg = cv2.imread('C:/Users/lenovo/Pictures/Saved Pictures/castle.jpg') # 路径中不能出现中文
print(image)

注意:“D:/1.jpg"等价于"D:\1.jpg”

显示图像

imshow()

imshow()方法用于显示图像:

cv2.imshow(winname,mat)
  • winname: 显示图像的窗口名称。
  • mat: 要显示的图像

waitKey()

waitKey()方法用于等待用户按下键盘上的某个按键时将执行waitKey()方法,并且获取与这个按键相对应的ASCII码:

retval = cv2.waitKey(delay)
  • delay:等待用户按下键盘上按键的时间,单位为毫秒(ms)。当delay的值为负数,0或者空时,表示无限等待用户按下键盘上按键的时间。
  • retval:与被按下的按键相对应的ASCII码。例如ESC键的ASCII码是27,当用户按下该键时,waitKey()方法的返回值为27.如果没有按键被按下,waitKey()方法的返回值是-1。

destroyAllWindows()

destroyAllWindows()方法用于销毁所有正在显示图像的窗口:

cv2.destroyAllWindows()

实例2: 窗口显示图像

import cv2image = cv2.imread("1.jpg", 1)  # 读取1.jpg
cv2.imshow("image",image)       # 在名为 image 的窗口中显示1.jpg
cv2.waitKey()                   # 按下任何键盘按键中
cv2.destroyAllWindows()         # 销毁所有窗口

结果如下:
在这里插入图片描述
如果想设置窗口显示图像的时间为5s,示例代码如下:

import cv2image = cv2.imread("1.jpg", 1)  # 读取1.jpg
cv2.imshow("image",image)       # 在名为 image 的窗口中显示1.jpg
cv2.waitKey(5000)               # 括号内单位为ms
cv2.destroyAllWindows()         # 销毁所有窗口

注意:

  • 显示图像的窗口名称不能是中文,否则会乱码。
  • 为了能够正常显示图像,要在cv2.imshow()后紧跟着cv2.waitKey()。

保存图像

imwrite()

imwrite()可按照指定路径保存图像

cv2.imwrite(filename,img)
  • filename: 保存图像时所用的完整路径
  • img: 要保存的图像

实例3: 保存图像

import cv2image = cv2.imread("1.jpg", 1)  # 读取1.jpg
cv2.imwrite("D:/Pictures/1.jpg",image) # 把1.jpg保存为D盘根目录下,Pictures文件夹中的1.jpg

注意: 运行上述代码前,要在E盘根目录下新建一个空的Pictures文件夹

获取图像属性

处理图像的过程中,经常需要获取图像的大小、类型等图像属性。为此,OpenCV提供了shape、size和dtype这3个常用属性。

  • shape: 如果是彩色图像,那么获取的是一个包含图像的像素行数、像素列数、通道数的数组,数组的格式为(像素行数,像素列数,通道数);如果是灰度图像,那么获取的是一个包含图像的像素列数、像素行数的数组,数组的格式为(像素行数,像素列数)
  • size: 获取的是图像包含的像素总数,其值为像素行数×像素列数×通道数(灰度图像的通道数为1)
  • dtype: 获取的是图像的数据类型

实例4: 打印彩色图像和灰度图像的属性

import cv2image_Color = cv2.imread("1.jpg", 1)  # 读取1.jpg
print("获取彩色图像的属性:")
print("shape =",image_Color.shape) #打印彩色图像的(像素行数,像素列数,通道数)
print("size =",image_Color.size) #打印彩色图像包含的像素总数
print("dtype =",image_Color.dtype) #打印彩色图像的数据类型image_Gray = cv2.imread("1.jpg", 0)  # 读取1.jpg的灰度图像
print("获取灰度图像的属性:")
print("shape =",image_Gray.shape) #打印灰度图像的(像素行数,像素列数)
print("size =",image_Gray.size) #打印灰度图像包含的像素总数
print("dtype =",image_Gray.dtype) #打印灰度图像的数据类型

结果如下:
在这里插入图片描述

像素

像素是构成数字图像的基本单位。将电脑上的一幅图片放大,会发现图像是由许多个小方块组成的,通常把一个小方块称作一个像素。因此,一个像素是具有一定面积的一个块,而不是一个点。需要注意的是,像素的形状是不固定的,大多数情况下,像素被认为是方形的,但有时也可能是圆形的或者是其他形状的。

确定像素的位置

在OpenCV中,正确表示图像中某个像素坐标的格式为 (y,x) ,方向示意图如下:
在这里插入图片描述

实例5: 表示图中的指定像素

import cv2image = cv2.imread("1.jpg", 1)  # 读取1.jpg
px = image[50,30] # 坐标(50,30)上的像素

获取像素的BGR值

人眼能够感知红色、绿色和蓝色这3种不同的颜色,称为三基色。计算机利用色彩空间对颜色进行编码,把与“三基色”对应的色彩空间称作“RGB色彩空间”。

在RGB色彩空间种包含3个通道:R通道、G通道、B通道,分别代表红色通道、绿色通道、蓝色通道,每个通道都在区间[0,255]内进行取值。这样,计算机通过为这3个色彩通道取不同的值来表示不同的颜色。

OpenCV默认的通道顺序是B->G->R。也就是说,当OpenCV获取图像内某个像素的值时,这个值指的是这个像素的BGR值,OpenCV默认使用的色彩空间是BGR色彩空间。
在实例5中,凭借一个标签px就成功地表示了坐标(50,30)上的像素。如果使用print()方法打印这个像素,就会得到这个像素的BGR值。

import cv2image = cv2.imread("1.jpg", 1)  # 读取1.jpg
px = image[50,30] # 坐标(50,30)上的像素,同时获取三个通道的值
blue = image[50, 30, 0]  # 坐标(50,30)上的像素的B通道的值
green = image[50, 30, 1]  # 坐标(50,30)上的像素的G通道的值
red = image[50, 30, 2]  # 坐标(50,30)上的像素的R通道的值
print(px)
print(blue,green,red)

结果如下:
在这里插入图片描述

修改像素的BGR值

import cv2image = cv2.imread("1.jpg", 1)  # 读取1.jpg
px = image[50, 30]  # 坐标(50,30)上的像素
print("像素的初试BGR值是:",px)
px = [255,255,255] # 把坐标上的像素的值修改为[255,255,255]
print("像素修改后的BGR值是:",px)

结果如下:
在这里插入图片描述
当图像中的每个像素的B、G、R这3个数值相等时,就可以得到灰度图像。其中,当B = G = R = 0时,像素呈现纯黑色;当B = G = R = 255时,像素呈现纯白色

实例6: 修改图像中的指定区域内的所有像素
在图像上设定4个点,将4个点围成的区域内的所有像素都修改为白色。

import cv2image = cv2.imread("1.jpg", 1)  # 读取1.jpg
cv2.imshow("img_01", image)  # 显示图像
for i in range(241, 292):  # i表示横坐标,在区间[241,291]内取值for j in range(168, 219):  # j表示纵坐标,在区间[168,218]内取值image[i, j] = [255, 255, 255]  # 把区域内的所有像素都修改为白色
cv2.imshow("img_02", image)  # 显示像素被修改后的图像
cv2.waitKey()
cv2.destroyAllWindows()  # 关闭所有的窗口时,销毁所有窗口

结果如下:
在这里插入图片描述

色彩空间

上文中简单介绍了RGB色彩空间和BGR色彩空间。接下来将介绍在OpenCV中另外两个比较常见的色彩空间:GRAY色彩空间和HSV色彩空间。

GRAY色彩空间

GRAY色彩空间通常指的是灰度图像。灰度图像是一种每个像素都是从黑到白,被处理为256个灰度级别的单色图像。这256个灰度级别分别用区间[0,255]中的数值表示。“0”表示黑色,“255”表示白色,0~255之间的数值表示不同亮度(即色彩的深浅程度)的深灰色和浅灰色。

cvtColor()——从BGR色彩空间转换到GRAY色彩空间

OpenCV可以使用imread()方法把图片读取为灰度图像。除此之外,OpenCV还提供了cvtColor()方法用于转换图像的色彩空间。

dst = cv2.cvtColor(src,code)
  • src: 转换色彩空间前的初始图象
  • code: 色彩空间转换码
  • dst: 转换色彩空间后的图像

当一幅彩色图像从BGR色彩空间转换到GRAY色彩空间时,需要使用的色彩空间转换码时cv2.COLOR_BGR2GRAY。

实例7: 从BGR色彩空间转换到GRAY色彩空间

import cv2image = cv2.imread("1.jpg", 1)  # 读取1.jpg
cv2.imshow("img_01", image)  # 显示图像
# 将1.jpg从BGR色彩空间转换到GRAY色彩空间
gray_image = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)
cv2.imshow("GRAY", gray_image)  # 显示灰度图像
cv2.waitKey()
cv2.destroyAllWindows()  # 关闭所有的窗口时,销毁所有窗口

结果如下;
在这里插入图片描述
虽然色彩空间类型转换是双向的,而且OpenCV也提供了cv2.COLOR_GRAY2BGR这个色彩空间转换码,但是灰度图像是无法转换成彩色图像的。这是因为在彩色图像转换成灰度图像的过程中,已经丢失了颜色比例。

HSV色彩空间

RGB色彩空间是基于三基色而言的,即红色、绿色和蓝色。而HSV色彩空间则是基于色调、饱和度和亮度而言的。

  • 色调(H)是指光的颜色。OpenCV中,色调在区间[0,180]内取值。例如代表红色、黄色、绿色和蓝色的色调值分别为0、30、60和120。
  • 饱和度(S)是指色彩的深浅。在OpenCV中,饱和度在[0,255]内取值。当饱和度为0时,图像将变为灰度图像。
  • 亮度(V)是指光的明暗。与饱和度相同,在OpenCV中,亮度在区间[0,255]内取值。亮度值越大,图像越亮;当亮度值为0时,图像呈纯黑色。

从BGR色彩空间转换到HSV色彩空间

当一幅彩色图像从BGR色彩空间转换到HSV色彩空间时,需要使用的色彩空间转换码是cv2.COLOR_BGR2HSV

实例8:从BGR色彩空间转换到HSV色彩空间

import cv2image = cv2.imread("1.jpg", 1)  # 读取1.jpg
cv2.imshow("img_01", image)  # 显示图像
# 将1.jpg从BGR色彩空间转换到HSV色彩空间
hsv_image = cv2.cvtColor(image,cv2.COLOR_BGR2HSV)
cv2.imshow("HSV", hsv_image)  # 显示灰度图像
cv2.waitKey()
cv2.destroyAllWindows()  # 关闭所有的窗口时,销毁所有窗口

结果如下:
在这里插入图片描述

通道

在BGR色彩空间中,包含3个通道:B通道、G通道和R通道。

拆分通道

为了拆分一幅图像中的通道,OpenCV提供了split()方法。

拆分一幅BGR图像中的通道

b, g, r = cv2.split(bgr_image)
  • bgr_image: 一幅BGR图像
  • b: B通道图像
  • g: G通道图像
  • r: R通道图像

实例9: 拆分一幅BGR图像中的通道

import cv2image = cv2.imread("1.jpg", 1)  # 读取1.jpg
cv2.imshow("img_01", image)  # 显示图像
b,g,r=cv2.split(image)
cv2.imshow("B",b)
cv2.imshow("G",g)
cv2.imshow("R",r)
cv2.waitKey()
cv2.destroyAllWindows()  # 关闭所有的窗口时,销毁所有窗口

结果如下:
在这里插入图片描述
可以看到结果是0三个不同亮度的灰度图像。这是因为当程序执行到cv2.imshow(“B”,b)时原图像B、G、R这3个通道的值都会被修改为B通道的值,即(B,B,B),其余同理。对于BGR图像,只要B=G=R(即数值相等),就可以得到灰度图像。

拆分一幅HSV图像中的通道

h, s, v = cv2.split(hsv_image)
  • hsv_image: 一幅HSV图像。
  • h: H通道图像
  • s: S通道图像
  • v: V通道图像

实例10: 拆分一幅HSV图像中的通道

import cv2image = cv2.imread("1.jpg", 1)  # 读取1.jpg
cv2.imshow("img_01", image)  # 显示图像
hsv_image = cv2.cvtColor(image,cv2.COLOR_BGR2HSV)
h,s,v=cv2.split(hsv_image)
cv2.imshow("H",h)
cv2.imshow("S",s)
cv2.imshow("V",v)
cv2.waitKey()
cv2.destroyAllWindows()  # 关闭所有的窗口时,销毁所有窗口

结果如下:
在这里插入图片描述

合并通道

使用merge()方法合并H、S、V通道图像。

hsv = cv2.merge([h, s, v])
  • h: H通道图像
  • s: S通道图像
  • v: V通道图像
  • hsv:合并H通道图像、S通道图像和V通道图像后得到的图像

实例11: 合并H、S、V通道图像
首先将图像从BGR色彩空间转换到HSV色彩空间,然后拆分得到HSV图像中的通道,接着合并拆分后的通道图像,最后显示合并通道的HSV图像。

import cv2image = cv2.imread("1.jpg", 1)  # 读取1.jpg
cv2.imshow("img_01", image)  # 显示图像
hsv_image = cv2.cvtColor(image,cv2.COLOR_BGR2HSV)
h,s,v=cv2.split(hsv_image)
hsv = cv2.merge([h,s,v])
cv2.imshow("HSV",hsv)
cv2.waitKey()
cv2.destroyAllWindows()  # 关闭所有的窗口时,销毁所有窗口

结果如下:
在这里插入图片描述

综合运用拆分通道和合并通道

在HSV色彩空间中,如果保持其中两个通道的值不变,调整第3个通道的值,会得到响应的艺术效果。

实例12: 只把H通道的值调整为180
首先将图像从BGR色彩空间转换到HSV色彩空间;然后拆分得到HSV图像中的通道;接着让S通道和V通道的值表示不变,把H通道的值调整为180;再接着合并拆分后的通道图像,把这个图像从HSV色彩空间转换到BGR色彩空间;最后显示得到的BGR图像。

import cv2image = cv2.imread("1.jpg", 1)  # 读取1.jpg
cv2.imshow("img_01", image)  # 显示图像
hsv_image = cv2.cvtColor(image,cv2.COLOR_BGR2HSV) # 将图像从BGR色彩空间转换到HSV色彩空间
h,s,v=cv2.split(hsv_image) # 拆分得到HSV图像中的通道
h[:,:] = 180 # 让S通道和V通道的值表示不变,把H通道的值调整为180
hsv = cv2.merge([h,s,v]) # 合并拆分后的通道图像
new_Image = cv2.cvtColor(hsv,cv2.COLOR_HSV2BGR) # 把这个图像从HSV色彩空间转换到BGR色彩空间
cv2.imshow("NEW",new_Image)
cv2.waitKey()
cv2.destroyAllWindows()  # 关闭所有的窗口时,销毁所有窗口

结果如下:
在这里插入图片描述

alpha通道

OpenCV在B、G、R三个通道的基础上,又增加了一个A通道,即alpha通道,用于设置图像的透明度。在BGRA色彩空间中,alpha通道在区间[0,255]内取值,其中0表示透明,255表示不透明。

实例13: 调整A通道的值

import cv2bgr_image = cv2.imread("1.jpg", 1)  # 读取1.jpg
bgra_image = cv2.cvtColor(bgr_image, cv2.COLOR_BGR2BGRA)  # 把图片从BGR色彩空间转换到BGRA色彩空间
b, g, r, a = cv2.split(bgra_image)  # 拆分BGRA图像中的通道
a[:, :] = 172  # 将BGRA图像的透明度调整为172(半透明)
bgra_172 = cv2.merge([b, g, r, a])  # 合并拆分后并将透明度调整为172的通道图像
a[:, :] = 0  # 将BGRA图像的透明度调整为0(透明)
bgra_0 = cv2.merge([b, g, r, a])  # 合并拆分后并将透明度调整为0的通道图像
cv2.imwrite("D:/bgra_image.png", bgra_image)  # 在D盘根目录下,保存BGRA图像
cv2.imwrite("D:/bgra_172.png", bgra_172)  # 在D盘根目录下,保存透明度为172的BGRA图像
cv2.imwrite("D:/bgra_0.png", bgra_0)  # 在D盘根目录下,保存透明度为0的BGRA图像

如果使用imshow()方法的话,窗口里显示的图像是相同的。为了显示这3幅图像的不同效果,需要使用imwrite()方法来保存。

相关文章:

【OpenCV入门】第一部分——图像处理基础

本文结构 图像处理的基本操作读取图像imread() 显示图像imshow()waitKey()destroyAllWindows() 保存图像imwrite() 获取图像属性 像素确定像素的位置获取像素的BGR值修改像素的BGR值 色彩空间GRAY色彩空间cvtColor()——从BGR色彩空间转换到GRAY色彩空间 HSV色彩空间从BGR色彩空…...

vue3+ts+tinynce富文本编辑器+htmlDocx+file-saver 配合实现word下载

vue3 请下载html-docx-js-typescript,否则会报错类型问题 //报告导出word import * as htmlDocx from "html-docx-js-typescript";//ts-ignore import { saveAs } from file-saver// 下载文件, const downloadFile (row)> {try {const co…...

论文阅读 The Power of Tiling for Small Object Detection

The Power of Tiling for Small Object Detection Abstract 基于深度神经网络的技术在目标检测和分类方面表现出色。但这些网络在适应移动平台时可能会降低准确性,因为图像分辨率的增加使问题变得更加困难。在低功耗移动设备上实现实时小物体检测一直是监控应用的…...

【FreeRTOS】【应用篇】消息队列【下篇】

前言 本篇文章主要对 FreeRTOS 中消息队列的概念和相关函数进行了详解消息队列【下篇】详细剖析了消息队列中发送、接收时队列消息控制块中各种指针的行为,以及几个发送消息和接收消息的函数的运作流程笔者有关于 【FreeRTOS】【应用篇】消息队列【上篇】——队列基…...

芯片技术的崭新时代:探索未来的可能性

引言 芯片作为现代科技领域的核心,扮演着无可替代的角色。从智能手机到数据中心,从医疗设备到智能家居,芯片技术已经深刻地改变了我们的生活。然而,随着技术的不断发展,芯片行业也在经历着一场前所未有的变革。本文将…...

博流RISC-V芯片Eclipse环境搭建

文章目录 1、下载 Eclipse2、导入 bouffalo_sdk3、编译4、烧录5、使用ninja编译 之前编译是通过 VSCode 编译,通过手工输入 make 命令编译,我们也可以通过 Eclipse 可视化 IDE 来编译、烧录。 1、下载 Eclipse 至 Eclipse 官网 https://www.eclipse.org…...

智慧水产养殖方案,守护养殖水产品安全!

水产品在人们的饮食文化中占据着举足轻重的地位,更是人们摄入蛋白质的重要来源。因此,保障食品安全,提升养殖水产品的品质至关重要然。而传统的人工观察水产养殖方式较为单一,难以及时发现水质问题和投喂情况,容易导致…...

前端vue引入高德地图入门教程

距离上一篇关于前端项目中使用高德地图的文章已经将近5年之久, 这是我的第一篇关于高德地图的文章 这期间前端技术日新月异,5年前JQuery还如日中天,如今已经销声匿迹,很少有公司招聘还在要求JQuery,更多的是Vue、React…...

【LeetCode题目详解】第八章 贪心算法 part05 435. 无重叠区间 763.划分字母区间 56. 合并区间 (day36补)

本文章代码以c为例! 一、力扣第435题:无重叠区间 题目: 给定一个区间的集合 intervals ,其中 intervals[i] [starti, endi] 。返回 需要移除区间的最小数量,使剩余区间互不重叠 。 示例 1: 输入: intervals [[1,…...

数据的语言:学习数据可视化的实际应用

数据可视化应该学什么?这是一个在信息时代越来越重要的问题。随着数据不断增长和积累,从社交媒体到企业业务,从科学研究到医疗健康,我们都面临着海量的数据。然而,数据本身往往是冰冷、抽象的数字,对于大多…...

【Flutter】Flutter简介

Flutter是Google开发的一款用于构建高性能、高保真移动应用程序的开源UI工具包。它允许开发人员使用Dart语言来构建跨平台的移动应用程序,并提供了丰富的UI组件、动画效果和手势识别等功能。 以下是Flutter入门的一些详细介绍: Flutter概述 Flutter是一…...

做区块链卡牌游戏有什么好处?

区块链卡牌游戏是一种基于区块链技术的创新性游戏形式,它将传统的卡牌游戏与区块链技术相结合,实现了去中心化、数字化资产的交易和收集。这种新型游戏形式正逐渐在游戏行业引起了广泛的关注和热潮。本文将深入探讨区块链卡牌游戏的定义、特点以及其在未…...

C语言每日一练------Day(5)

本专栏为c语言练习专栏,适合刚刚学完c语言的初学者。本专栏每天会不定时更新,通过每天练习,进一步对c语言的重难点知识进行更深入的学习。 今日练习题关键字:错误的集合 密码检查 💓博主csdn个人主页:小小u…...

(Windows )本地连接远程服务器(Linux),免密码登录设置

在使用VScode连接远程服务器时,每次打开都要输入密码,以及使用ssh登录或其它方法登录,都要本地输入密码,这大大降低了使用感受,下面总结了免密码登录的方法,用起来巴适得很,起飞。 目录 PowerSh…...

Python 面试:异常处理机制

格式: 继承Exception实现自定义异常。 注意:这里是继承Exception类,而不是BaseException类,因为继承BaseException可能会导致捕获不到自定义异常。 class MyException(Exception):passtry:raise MyException(my salary is too…...

Matlab图像处理-水平镜像

镜像变换 镜像变换又常称为对称变换,它可以分为水平对称、垂直对称等多种变换。对称变换后,图像的宽和高不变。 图像的镜像分为两种垂直镜像和水平镜像。 水平镜像即将图像左半部分和右半部分以图像竖直中轴线为中心轴进行对换; 竖直镜像…...

Ansys Zemax | 手机镜头设计 - 第 2 部分:使用 OpticsBuilder 实现光机械封装

本文是3篇系列文章的一部分,该系列文章将讨论智能手机镜头模块设计的挑战,从概念、设计到制造和结构变形的分析。本文是三部分系列的第二部分。概括介绍了如何在 CAD 中编辑光学系统的光学元件以及如何在添加机械元件后使用 Zemax OpticsBuilder 分析系统…...

【GPT,Flask】用Python Flask结合OpenAI的GPT API构建一个可自主搭建的内容生成应用网站

【背景】 自己构建模型并进行训练需要很高的知识,技能和资源门槛。如今,通过OpenAI提供的API,则可以快速通过GPT能力构建可以提供内容生成服务的在线网站。这套框架可以提供给用户,用户可以利用该框架在自己的环境(比如自己的公司内)构建内容生成服务。你也可以自己上线…...

vue + electron

node 版本 v14.19.3 npm 版本 6.14.17 要是node-sass报错执行命令: npm uninstall node-sass sass-loader npm i node-sass4.14.1 sass-loader7.3.1 --save -dev首先安装依赖 npm install electron npm install electron-packagerelectronRun.js放在根目录下 con…...

spring中LocalDateTime 转成字符串的时候注意事项

ApiOperation("查询课程发布信息") ResponseBody GetMapping("/r/coursepublish/{courseId}") public CoursePublish getCoursepublish(PathVariable("courseId") Long courseId) { CoursePublish coursePublish coursePublishService.getC…...

变量 varablie 声明- Rust 变量 let mut 声明与 C/C++ 变量声明对比分析

一、变量声明设计:let 与 mut 的哲学解析 Rust 采用 let 声明变量并通过 mut 显式标记可变性,这种设计体现了语言的核心哲学。以下是深度解析: 1.1 设计理念剖析 安全优先原则:默认不可变强制开发者明确声明意图 let x 5; …...

MySQL 隔离级别:脏读、幻读及不可重复读的原理与示例

一、MySQL 隔离级别 MySQL 提供了四种隔离级别,用于控制事务之间的并发访问以及数据的可见性,不同隔离级别对脏读、幻读、不可重复读这几种并发数据问题有着不同的处理方式,具体如下: 隔离级别脏读不可重复读幻读性能特点及锁机制读未提交(READ UNCOMMITTED)允许出现允许…...

练习(含atoi的模拟实现,自定义类型等练习)

一、结构体大小的计算及位段 (结构体大小计算及位段 详解请看:自定义类型:结构体进阶-CSDN博客) 1.在32位系统环境,编译选项为4字节对齐,那么sizeof(A)和sizeof(B)是多少? #pragma pack(4)st…...

java调用dll出现unsatisfiedLinkError以及JNA和JNI的区别

UnsatisfiedLinkError 在对接硬件设备中,我们会遇到使用 java 调用 dll文件 的情况,此时大概率出现UnsatisfiedLinkError链接错误,原因可能有如下几种 类名错误包名错误方法名参数错误使用 JNI 协议调用,结果 dll 未实现 JNI 协…...

电脑插入多块移动硬盘后经常出现卡顿和蓝屏

当电脑在插入多块移动硬盘后频繁出现卡顿和蓝屏问题时,可能涉及硬件资源冲突、驱动兼容性、供电不足或系统设置等多方面原因。以下是逐步排查和解决方案: 1. 检查电源供电问题 问题原因:多块移动硬盘同时运行可能导致USB接口供电不足&#x…...

跨链模式:多链互操作架构与性能扩展方案

跨链模式:多链互操作架构与性能扩展方案 ——构建下一代区块链互联网的技术基石 一、跨链架构的核心范式演进 1. 分层协议栈:模块化解耦设计 现代跨链系统采用分层协议栈实现灵活扩展(H2Cross架构): 适配层&#xf…...

爬虫基础学习day2

# 爬虫设计领域 工商:企查查、天眼查短视频:抖音、快手、西瓜 ---> 飞瓜电商:京东、淘宝、聚美优品、亚马逊 ---> 分析店铺经营决策标题、排名航空:抓取所有航空公司价格 ---> 去哪儿自媒体:采集自媒体数据进…...

全面解析各类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…...

Aspose.PDF 限制绕过方案:Java 字节码技术实战分享(仅供学习)

Aspose.PDF 限制绕过方案:Java 字节码技术实战分享(仅供学习) 一、Aspose.PDF 简介二、说明(⚠️仅供学习与研究使用)三、技术流程总览四、准备工作1. 下载 Jar 包2. Maven 项目依赖配置 五、字节码修改实现代码&#…...

【Go语言基础【12】】指针:声明、取地址、解引用

文章目录 零、概述:指针 vs. 引用(类比其他语言)一、指针基础概念二、指针声明与初始化三、指针操作符1. &:取地址(拿到内存地址)2. *:解引用(拿到值) 四、空指针&am…...