Java使用OpenCV进行图像操作

news2024/11/26 18:43:20

OpenCV图像操作

  • OpenCV
    • 概述
    • 下载与安装
    • 目录说明
    • 项目集成
    • 验证
  • Mat类
    • 创建Mat对象
    • 其他操作
  • 常见图像API
    • 读取与输出图像
    • 显示图像
    • 图像压缩和解压缩
    • 图像转换
    • 图像缩放
    • 亮度调整
    • 图像锐化
    • 图像梯度
    • 图像二值化
    • 边缘检测
    • 图像高斯模糊
    • 图像反色

OpenCV

概述

OpenCV(开源计算机视觉库)是在BSD(开源协议)许可下发布的。它是一个高度优化的库,专注于实时应用程序。它具有C ++,Python和Java接口,支持Windows,Linux,Mac OS,iOS和Android。

OpenCV是一个开源的计算机视觉库,它提供了一系列丰富的图像处理和计算机视觉算法,包括图像读取、显示、滤波、特征检测、目标跟踪等功能。

OpenCV被广泛应用于各种领域,如医疗影像处理、智能交通、安防监控、机器人视觉、虚拟现实等。它可以帮助开发者快速构建高效、准确、可靠的计算机视觉应用,并且支持多种编程语言,如C++、Python、Java等。

在计算机视觉应用中,OpenCV可以用来进行图像预处理、特征提取、物体检测、目标跟踪、三维重建等操作。通过结合深度学习技术,OpenCV还可以用于图像分类、目标分割、姿态估计等更加复杂的任务。

官网文档地址:https://docs.opencv.org/4.6.0/df/d65/tutorial_table_of_content_introduction.html

教程参考:https://www.w3cschool.cn/opencv/

教程参考:https://www.yiibai.com/opencv/opencv_adding_text.html

下载与安装

下载地址:https://opencv.org/releases/

在这里插入图片描述

下载到本地后,双击进行安装即可

在这里插入图片描述

目录说明

安装目录如下

在这里插入图片描述

build :基于window构建

sources:开源,提供源码

build目录说明

在这里插入图片描述

这里是Java开发关注java目录即可

在这里插入图片描述

x64与x86代表给不同的系统使用

opencv-460.jar给java操作openvc的程序包

由于是64位系统,所以关注x64目录

在这里插入图片描述

DLL(Dynamic Link Library)文件为动态链接库文件,又称“应用程序拓展”,是软件文件类型。DLL文件,放置于系统中。当执行某一个程序时,相应的DLL文件就会被调用

项目集成

方式1:

这里使用IDEA进行开发,导入opencv-460.jar库

使用快捷键 Ctrl+Shift+Alt+S打开
在这里插入图片描述
选择库项,导入Java库。
在这里插入图片描述
在这里插入图片描述
方式2:

除了上述方式,还可以将opencv-460.jar安装到本地仓库或私有仓库,然后在pom.xml中引入依赖。

在项目根目录创建lib目录,将上述提及的opencv-460.jaropencv_java460.dll放到该目录

在这里插入图片描述
pom.xml文件中,通过坐标的形式引入

        <!-- 加载lib目录下的opencv包 -->
        <dependency>
            <groupId>org.opencv</groupId>
            <artifactId>opencv</artifactId>
            <version>4.6.0</version>
            <scope>system</scope>
            <systemPath>${basedir}/lib/opencv-460.jar</systemPath>
        </dependency>

验证

public class MyTest {

	// 调用OpenCV库文件
    static {
        System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
    }

    public static void main(String args[]) {
        // 创建一个3X3的对角矩阵
        Mat a = Mat.eye(3, 3, CvType.CV_8UC1);
        System.out.println(a.dump());
    }
}

执行上述代码,不出意外将出现如下异常:

Exception in thread "main" java.lang.UnsatisfiedLinkError: no opencv_java460 in java.library.path
	at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1860)
	at java.lang.Runtime.loadLibrary0(Runtime.java:871)
	at java.lang.System.loadLibrary(System.java:1122)

解决方案有2种:

1.将D:\Development\opencv\build\java\x64\opencv_java460.dll文件拷贝至下面2个目录,任选其一即可。

在这里插入图片描述

在这里插入图片描述
2.通过指定虚拟机参数解决:

-Djava.library.path=D:\WorkSpace\projectName\demo\lib\opencv_java460.dll

Mat类

OpenCV中的Mat类是一个用于表示图像、矩阵和向量的基本数据类型,它可以包含任意尺寸和类型的元素。

创建Mat对象

创建一个Mat对象

# 生成一个空的矩阵
Mat mat = new Mat();

创建Mat对象时同时设置矩阵的基本参数

params1:代表矩阵的行数(rows)

params2:代表矩阵的列数(cols)

params3:代表矩阵中像素点的位数和通道数
Mat a = Mat.eye(3, 3, CvType.CV_8UC1);

其他操作

访问Mat对象中的像素值

double[] pixel = mat.get(row, col); // 获取像素值

修改Mat对象中的像素值

mat.put(row, col, new double[]{255, 255, 255}); // 修改像素值

获取Mat对象的大小和通道数

int rows = mat.rows(); // 获取行数
int cols = mat.cols(); // 获取列数
int channels = mat.channels(); // 获取通道数

常见图像API

读取与输出图像

在OpenCV中,图象输入与输出使用imread()imwrite()两个方法

1.imread()

params1:代表输入图片路径

params2:一个标志表明加载图象的颜色类型

从文件读取一张图像并创建一个Mat对象

Mat mat1 = Imgcodecs.imread("D://test.png");

Mat mat2 = Imgcodecs.imread("D://test.png",Imgcodecs.IMREAD_LOAD_GDAL);

2.imwrite()

params1:文件输出位置

params2:将要输出为图片的源矩阵的名字,它是一个我们读入或处理过的Mat类型的参数

将一个Mat对象保存到文件中

    public static void main(String args[]) {
	    // 加载本地OpenCV库
        System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
        
        Mat mat = Imgcodecs.imread("D://test.png");
        boolean imwrite = Imgcodecs.imwrite("D://write.png", mat);
        System.out.println("图像是否输出成功: " + imwrite);
    }

显示图像

可以通过GUI的方式显示图片,不需要再将图像通过流输出到本地再来查看

    public static void main(String args[]) {
        // 加载本地OpenCV库
        System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
        
        Mat mat = Imgcodecs.imread("D://test.png");
        //显示图像
        HighGui.imshow("原图", mat);
        //延时多长时间后显示
        HighGui.waitKey(0);
    }

图像压缩和解压缩

OpenCV中的imencode方法和imdecode方法是用于图像压缩和解压缩的函数。

1.imencode()

imencode方法将一个OpenCV格式的图像进行编码成指定格式的图像数据流,常用的编码格式有JPEG、PNG等。

方法原型为:

boolean imencode(String ext, Mat img, MatOfByte buf, MatOfInt params);
ext表示编码后的文件类型(例如".jpg"、".png"等)

img表示需要编码的图像

buf表示存储编码结果的字节流

params为可选参数,表示编码参数(例如JPEG的压缩质量)

将一张Mat对象保存为JPEG格式的文件

    public static void main(String args[]) throws IOException {
        Mat mat = Imgcodecs.imread("D://test.png");
        MatOfByte matOfByte = new MatOfByte();
        Imgcodecs.imencode(".png", mat, matOfByte);
        # Imgcodecs.imencode(".jpg", mat, matOfByte , new MatOfInt(Imgcodecs.IMWRITE_JPEG_QUALITY, 80));
        Files.write(Paths.get("D://write.png"), matOfByte.toArray());
    }

2.imdecode()

imdecode方法则是将压缩后的图像数据流解码成OpenCV格式的图像。

方法原型为:

Mat imdecode(Mat buf, int flags)
buf为需要解码的图像数据流

flags为解码标志,通常使用IMREAD_COLOR表示将图像解码为彩色图像。

当已经有了一个编码后的JPEG格式图像数据流,可以使用以下代码将其解码为OpenCV格式的图像:

byte[] bytes = Files.readAllBytes(Paths.get("D://write.jpg"));
Mat matImage = Imgcodecs.imdecode(new MatOfByte(bytes), Imgcodecs.IMREAD_COLOR);

图像转换

1.将RGB图像转为灰度图像

在识别图像的时候一般用灰度图像,因为彩色图片信息量太大,为了提高运算速度,通常采用灰度。如果灰度图还是过大,则采用二值化图像。

比如一个点,灰度则只有256个维度,如果算上RGB色彩,则是1600万以上维度,因此就先降维(灰度)来计算

    static {
        // 加载本地OpenCV库
        System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
    }
    
    @Test
    public void cvtColorTest() {
        // 读取图像文件并存储在src变量中作为输入图像
        Mat src = Imgcodecs.imread("D://test.png");
        
        // 创建一个空的Mat对象dst,用于存储经过处理调整后的图像
        Mat dst = new Mat();
        if (src.channels() == 3) {
            // 将RGB图像转为灰度图像
        	Imgproc.cvtColor(src, dst, Imgproc.COLOR_RGB2GRAY);
        } else {
            System.out.println("图像不是BGR格式");
        }

        // 使用HighGui库显示原始图像和修改后的图像
        HighGui.imshow("原图", src);
        HighGui.imshow("新图", dst);
        
        // 等待用户关闭窗口 或 等待用户按下任意键继续程序执行
        HighGui.waitKey(0);

        // 释放内存
        src.release();
        dst.release();
    }

在这里插入图片描述
2.将BGR图像转为RGB图像

 Mat rgbImage = new Mat();
 Imgproc.cvtColor(src, rgbImage, Imgproc.COLOR_BGR2RGB);

图像缩放

1.图像缩小

    @Test
    public void resizeTest() {
        // 读取原始图像
        Mat src = Imgcodecs.imread("D://test.png");

        // 定义缩放比例
        double scale = 0.5;
        // 计算新图像尺寸
        Size newSize = new Size(src.width() * scale, src.height() * scale);

        // 创建一个与输入图像src相同大小和类型的Mat对象
        Mat dst = new Mat();
        Mat.zeros(src.size(), src.type());
        // 对图像进行缩放
        Imgproc.resize(src, dst, newSize, 0, 0, Imgproc.INTER_LINEAR);

        // 显示原始图像和缩放后的图像
        HighGui.imshow("原图", src);
        HighGui.imshow("新图", dst);

        // 等待用户关闭窗口 或 等待用户按下任意键继续程序执行
        HighGui.waitKey(0);

        // 释放内存
        src.release();
        dst.release();
    }

在这里插入图片描述

    @Test
    public void resizeTest() {
        // 读取原始图像
        Mat src = Imgcodecs.imread("D://test.png");
        // 创建一个空的Mat对象dst,用于存储经过处理调整后的图像
        Mat dst = new Mat();
        // 将RGB图像转为灰度图像
        Imgproc.cvtColor(src, dst, Imgproc.COLOR_RGB2GRAY);
        // 使用resize函数将原始图像和目标图像缩小到其一半大小
        Imgproc.resize(src, src, new Size(dst.cols() / 2, dst.rows() / 2));
        Imgproc.resize(dst, dst, new Size(dst.cols() / 2, dst.rows() / 2));
        // 使用HighGui库显示原始图像和修改后的图像
        HighGui.imshow("原图", src);
        HighGui.imshow("新图", dst);
        // 延时多长时间后显示
        HighGui.waitKey(0);
    }

在这里插入图片描述
2.图像放大

    @Test
    public void resizeTest() {
        // 读取原始图像
        Mat src = Imgcodecs.imread("D://test.png");

        // 创建一个与输入图像src相同大小和类型的Mat对象
        Mat dst = new Mat();
        Mat.zeros(src.size(), src.type());
        // 对图像进行缩放
        Imgproc.resize(src, dst, new Size(), 1.1, 1.1, Imgproc.INTER_LINEAR);

        // 使用HighGui库显示原始图像和修改后的图像
        HighGui.imshow("原图", src);
        HighGui.imshow("新图", dst);
        // 延时多长时间后显示
        HighGui.waitKey(0);
    }

在这里插入图片描述

亮度调整

1.亮度提升

当遇到图片比较暗的图像,可以通过亮度提升,从而实现达到更高的识别率

    @Test
    public void addWeightedTest() {
        Mat src = Imgcodecs.imread("D://test.png");
        Mat dst = new Mat();
        // 创建一个与输入图像src相同大小和类型的Mat对象
        Mat black = Mat.zeros(src.size(), src.type());
        // 使用addWeighted函数将输入图像src和black图像按比例相加,实现亮度调整
        // 参数1.2表示亮度增加的比例,0.5表示black图像的权重,0表示亮度调整的偏移量
        Core.addWeighted(src, 1.2, black, 0.5, 0, dst);
        
        // 使用resize函数将原始图像和目标图像缩小到其一半大小
        Imgproc.resize(src, src, new Size(), 0.5, 0.5, Imgproc.INTER_LINEAR);
        Imgproc.resize(dst, dst, new Size(), 0.5, 0.5, Imgproc.INTER_LINEAR);

        // 使用HighGui库显示原始图像和修改后的图像
        HighGui.imshow("原图", src);
        HighGui.imshow("新图", dst);
        // 等待用户按下任意键继续程序执行
        HighGui.waitKey(0);
    }

在这里插入图片描述2.亮度降低

当遇到图片亮度很亮,曝光度很高的图像,可以通过降低亮度来提高识别率

    @Test
    public void addWeightedTest() {
        Mat src = Imgcodecs.imread("D://test.png");

        Mat dst = new Mat();
        // 创建一个与输入图像src相同大小和类型的Mat对象
        Mat black = Mat.zeros(src.size(), src.type());

        // 使用addWeighted函数将输入图像src和black图像按比例相加,实现亮度调整
        // 参数0.5表示亮度增加的比例,0.5表示black图像的权重,0表示亮度调整的偏移量
        Core.addWeighted(src, 0.5, black, 0.5, 0, dst);

        // 使用resize函数将原始图像和目标图像缩小到其一半大小
        Imgproc.resize(src, src, new Size(), 0.5, 0.5, Imgproc.INTER_LINEAR);
        Imgproc.resize(dst, dst, new Size(), 0.5, 0.5, Imgproc.INTER_LINEAR);

        // 使用HighGui库显示原始图像和修改后的图像
        HighGui.imshow("原图", src);
        HighGui.imshow("新图", dst);

        // 等待用户按下任意键继续程序执行
        HighGui.waitKey(0);
    }

在这里插入图片描述

图像锐化

图像锐化可以让彩色图片看起来更有色彩

    @Test
    public void sharpenTest() {
        Mat src = Imgcodecs.imread("D://test.png");

        Mat dst = new Mat();
        // 定义一组锐化滤波器的参数值sharper
        float[] sharper = new float[]{0, -1, 0, -1, 5, -1, 0, -1, 0};
        // 定义一个3x3的卷积核operator
        Mat operator = new Mat(3, 3, CvType.CV_32FC1);
        // 使用sharper
        operator.put(0, 0, sharper);
        // 使用filter2D函数将卷积核应用于原始图像src
        Imgproc.filter2D(src, dst, -1, operator);

        // 使用resize函数将原始图像和目标图像缩小到其一半大小
        Imgproc.resize(src, src, new Size(), 0.5, 0.5, Imgproc.INTER_LINEAR);
        Imgproc.resize(dst, dst, new Size(), 0.5, 0.5, Imgproc.INTER_LINEAR);

        // 使用HighGui库显示原始图像和修改后的图像
        HighGui.imshow("原图", src);
        HighGui.imshow("新图", dst);

        // 等待用户按下任意键继续程序执行
        HighGui.waitKey(0);
    }    

在这里插入图片描述

图像梯度

图像梯度计算的是图像变化的速度。对于图像的边缘部分,其灰度值变化较大,梯度值也较大。一般情况下,图像梯度计算的是图像的边缘信息。严格来讲,图像梯度计算需要求导数,但图像梯度一般通过计算像素差值来得到梯度的近似值。

    @Test
    public void gradientTest() {
        Mat src = Imgcodecs.imread("D://test.png");

        Mat grad_x = new Mat();
        Mat grad_y = new Mat();
        Mat abs_grad_x = new Mat();
        Mat abs_grad_y = new Mat();
        // 使用Sobel滤波器计算其水平和垂直梯度
        Imgproc.Sobel(src, grad_x, CvType.CV_32F, 1, 0);
        Imgproc.Sobel(src, grad_y, CvType.CV_32F, 0, 1);
        Core.convertScaleAbs(grad_x, abs_grad_x);
        Core.convertScaleAbs(grad_y, abs_grad_y);
        grad_x.release();
        grad_y.release();
        // 最终的梯度通过加权平均值组合在gradxy中
        Mat gradxy = new Mat();
        Core.addWeighted(abs_grad_x, 0.5, abs_grad_y, 0.5, 10, gradxy);

        // 使用resize函数将原始图像和目标图像缩小到其一半大小
        Imgproc.resize(src, src, new Size(), 0.5, 0.5, Imgproc.INTER_LINEAR);
        Imgproc.resize(gradxy, gradxy, new Size(), 0.5, 0.5, Imgproc.INTER_LINEAR);

        // 使用HighGui库显示原始图像和修改后的图像
        HighGui.imshow("原图", src);
        HighGui.imshow("新图", gradxy);

        // 等待用户按下任意键继续程序执行
        HighGui.waitKey(0);
    }

在这里插入图片描述

图像二值化

图像二值化是将一幅彩色或灰度图像转换为只包含两种颜色的图像,其中颜色通常为黑色(灰度为0)和白色(灰
度为255)。二值化图像可以帮助我们更好地分离物体和背景,简化图像处理流程

二值化的好处就是将图片上的有用信息和无用信息区分开来:

比如二值化之后的验证码图片,验证码像素为黑色,背景和干扰点为白色,这样后面对验证码像素处理的时候就会很方便。

常见的二值化方法为固定阀值和自适应阀值:

固定阀值

制定一个固定的数值作为分界点,大于这个阀值的像素就设为255,小于该阀值就设为0,这种方法简单粗暴,但是效果不一定好

自适应阀值

每次根据图片的灰度情况找合适的阀值。自适应阀值的方法有很多,这里采用了一种类似K均值的方法,就是先选择一个值作为阀值,统计大于这个阀值的所有像素的灰度平均值和小于这个阀值的所有像素的灰度平均值,再求这两个值的平均值作为新的阀值。重复上面的计算,直到每次更新阀值后,大于该阀值和小于该阀值的像素数目不变为止。

    @Test
    public void thresholdTest() {
        // 读取灰度化的图像
        Mat src = Imgcodecs.imread("D://test.png", Imgcodecs.IMREAD_GRAYSCALE);
        
		// 阈值化
        Mat dst = new Mat();
        Imgproc.threshold(src, dst, 127, 255, Imgproc.THRESH_BINARY);

        // 使用resize函数将原始图像和目标图像缩小到其一半大小
        Imgproc.resize(src, src, new Size(), 0.5, 0.5, Imgproc.INTER_LINEAR);
        Imgproc.resize(dst, dst, new Size(), 0.5, 0.5, Imgproc.INTER_LINEAR);

        // 使用HighGui库显示原始图像和修改后的图像
        HighGui.imshow("原图", src);
        HighGui.imshow("新图", dst);

        // 等待用户按下任意键继续程序执行
        HighGui.waitKey(0);
    }

在这里插入图片描述

边缘检测

边缘检测是指寻找图像中明暗变化的区域,并将这些区域称为边缘。这些边缘通常表示了图像中物体之间的界限或轮廓。使用OpenCV进行边缘检测,可以帮助我们更好地理解图像中的细节和结构,从而提高图像处理和分析的效率和准确性。

    @Test
    public void cannyTest() {
        Mat src = Imgcodecs.imread("D://test.png");

        // 边缘检测
        Mat dst = new Mat();
        Imgproc.Canny(src, dst, 100, 200);

        // 使用resize函数将原始图像和目标图像缩小到其一半大小
        Imgproc.resize(src, src, new Size(), 0.5, 0.5, Imgproc.INTER_LINEAR);
        Imgproc.resize(dst, dst, new Size(), 0.5, 0.5, Imgproc.INTER_LINEAR);

        // 使用HighGui库显示原始图像和修改后的图像
        HighGui.imshow("原图", src);
        HighGui.imshow("新图", dst);

        // 等待用户按下任意键继续程序执行
        HighGui.waitKey(0);
    }

图像高斯模糊

高斯模糊本质上是低通滤波器,输出图像的每个像素点是原图像上对应像素点与周围像素点的加权和,原理并不复杂,就是用高斯分布权值矩阵与原始图像矩阵做卷积运算

    @Test
    public void gaussianBlurTest() {
        Mat src = Imgcodecs.imread("D://test.png");

        // 高斯模糊
        Mat dst = new Mat();
        Imgproc.GaussianBlur(src, dst, new Size(15, 15), 0);

        // 使用resize函数将原始图像和目标图像缩小到其一半大小
        Imgproc.resize(src, src, new Size(), 0.5, 0.5, Imgproc.INTER_LINEAR);
        Imgproc.resize(dst, dst, new Size(), 0.5, 0.5, Imgproc.INTER_LINEAR);

        // 使用HighGui库显示原始图像和修改后的图像
        HighGui.imshow("原图", src);
        HighGui.imshow("新图", dst);

        // 等待用户按下任意键继续程序执行
        HighGui.waitKey(0);
    }

在这里插入图片描述

图像反色

图像反色是指对图像中的每个像素值进行取反操作,即将原始图像中每个像素的亮度值或颜色值减去255得到的新图像

    @Test
    public void inverseColorTest() {
        Mat src = Imgcodecs.imread("D://test.png");

        Mat dst = src.clone();
        int width = dst.cols();
        int height = dst.rows();
        int dims = dst.channels();
        byte[] data = new byte[width * height * dims];
        dst.get(0, 0, data);

        int index, r, g, b;
        for (int row = 0; row < height; row++) {
            for (int col = 0; col < width * dims; col += dims) {
                index = row * width * dims + col;
                b = data[index] & 0xff;
                g = data[index + 1] & 0xff;
                r = data[index + 2] & 0xff;

                r = 255 - r;
                g = 255 - g;
                b = 255 - b;

                data[index] = (byte) b;
                data[index + 1] = (byte) g;
                data[index + 2] = (byte) r;
            }
        }

        dst.put(0, 0, data);

        // 使用resize函数将原始图像和目标图像缩小到其一半大小
        Imgproc.resize(src, src, new Size(), 0.5, 0.5, Imgproc.INTER_LINEAR);
        Imgproc.resize(dst, dst, new Size(), 0.5, 0.5, Imgproc.INTER_LINEAR);

        // 使用HighGui库显示原始图像和修改后的图像
        HighGui.imshow("原图", src);
        HighGui.imshow("新图", dst);

        // 等待用户按下任意键继续程序执行
        HighGui.waitKey(0);
    }

在这里插入图片描述

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

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

相关文章

2023互联网高级测试工程师至少具备的能力

业务熟悉 熟悉本系统 测试人员参与测试的系统的各种业务场景&#xff0c;必须做到精熟 。一旦需求有改动&#xff0c;可以清楚快速的知道上下文。同时可以清楚的知道哪些点是需要重点测试的。 熟悉跟本系统有通讯的上下游系统业务 跟本系统有通讯的上下游系统也要非常熟悉。这…

Exception in thread “main“ java.lang.UnsupportedClassVersionError 50报错处理

之间正常走jenkinsdocker自动化部署的项目&#xff0c;今天改了一个文件&#xff0c;点了一下&#xff0c;竟然没有部署上去&#xff0c;提示如上&#xff0c;如下 Exception in thread "main" java.lang.UnsupportedClassVersionError: com/coocaa/tsp/sys/user/Use…

Web 自动化测试Selenium 之PO 模型

目录 1. po 模型介绍 2. PageObject 设计模式 3. PO 的核心要素 4. 非PO 实现 5. PO 实现 6. 总结 7. PO 模式的特点 总结&#xff1a; 1. po 模型介绍 在自动化中&#xff0c;Selenium 自动化测试中有一个名字经常被提及 PageObject (思想与面向对象的特征相同)&#x…

【改进算法】混合鲸鱼WOA和BAT算法(Matlab代码实现)​

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

Python键盘监听:实现快捷操作和自动化脚本(监听组合键

前言 本文主要介绍一下使用Python进行事件监听功能&#xff0c;以实现一些特有的操作。本文旨在介绍如何实现这一功能。 笔者根据一些需求写了一个小工具&#xff0c;流程和功能如下图所示&#xff08;实际功能有更多&#xff09;&#xff1a; 该工具主要实现了 键盘监听 和 鼠…

从Linux源码看TIME_WAIT状态的持续时间

前言 笔者一直以为在Linux下TIME_WAIT状态的Socket持续状态是60s左右。线上实际却存在TIME_WAIT超过100s的Socket。由于这牵涉到最近出现的一个复杂Bug的分析。所以&#xff0c;笔者就去Linux源码里面&#xff0c;一探究竟。 首先介绍下Linux环境 TIME_WAIT这个参数通常和五…

C++入门,一些C++基本概念介绍

文章目录 目录 前言 1.C关键字 1.1命名空间 1.2命名空间定义 1.3命名空间的使用 2.C输入&输出 3.缺省参数 3.1缺省参数的概念 3.2缺省参数分类 4.函数重载 4.1函数重载的概念 5.引用 5.1 引用特性 5.2 常引用 5.3引用的使用场景 5.4引用和指针 6.内联函数…

【Java基础】注解——自定义注解

什么是注解? Java 注解(Annotation)又称 Java 标注&#xff0c;是 JDK5.0 引入的一种注释机制。 比如我们常见的Override和Deprecated都是注解&#xff0c;注解可以加在类、方法、成员变量等上面&#xff0c;类似于给他们“打标签"。 注解怎么定义? public interface…

华为OD机试真题 JavaScript 实现【百钱买百鸡问题】【牛客练习题】

一、题目描述 公元五世纪&#xff0c;我国古代数学家张丘建在《算经》一书中提出了“百鸡问题”&#xff1a;鸡翁一值钱五&#xff0c;鸡母一值钱三&#xff0c;鸡雏三值钱一。百钱买百鸡&#xff0c;问鸡翁、鸡母、鸡雏各几何&#xff1f; 现要求你打印出所有花一百元买一百…

AM@空间直角坐标系@数量积和向量积@向量的外积在物理学中的相关概念

文章目录 空间直角坐标系坐标面分向量坐标分解式余弦定理数量积的坐标表示公式 向量积向量积的坐标表示公式 向量的外积在物理学中的相关概念物理量ref 角速度和向量积量纲Base unit (measurement)Background&#x1f388;International System of Units&#x1f388;附 表达方…

【ROS】ROS1导航(了解)

1、简述 ROS1导航模块navigation&#xff0c;它从里程计、传感器流和目标姿势中获取信息&#xff0c;并将速度、角速度控制命令发送至差速控制单元。 因为是ROS1&#xff0c;所以下面的内容只是一带而过&#xff0c;没有深入学习总结。详细内容可参考官网&#xff1a;http://…

Spring高手之路5——彻底掌握Bean的生命周期

文章目录 1. 理解Bean的生命周期1.1 生命周期的各个阶段 2. 理解init-method和destroy-method2.1 从XML配置创建Bean看生命周期2.2 从配置类注解配置创建Bean看生命周期2.3 初始化和销毁方法的特性2.4 探究Bean的初始化流程顺序 3. PostConstruct和PreDestroy3.1 示例&#xff…

Scala入门

第1章 Scala入门 1.1 概述 Scala将面向对象和函数式编程结合成一种简洁的高级语言。 语言特点如下&#xff1a; &#xff08;1&#xff09;Scala和Java一样属于JVM语言&#xff0c;使用时都需要先编译为class字节码文件&#xff0c;并且Scala能够直接调用Java的类库。 &#…

Linux进程信号 | 信号处理

前面的文章中我们讲述了信号的产生与信号的保存这两个知识点&#xff0c;在本文中我们将继续讲述与信号处理有关的信息。 信号处理 之前我们说过在收到一个信号的时候&#xff0c;这个信号不是立即处理的&#xff0c;而是要得到的一定的时间。从信号的保存中我们可以知道如果…

CSP-J组初赛历年真题讲解第1篇

一、二进制基础 1.二进制数 00100100 和 00010100 的和是( )。 A.00101000 B.01100111 C.01000100 D.00111000 来源&#xff1a;模拟试题正确答案&#xff1a;D 讲解&#xff1a; 2.在二进制下&#xff0c;1011001()11001101011001( )1100110 A. 1011 B. 1101 C. 1010…

仓库Vuex

1. 搭建vuex仓库 1.1 安装 npm install vuexnext 1.2 引入 创建store文件夹&#xff0c;里面创建index.js&#xff0c;该js文件中写&#xff1a; import { createStore } from vuex // 引入子仓库 import model1 from "./model1.js" import model2 from "…

行为型设计模式05-备忘录模式

&#x1f9d1;‍&#x1f4bb;作者&#xff1a;猫十二懿 ❤️‍&#x1f525;账号&#xff1a;CSDN 、掘金 、个人博客 、Github &#x1f389;公众号&#xff1a;猫十二懿 备忘录模式 1、备忘录模式介绍 备忘录模式是一种行为型设计模式&#xff0c;用于在不破坏封装性的前提…

Spring Resources资源操作

文章目录 1、Spring Resources概述2、Resource接口3、Resource的实现类3.1、UrlResource访问网络资源3.2、ClassPathResource 访问类路径下资源3.3、FileSystemResource 访问文件系统资源3.4、ServletContextResource3.5、InputStreamResource3.6、ByteArrayResource 4、Resour…

H桥级联型五电平三相逆变器MATLAB仿真模型

H桥级联型五电平逆变器MATLAB仿真模型资源-CSDN文库https://download.csdn.net/download/weixin_56691527/87899094 模型简介&#xff1a; MATLAB21b版本 逆变器采用H桥级联的形式连接&#xff0c;加设LCL滤波器&#xff0c;三相负载构成主电路。 采用SPWM调制&#xff0c;可…

不宜使用Selenium自动化的10个测试场景

尽管在很多情况下测试自动化是有意义的&#xff0c;但一些测试场景是不应该使用自动化测试工具的&#xff0c;比如Selenium、WebDriver。 下面有10个示例&#xff0c;来解释为什么自动化在这种情况下使用时没有意义的&#xff0c;我还将为您提供每种方法的替代方法。 01.验证…