OpenCV15-图像边缘检测:Sobel、Scharr、Laplace、Canny

news2024/12/23 10:58:47

OpenCV15-图像边缘检测:Sobel、Scharr、Laplace、Canny

    • 1.边缘检测原理
    • 2.Sobel算子
    • 3.Scharr算子
    • 4.生成边缘检测滤波器
    • 5.Laplacian算子
    • 6.Canny算法


1.边缘检测原理

图像的边缘指的是图像中像素灰度值突然发生变化的区域,如果将图像中的每一行像素和每一列像素都描述成一个关于灰度值的函数,那么图像的边缘对应在灰度值函数中是函数值突然变大的区域。函数值得变化趋势可以用导数描述,当函数值突然变大时,导数也必然会变大,而函数值变化较为平缓时,导数值也比较小,因此可以通过寻找导数值较大的区域寻找函数中突然变化的区域,进而确定图像中的边缘位置。

由于图像是练得信号,因此我们可以用临近的两个像素值来表示像素灰度值函数的导数,求导形式表示如下:
d f ( x , y ) d x = f ( x , y ) − f ( x − 1 , y ) \frac{df(x,y)}{dx} = f(x,y) - f(x-1,y) dxdf(x,y)=f(x,y)f(x1,y)
这种对x轴方向的滤波器为 [ − 1 1 ] \begin{bmatrix} -1 & 1 \end{bmatrix} [11],同样对y轴方向的求导对应的滤波器为 [ − 1 1 ] T \begin{bmatrix} -1 & 1 \end{bmatrix}^T [11]T

而表示某个像素处的梯度,最接近的方式是求取前一个像素和后一个像素的差值,于是修改上式为:
d f ( x , y ) d x = f ( x + 1 , y ) − f ( x − 1 , y ) 2 \frac{df(x,y)}{dx} = \frac{f(x+1,y) - f(x-1,y)}{2} dxdf(x,y)=2f(x+1,y)f(x1,y)
改进的求导方式对应的滤波器在 X 方向和 Y 方向分别为 [ − 0.5 0 0.5 ] \begin{bmatrix} -0.5 & 0 & 0.5 \end{bmatrix} [0.500.5] [ − 0.5 0 0.5 ] T \begin{bmatrix} -0.5 & 0 & 0.5 \end{bmatrix}^T [0.500.5]T

根据这种方式,也可以使用下面的滤波器计算 4 5 ∘ 45^\circ 45 方向的梯度:

X Y = [ 1 0 0 − 1 ] Y X = [ 0 1 − 1 0 ] XY = \begin{bmatrix} 1 & 0 \\ 0 & -1 \\ \end{bmatrix} YX = \begin{bmatrix} 0 & 1 \\ -1 & 0 \\ \end{bmatrix} XY=[1001]YX=[0110]

图像的边缘有可能是由高像素值变为低像素值,也有可能是由低像素值变成高像素值。通过上面的梯度公式,得到正数值表示像素值突然由低变高,得到的负数值表示像素值由高到低,这两种都是图像的边缘,因此,为了在图像中同时表示出这两种边缘信息,需要将计算的结果求取绝对值。

OpenCV中提供了 convertScaleAbs() 函数用于计算矩阵中的所有数据的的绝对值:

void convertScaleAbs(
    InputArray src,    // 输入图像
    OutputArray dst,   // 输出图像
    double alpha = 1,  // 缩放因子
    double beta = 0    // 偏置值
);

下面代码中给出了利用 filter2D() 函数实现图像边缘检测的算法,需要说明的是,由于求取边缘的结果可能会有负值,不在原始图像的 CV_8U 数据范围内,因此滤波后的图像数据类型不要用 “-1” ,而应该为 CV_16S。

#include <opencv2\opencv.hpp>
#include <opencv2/core/utils/logger.hpp> // debug no log

using namespace cv;
using namespace std;

int main()
{
	cout << "OpenCV Version: " << CV_VERSION << endl;
	utils::logging::setLogLevel(utils::logging::LOG_LEVEL_SILENT);

	//创建边缘检测滤波器
	Mat kernel1 = (Mat_<float>(1, 2) << 1, -1);  //X方向边缘检测滤波器
	Mat kernel2 = (Mat_<float>(1, 3) << 1, 0, -1);  //X方向边缘检测滤波器
	Mat kernel3 = (Mat_<float>(3, 1) << 1, 0, -1);  //X方向边缘检测滤波器
	Mat kernelXY = (Mat_<float>(2, 2) << 1, 0, 0, -1);  //由左上到右下方向边缘检测滤波器
	Mat kernelYX = (Mat_<float>(2, 2) << 0, -1, 1, 0);  //由右上到左下方向边缘检测滤波器

	//读取图像,黑白图像边缘检测结果较为明显
	Mat img = imread("equalLena.png", IMREAD_ANYCOLOR);
	if (img.empty())
	{
		cout << "请确认图像文件名称是否正确" << endl;
		return -1;
	}
	Mat result1, result2, result3, result4, result5, result6;

	//检测图像边缘
	//以[1 -1]检测水平方向边缘
	filter2D(img, result1, CV_16S, kernel1);
	convertScaleAbs(result1, result1);

	//以[1 0 -1]检测水平方向边缘
	filter2D(img, result2, CV_16S, kernel2);
	convertScaleAbs(result2, result2);

	//以[1 0 -1]'检测由垂直方向边缘
	filter2D(img, result3, CV_16S, kernel3);
	convertScaleAbs(result3, result3);

	//整幅图像的边缘
	result6 = result2 + result3;
	//检测由左上到右下方向边缘
	filter2D(img, result4, CV_16S, kernelXY);
	convertScaleAbs(result4, result4);

	//检测由右上到左下方向边缘
	filter2D(img, result5, CV_16S, kernelYX);
	convertScaleAbs(result5, result5);

	//显示边缘检测结果
	imshow("result1", result1);
	imshow("result2", result2);
	imshow("result3", result3);
	imshow("result4", result4);
	imshow("result5", result5);
	imshow("result6", result6);

	waitKey(0);
	return 0;
}

2.Sobel算子

使用Sobel边缘检测算子提取图像边缘的过程:

1.提取 X 方向的边缘,X方向的一阶 Sobel 边缘检测算子:
[ − 1 0 1 − 2 0 2 − 1 0 1 ] \begin{bmatrix} -1 & 0 & 1 \\ -2 & 0 & 2 \\ -1 & 0 & 1 \\ \end{bmatrix} 121000121
2.提取 Y 方向的边缘,Y方向的一阶 Sobel 边缘检测算子:
[ − 1 − 2 − 1 0 0 0 1 2 1 ] \begin{bmatrix} -1 & -2 & -1 \\ 0 & 0 & 0 \\ 1 & 2 & 1 \\ \end{bmatrix} 101202101
3.综合两个方向的边缘信息得到整幅图像的边缘。由两个方向的边缘得到整幅图像的边缘有两种计算方式,第一种是求取两幅图像对应像素的像素值的绝对值之和,第二种是求取两幅图像对应像素值的平方和的二次方根:
I ( x , y ) = I x ( x , y ) 2 + I y ( x , y ) 2 I ( x , y ) = ∣ I x ( x , y ) ∣ + ∣ I y ( x , y ) ∣ \begin{align} I(x,y) &= \sqrt{I_x(x,y)^2 + I_y(x,y)^2} \\ I(x,y) &= |I_x(x,y)| + |I_y(x,y)| \\ \end{align} I(x,y)I(x,y)=Ix(x,y)2+Iy(x,y)2 =Ix(x,y)+Iy(x,y)
OpenCV提供了对图像提取 Sobel 边缘的 Sobel() 函数:

void Sobel(
    InputArray src, 
    OutputArray dst, 
    int ddepth, // 输出图像的数据类型,-1表示自动选择
    int dx, // X方向差分阶数,即使用几阶Sobel算子
    int dy, // Y方向差分阶数,即使用几阶Sobel算子
    int ksize = 3, // Sobel算子尺寸,必须是1,3,5,7
    double scale = 1, // 对导数计算结果进行缩放
    double delta = 0, // 偏置值
    int borderType = BORDER_DEFAULT
);

dx、dy、ksize:任意一个方向的差分阶数都需要小于算子的尺寸。但有以下特殊情况:当ksize=1时,任意一个方向的阶数都需要小于3。

一般情况下,当差分阶数的最大值取1时,ksize取3;当差分阶数的最大值取2时,ksize取5;当差分阶数的最大值取3时,ksize取7;

当ksize=1时,程序中使用的算子尺寸不再是正方形,而是3x1或者1x3。

#include <opencv2\opencv.hpp>
#include <opencv2/core/utils/logger.hpp> // debug no log

using namespace cv;
using namespace std;

int main()
{
	cout << "OpenCV Version: " << CV_VERSION << endl;
	utils::logging::setLogLevel(utils::logging::LOG_LEVEL_SILENT);

	//读取图像,黑白图像边缘检测结果较为明显
	Mat img = imread("equalLena.png", IMREAD_ANYCOLOR);
	if (img.empty())
	{
		cout << "请确认图像文件名称是否正确" << endl;
		return -1;
	}
	Mat resultX, resultY, resultXY;

	//X方向一阶边缘
	Sobel(img, resultX, CV_16S, 1, 0, 1);
	convertScaleAbs(resultX, resultX);

	//Y方向一阶边缘
	Sobel(img, resultY, CV_16S, 0, 1, 3);
	convertScaleAbs(resultY, resultY);

	//整幅图像的一阶边缘
	resultXY = resultX + resultY;

	//显示图像
	imshow("resultX", resultX);
	imshow("resultY", resultY);
	imshow("resultXY", resultXY);

	waitKey(0);
	return 0;
}

3.Scharr算子

虽然Sobel算子可以有效地提取图像边缘,但是对于图像中较弱的边缘提取效果较差。因此,为了能够有效地提出较弱的边缘,需要将像素值间的差距值增大。

Socharr算子是对Sobel算子差异性的增强,两者在检测图像边缘的原理和使用方式上相同,Scharr算子在X方向和Y方向的边缘检测算子:
G x = [ − 3 0 3 − 10 0 10 − 3 0 3 ] G y = [ − 3 − 10 − 3 0 0 0 3 10 3 ] G_x = \begin{bmatrix} -3 & 0 & 3 \\ -10 & 0 & 10 \\ -3 & 0 & 3 \\ \end{bmatrix} G_y = \begin{bmatrix} -3 & -10 & -3 \\ 0 & 0 & 0 \\ 3 & 10 & 3 \\ \end{bmatrix} Gx= 31030003103 Gy= 30310010303
OpenCV提供了对图像提取Scharr边缘的 Scharr() 函数:

void Scharr(
    InputArray src, 
    OutputArray dst, 
    int ddepth,
    int dx, 
    int dy, 
    double scale = 1, 
    double delta = 0,
    int borderType = BORDER_DEFAULT
);

dx和dy只能有一个为1,并且不能同时为0。

下面代码中,分别提取X方向和Y方向边缘,并利用这两个方向的边缘求取整幅图像的边缘。可以看出Scharr算子比Sobel算子提取到更微弱的边缘。

#include <opencv2\opencv.hpp>
#include <opencv2/core/utils/logger.hpp> // debug no log

using namespace cv;
using namespace std;

int main()
{
	cout << "OpenCV Version: " << CV_VERSION << endl;
	utils::logging::setLogLevel(utils::logging::LOG_LEVEL_SILENT);

	//读取图像,黑白图像边缘检测结果较为明显
	Mat img = imread("equalLena.png", IMREAD_ANYDEPTH);
	if (img.empty())
	{
		cout << "请确认图像文件名称是否正确" << endl;
		return -1;
	}
	Mat resultX, resultY, resultXY;

	//X方向一阶边缘
	Scharr(img, resultX, CV_16S, 1, 0);
	convertScaleAbs(resultX, resultX);

	//Y方向一阶边缘
	Scharr(img, resultY, CV_16S, 0, 1);
	convertScaleAbs(resultY, resultY);

	//整幅图像的一阶边缘
	resultXY = resultX + resultY;

	//显示图像
	imshow("resultX", resultX);
	imshow("resultY", resultY);
	imshow("resultXY", resultXY);

	waitKey(0);
	return 0;
}

4.生成边缘检测滤波器

Scharr算子只有上面的两种,而Sobel算子有不同的尺寸、不同阶数。OpenCV中提供了 getDerivKernels() 函数可以得到不同尺寸、不同阶数的Sobel算子和Scharr算子滤波器。

void getDerivKernels(
    OutputArray kx, // 行滤波器系数输出矩阵 ksize x 1
    OutputArray ky, // 列滤波器系数输出矩阵 ksize x 1 
    int dx,     // X方向导数的阶次
    int dy,     // Y方向导数的阶次
    int ksize,  // 滤波器的大小可以为FILTER_SCHARR、1、3、5、7
    bool normalize = false, // 是否归一化
    int ktype = CV_32F      // 滤波器系数类型,CV_32F、CV_64F
);

下面的例子中给出利用 getDerivKernels() 函数生成Sobel算子和Scharr算子的代码:

#include <opencv2\opencv.hpp>
#include <opencv2/core/utils/logger.hpp> // debug no log

using namespace cv;
using namespace std;

int main()
{
	cout << "OpenCV Version: " << CV_VERSION << endl;
	utils::logging::setLogLevel(utils::logging::LOG_LEVEL_SILENT);

	Mat sobel_x1, sobel_y1, sobel_x2, sobel_y2, sobel_x3, sobel_y3;  //存放分离的Sobel算子
	Mat scharr_x, scharr_y;  //存放分离的Scharr算子
	Mat sobelX1, sobelX2, sobelX3, scharrX;  //存放最终算子

	//一阶X方向Sobel算子
	getDerivKernels(sobel_x1, sobel_y1, 1, 0, 3);
	sobel_x1 = sobel_x1.reshape(CV_8U, 1);
	sobelX1 = sobel_y1 * sobel_x1;  //计算滤波器

	//二阶X方向Sobel算子
	getDerivKernels(sobel_x2, sobel_y2, 2, 0, 5);
	sobel_x2 = sobel_x2.reshape(CV_8U, 1);
	sobelX2 = sobel_y2 * sobel_x2;  //计算滤波器

	//三阶X方向Sobel算子
	getDerivKernels(sobel_x3, sobel_y3, 3, 0, 7);
	sobel_x3 = sobel_x3.reshape(CV_8U, 1);
	sobelX3 = sobel_y3 * sobel_x3;  //计算滤波器

	//X方向Scharr算子
	getDerivKernels(scharr_x, scharr_y, 1, 0, FILTER_SCHARR);
	scharr_x = scharr_x.reshape(CV_8U, 1);
	scharrX = scharr_y * scharr_x;  //计算滤波器

	//输出结果
	cout << "X方向一阶Sobel算子:" << endl << sobelX1 << endl;
	cout << "X方向二阶Sobel算子:" << endl << sobelX2 << endl;
	cout << "X方向三阶Sobel算子:" << endl << sobelX3 << endl;
	cout << "X方向Scharr算子:" << endl << scharrX << endl;

	waitKey(0);
	return 0;
}
/*
X方向一阶Sobel算子:
[-1, 0, 1;
 -2, 0, 2;
 -1, 0, 1]
X方向二阶Sobel算子:
[1, 0, -2, 0, 1;
 4, 0, -8, 0, 4;
 6, 0, -12, 0, 6;
 4, 0, -8, 0, 4;
 1, 0, -2, 0, 1]
X方向三阶Sobel算子:
[-1, 0, 3, 0, -3, 0, 1;
 -6, 0, 18, 0, -18, 0, 6;
 -15, 0, 45, 0, -45, 0, 15;
 -20, 0, 60, 0, -60, 0, 20;
 -15, 0, 45, 0, -45, 0, 15;
 -6, 0, 18, 0, -18, 0, 6;
 -1, 0, 3, 0, -3, 0, 1]
X方向Scharr算子:
[-3, 0, 3;
 -10, 0, 10;
 -3, 0, 3]
*/

5.Laplacian算子

上述的边缘检测算子都具有方向性,因此都需要分别求取X方向的边缘和Y方向的边缘,之后将两个方向的边缘综合得到图像的整体边缘。Laplacian算子具有各个方向同性的特点,能够对任意方向的边缘进行提取,具有无方向性的优点。

Laplacian算子是一种二阶导数算子,对噪声比较敏感,因此常需要配合高斯滤波一起使用。

二维图像函数 f ( x , y ) f(x,y) f(x,y) ,图像的Laplace运算二阶导数定义:
∇ 2 f ( x , y ) = ∂ 2 f ∂ x 2 + ∂ 2 f ∂ y 2 \nabla^2 f(x,y) = \frac{\partial^2 f}{\partial x^2} + \frac{\partial^2 f}{\partial y^2} 2f(x,y)=x22f+y22f
对于二维离散图像而言,图像的Laplace可表示吐下:
∇ 2 f ( x , y ) = f ( x + 1 , y ) + f ( x − 1 , y ) + f ( x , y + 1 ) + f ( x , y − 1 ) − 4 f ( x , y ) \nabla^2 f(x,y) = f(x+1,y) + f(x-1,y) + f(x,y+1) + f(x,y-1) - 4f(x,y) 2f(x,y)=f(x+1,y)+f(x1,y)+f(x,y+1)+f(x,y1)4f(x,y)
根据离散Laplace表达式,可以得到其滤波器:
G 1 = [ 0 1 0 1 − 4 1 0 1 0 ] G 2 = [ 1 1 1 1 − 8 1 1 1 1 ] G_1 = \begin{bmatrix} 0 & 1 & 0 \\ 1 & -4 & 1 \\ 0 & 1 & 0 \\ \end{bmatrix} G_2 = \begin{bmatrix} 1 & 1 & 1 \\ 1 & -8 & 1 \\ 1 & 1 & 1 \\ \end{bmatrix} G1= 010141010 G2= 111181111
G 1 G_1 G1 G 2 G_2 G2 分别为离散拉普拉斯算子的模版与拓展模版,利用函数模版可以将图像中的奇异点如亮点变得更亮。对于图像中灰度变化剧烈的区域,拉普拉斯算子能实现其边缘检测。

OpenCV提供了Laplacian算子提取图像边缘的 Laplacian() 函数:

void Laplacian(
    InputArray src,
    OutputArray dst, 
    int ddepth,
    int ksize = 1,    // 滤波器大小,必须为正奇数
    double scale = 1, 
    double delta = 0,
    int borderType = BORDER_DEFAULT
);

ksize=1时,采用 G 1 G_1 G1 拉普拉斯算子。

下面代码中,采用图像去噪后通过拉普拉斯算子提取边缘变得更加准确:

#include <opencv2\opencv.hpp>
#include <opencv2/core/utils/logger.hpp> // debug no log

using namespace cv;
using namespace std;

int main()
{
	cout << "OpenCV Version: " << CV_VERSION << endl;
	utils::logging::setLogLevel(utils::logging::LOG_LEVEL_SILENT);

	//读取图像,黑白图像边缘检测结果较为明显
	Mat img = imread("equalLena.png", IMREAD_ANYDEPTH);
	if (img.empty())
	{
		cout << "请确认图像文件名称是否正确" << endl;
		return -1;
	}
	Mat result, result_g, result_G;

	//未滤波提取边缘
	Laplacian(img, result, CV_16S, 3, 1, 0);
	convertScaleAbs(result, result);

	//滤波后提取Laplacian边缘
	GaussianBlur(img, result_g, Size(3, 3), 5, 0);  //高斯滤波
	Laplacian(result_g, result_G, CV_16S, 3, 1, 0);
	convertScaleAbs(result_G, result_G);

	//显示图像
	imshow("result", result);
	imshow("result_G", result_G);

	waitKey(0);
	return 0;
}

6.Canny算法

Canny算法不容易受到噪声的影响,能够识别图像中的若边缘和强边缘,并结合强弱边缘的位置关系,综合给出图像整体的边缘信息。Canny边缘检测算法是目前最优越的边缘检测算法之一。该方法的检测过程:

1.使用高斯滤波去噪,平滑图像,下面是5x5的高斯滤波器:
G = 1 139 [ 2 4 5 4 2 4 9 12 9 4 5 12 15 12 5 4 9 12 9 4 2 4 5 4 2 ] G = \frac{1}{139} \begin{bmatrix} 2 & 4 & 5 & 4 & 2 \\ 4 & 9 & 12 & 9 & 4 \\ 5 & 12 & 15 & 12 & 5 \\ 4 & 9 & 12 & 9 & 4 \\ 2 & 4 & 5 & 4 & 2 \\ \end{bmatrix} G=1391 245424912945121512549129424542
2.计算图像中每个像素的梯度幅值与方向。可以通过Sobel算子分别检测图像X方向和Y方向边缘,之后利用下面公式计算梯度的方向和幅值:
θ = a r c t a n ( I y I x ) G = a r c t a n I x 2 + I y 2 \theta = arctan(\frac{I_y}{I_x}) \\ G = arctan\sqrt{I_x^2 + I_y^2} θ=arctan(IxIy)G=arctanIx2+Iy2
其中梯度方向近似到下面4个取值: 0 ∘ 0^\circ 0 4 5 ∘ 45^\circ 45 9 0 ∘ 90^\circ 90 13 5 ∘ 135^\circ 135

3.利用非极大值抑制算法消除边缘检测带来的杂散响应。通俗意义上是指寻找像素点局部最大值,将非极大值点所对应的灰度值设置为背景像素点,如像素领域区域满足梯度值的局部最优值判断为该像素的边缘,对其余非极大值的相关信息进行抑制。

4.应用双阈值法划分强边缘和弱边缘。如果某一像素位置的幅值超过高阈值,该像素被保留为边缘;如果某一像素位置的幅值小于低阈值,该像素被排除;如果某一像素位置的幅值在两个阈值之间,该像素仅仅在连接到一个高于阈值的像素时被保留。推荐高与低阈值比在 2:13:1 之间。

Canny算法流程复杂,好在OpenCV中提供了 Canny() 函数实现Canny算法检测图像中的边缘:

void Canny(
    InputArray image,  // CV_8U
    OutputArray edges, 
    double threshold1, // 第一个滞后阈值
    double threshold2, // 第二个滞后阈值
    int apertureSize = 3,   // Sobel算子直径
    bool L2gradient = false // 计算图像梯度幅值的方法是否使用L2范数
);

下面的代码中,通过设置不同的阈值来比较阈值的大小对图像边缘检测效果的影响,可以发现,较高的阈值会降低噪声信息的影响,但是也会减少边缘信息。

#include <opencv2\opencv.hpp>
#include <opencv2/core/utils/logger.hpp> // debug no log

using namespace cv;
using namespace std;

int main()
{
	cout << "OpenCV Version: " << CV_VERSION << endl;
	utils::logging::setLogLevel(utils::logging::LOG_LEVEL_SILENT);

	//读取图像,黑白图像边缘检测结果较为明显
	Mat img = imread("equalLena.png", IMREAD_ANYDEPTH);
	if (img.empty())
	{
		cout << "请确认图像文件名称是否正确" << endl;
		return -1;
	}
	Mat resultHigh, resultLow, resultG;

	//大阈值检测图像边缘
	Canny(img, resultHigh, 100, 200, 3);

	//小阈值检测图像边缘
	Canny(img, resultLow, 20, 40, 3);

	//高斯模糊后检测图像边缘
	GaussianBlur(img, resultG, Size(3, 3), 5);
	Canny(resultG, resultG, 100, 200, 3);

	//显示图像
	imshow("resultHigh", resultHigh);
	imshow("resultLow", resultLow);
	imshow("resultG", resultG);

	waitKey(0);
	return 0;
}

Canny边缘检测

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

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

相关文章

功能集成,不占空间,同为科技TOWE嵌入式桌面PDU超级插座

随着现代社会人们生活水平的不断提高&#xff0c;消费者对生活质量有着越来越高的期望。生活中&#xff0c;各式各样的电气设备为我们的生活带来了便利&#xff0c;在安装使用这些用电器时&#xff0c;需要考虑电源插排插座的选择。传统的插排插座设计多暴露于空间之中&#xf…

直播美颜技术的技术背后:美颜SDK的原理与实践

对于美颜美颜SDK来说大家都不会陌生&#xff0c;通过它&#xff0c;我们能够实现实时美颜效果&#xff0c;改善视频质量&#xff0c;吸引更多观众。 一、美颜SDK是什么&#xff1f; 美颜SDK为开发者提供了一整套美颜和图像处理功能&#xff0c;用于实时处理直播视频流。这个工…

Android USB分析

先下一个定论&#xff0c;常规来讲&#xff0c;所有作slave的android设备都是配件&#xff0c;作为主机的android设备还是叫Host。此外还有usb tethering支持的radnis功能以及ncm功能&#xff0c;这两个是网络相关的usb应用&#xff0c;使用usb模拟网卡。其中radnis属于上网能力…

如何减轻软件测试的时间压力?6大注意事项

软件测试处于软件研发流程的下游。如果上游的项目进度延迟&#xff0c;往往会遇到通过压缩测试时间来按时交付的情况。 因此软件测试人员经常遇到时间压力&#xff0c;可能会为了赶时间草率测试&#xff0c;导致测试人员无法充分地测试所有功能和场景&#xff0c;影响测试的覆盖…

如何制作有专业水准的的电子杂志:专家教你秘籍

​随着数字化时代的到来&#xff0c;电子杂志作为一种新型的传媒形式&#xff0c;越来越受到人们的关注和喜爱。但是&#xff0c;如何制作一份具有专业水准的电子杂志呢&#xff1f; 今天&#xff0c;给大家分享一款在线就能制作的电子杂志------FLBOOK&#xff0c;让你轻松打造…

【mac】常用命令01

1、如何像windows一样看磁盘&#xff1f; 不断的在上层文件夹显示&#xff0c;找到最上层&#xff0c;拖拽到左侧&#xff0c;方便之后找 2、Macintosh HD显示隐藏文件夹方法 终端窗口&#xff1a; defaults write com.apple.finder AppleShowAllFiles true killall Finder 或者…

Java发起Soap请求

目录 1.前言2.请求报文格式2.1不带表头的请求格式2.2带表头的请求格式 3 请求代码实例3.1解析Soap返回的XML&#xff0c;提取需要的元素 参考 文章所属专区 超链接 1.前言 SOAP请求&#xff08;Simple Object Access Protocol&#xff0c;简单对象访问协议&#xff09;是HTTP…

CEC2013(MATLAB):猎豹优化算法(The Cheetah Optimizer,CO)求解CEC2013

一、猎豹优化算法CO 猎豹优化算法&#xff08;The Cheetah Optimizer&#xff0c;CO&#xff09;由MohammadAminAkbari等人于2022年提出&#xff0c;该算法性能高效&#xff0c;思路新颖。 参考文献&#xff1a; Akbari, M.A., Zare, M., Azizipanah-abarghooee, R. et al. Th…

word误删除的文件怎么恢复?恢复办法分享

在日常工作和学习中&#xff0c;我们常常会使用到Word来撰写文章、毕业论文、方案等。然而&#xff0c;我们可能会遇到Word误删文件的情况&#xff0c;令我们陷入恐慌&#xff0c;特别是这个文件很重要时。幸运的是&#xff0c;有办法找回。下面一起来看下word误删除的文件怎么…

RFID固定资产管理的应用

在如今的商界竞争中&#xff0c;要确保企业的固定资产管理得当至关重要。庆幸的是&#xff0c;现代科技为这一挑战带来了一项高效的解决方案&#xff0c;那就是RFID技术。 **RFID技术就是借助无线射频通信&#xff0c;通过RFID标签和读写器之间的互动&#xff0c;来识别和跟踪资…

【力扣520】检测大写字母

&#x1f451;专栏内容&#xff1a;力扣刷题⛪个人主页&#xff1a;子夜的星的主页&#x1f495;座右铭&#xff1a;前路未远&#xff0c;步履不停 目录 一、题目描述二、题目分析 一、题目描述 题目链接&#xff1a;检测大写字母 我们定义&#xff0c;在以下情况时&#xff…

ARM Cortex-A9:裸机开发,点亮LED3

1.看原理图 外设板原理图 核心板原理图 2.在芯片手册中找到控制硬件的有效的特殊功能寄存器 选择0x1输出 GPX1DAT[0]->GPX1_0 0->1/0 3.编程 start.s Makefile复制到桌面 使用超级终端&#xff0c;连接串口 随便写一个 选择串口 配置串口 板子上电马上按enter…

MATLAB | 对随机信号进行统计分析,绘制频次直方图、频率分布图,与理论概率密度进行比较

一、问题描述 对于一个随机信号&#xff0c;我们可以通过统计手段&#xff0c;得到其的频次分布图&#xff08;直方图&#xff09;&#xff0c;并由此计算出它的频率分布图。当观察次数区域无穷大时&#xff0c;频率分布图近似于概率密度函数。 下面我们以稳定分布的随机变量为…

MySQL多表查询面试题一

其中分析题意&#xff0c;学生表student是与成绩表score关联&#xff0c;课程表course与教师表teacher关联&#xff0c;由此可以先确定关联关系&#xff0c;学生表为s&#xff0c;课程表为c&#xff0c;教师表为t&#xff0c;成绩表为o。s.s_ido.s_id&#xff0c;c.t_idt.t_id …

SpringBoot核心功能与基础配置

SpringBoot简介 原先的Spring程序缺点&#xff0c;包括依赖设置繁琐&#xff0c;每项jar的引用都需要自己撰写。并且配置繁琐&#xff0c;配置文件中也需要自己写加载bean等。由此针对原始的Spring程序&#xff0c;Pivotal团队提供的全新框架——SpringBoot&#xff0c;其设计…

PyQt 定义控件SwitchButton 指南

PyQt 定义控件SwitchButton 指南 PyQt 定义控件SwitchButton 指南实例程序效果如下所示&#xff1a; PyQt 定义控件SwitchButton 指南 SwitchButton 是一个自定义开关按钮控件&#xff0c;通常用于在用户界面中启用或禁用某些功能或选项。它是一种用户友好的控件&#xff0c;允…

云汉芯城一站式电子制造平台启想智联顺利通过IATF16949:2016质量管理体系认证

近日&#xff0c;云汉芯城旗下一站式电子制造服务平台上海启想智能科技有限公司&#xff08;以下简称“启想智联”&#xff09;顺利通过IATF16949:2016质量管理体系认证&#xff0c;并获得由URS颁发的认证证书。通过此项认证&#xff0c;标志着启想智联在全球汽车行业的技术规范…

AdminLTE 2 图标大全

AdminLTE 2 图标大全 链接地址&#xff1a;&#xff1a;&#xff1a;&#xff1a;&#xff1a;AdminLTE 2 | Icons

再也不用花钱了,教你一套键鼠控制多台电脑

Synergy是一款用于多台电脑之间共享键盘和鼠标的软件。它允许用户使用一套键盘和鼠标同时控制多台电脑&#xff0c;极大地提高了工作效率。Synergy支持跨平台使用&#xff0c;包括Windows、Mac和Linux等操作系统。用户只需在每台电脑上安装Synergy客户端&#xff0c;并按照软件…

十四.镜头知识之镜头色差

十四.镜头知识之镜头色差 文章目录 十四.镜头知识之镜头色差**14.1 色差** /Chromatic Aberration/**14.2 纵向色差****14.3 横向色差**14.4 ISP色彩还原同一场景两张由不同镜头拍出来的照片比较:上方的照片来自更高质量的镜头,下方的照片则出现了明显的色差,特别是在房顶右…