Opencv-C++笔记 (13) : opencv-图像卷积一(均值、中值、高斯、双边滤波)与 边缘处理

news2024/11/22 17:31:24

文章目录

  • 一、概述图像滤波
    • 1.1、均值滤波
    • 1.2中值滤波
    • 1.3、高斯滤波
    • 1.4、双边滤波
    • 1.5、方框滤波
  • 二、自定义掩码
  • 三、边缘处理
  • 四、Sobel算子
  • 五、Scharr算子
  • 六、拉普拉斯算子
  • 十、Canny算法

一、概述图像滤波

头文件 quick_opencv.h:声明类与公共函数

#pragma once
#include <opencv2\opencv.hpp>
using namespace cv;

class QuickDemo {
public:
	...
	void blur_Demo(Mat& image);
	void medianblur_Demo(Mat& image);
	void gaussian_Demo(Mat& image);
	void bilateralFilter_Demo(Mat& image);

	void custom_mask_Demo(Mat& image); //自定义掩膜运算
    void edge_process_Demo(Mat& image1);

};

主函数调用

#include <opencv2\opencv.hpp>
#include <quick_opencv.h>
#include <iostream>
using namespace cv;


int main(int argc, char** argv) {
	Mat src = imread("D:\\Desktop\\pandas.jpg");
	if (src.empty()) {
		printf("Could not load images...\n");
		return -1;
	}
	namedWindow("input", WINDOW_NORMAL);
	imshow("input", src);

	QuickDemo qk;

	...
	qk.blur_Demo(src);
	qk.medianblur_Demo(src);
	qk.gaussian_Demo(src);
	qk.bilateralFilter_Demo(src);
	qk.custom_mask_Demo(src);
	qk.edge_process_Demo(src1);
	waitKey(0);
	destroyAllWindows();
	return 0;
}

1.1、均值滤波

blur( InputArray src,OutputArray dst, Size ksize, 
      Point anchor = Point(-1,-1)int borderType = BORDER_DEFAULT)

src:输入图像 。

dst:输出图像 。

ksize:内核大小 ,一般用 Size(w,h),w 为宽度,h 为深度。

anchor:被平滑的点,表示取 内核中心 ,默认值 Point(-1,-1)。

boderType:推断图像外部像素的某种边界模式。默认值 BORDER_DEFAULT

目的:去除图像上的尖锐噪声,平滑图像。 原理:均值滤波属于线性滤波,它的实现原理是邻域平均法
在这里插入图片描述
源文件 quick_demo.cpp:实现类与公共函数

void QuickDemo::blur_Demo(Mat& image) {
	Mat dst, dst1, dst2;
	blur(image, dst, Size(5, 5), Point(-1, -1));
	blur(image, dst1, Size(15, 1), Point(-1, -1));
	blur(image, dst2, Size(1, 15), Point(-1, -1));
	imshow("均值滤波", dst);
	imshow("横向滤波", dst1);
	imshow("竖直滤波", dst2);
}

在这里插入图片描述

1.2中值滤波

medianBlur(InputArray src,OutputArray dst,int ksize)

src:输入图像 。

dst:输出图像 。

ksize:孔径的线性尺寸,这个参数必须是大于1 的奇数

统计排序滤波器 中值对椒盐噪声有很好的抑制作用

void QuickDemo::medianblur_Demo(Mat& image) {
	Mat dst, dst1, dst2;
	medianBlur(image.clone(), dst, (3, 3));
	medianBlur(image.clone(), dst1, (5, 5));
	medianBlur(image.clone(), dst2, (7, 7));
	imshow("中值滤波", dst);
	imshow("中值滤波1", dst1);
	imshow("中值滤波2", dst2);
}

在这里插入图片描述

1.3、高斯滤波

GaussianBlur( InputArray src, OutputArray dst, Size ksize,
                   double sigmaX, double sigmaY = 0,
                   int borderType = BORDER_DEFAULT )

src:输入图像 。

dst:输出图像 。

ksize:ksize.width 和 ksize.height 可以不同,但他们都必须为正数和奇数,或者为0,可由 sigma 计算而来

sigmaX:高斯核函数在 X 方向的的标准差

sigmaY:高斯核函数在 Y 方向的的标准差

若 sigmaY 为零,就将它设为 sigmaX;若 sigmaX 和 sigmaY 都是0,那么就由 ksize.width 和 ksize.height 计算出来

高斯滤波是一种线性平滑滤波,适用于消除高斯噪声,广泛应用于图像处理的减噪过程。

高斯滤波就是对整幅图像进行加权平均的过程,每一个像素点的值,都由其本身和邻域内的其他像素值经过加权平均后得到。

高斯滤波的具体操作是:用一个模板(或称卷积、掩模)扫描图像中的每一个像素,用模板确定的邻域内像素的加权平均灰度值去替代模板中心像素点的值。
在这里插入图片描述
在这里插入图片描述

void QuickDemo::gaussian_Demo(Mat& image) {
	Mat dst;
	GaussianBlur(image, dst, Size(5, 5), 15);
	imshow("高斯滤波", dst);
}

1.4、双边滤波

边缘保留滤波算法:

  • 高斯双边滤波
  • Meanshift均值迁移模糊
  • 局部均方差模糊
  • 导向滤波

双边滤波的原理示意图:
在这里插入图片描述

void bilateralFilter(
InputArray src,    输入图像
OutputArray dst,   目标图像,需要和源图片有一样的尺寸和类型
int d,        在过滤期间使用的每个像素邻域的直径。如果输入d非0(没输入),则sigmaSpace由d计算得出。
double sigmaColor,  颜色空间滤波器的sigma值,这个参数的值越大,就表明该像素邻域内有更宽广的颜色会被混合到一起,产生较大的半相等颜色区域。
double sigmaSpace, 坐标空间滤波器的sigma值,坐标空间的标注方差。他的数值越大,意味着越远的像素会相互影响,从而使更大的区域足够相似的颜色获取相同的颜色。当d>0,d指定了邻域大小且与sigmaSpace无关。否则,d正比于sigmaSpace。
int borderType = BORDER_DEFAULT  图像边界模式
)

src: 输入图像,可以是Mat类型,图像必须是8位或浮点型单通道、三通道的图像。
dst: 输出图像,和原图像有相同的尺寸和类型。
d: 表示在过滤过程中每个像素邻域的直径范围。如果这个值是非正数,则函数会从第五个参数sigmaSpace计算该值。
sigmaColor:颜色空间过滤器的sigma值,这个参数的值月大,表明该像素邻域内有月宽广的颜色会被混合到一起,产生较大的半相等颜色区域。
sigmaSpace: 坐标空间中滤波器的sigma值,如果该值较大,则意味着颜色相近的较远的像素将相互影响,从而使更大的区域中足够相似的颜色获取相同的颜色。当d>0时,d指定了邻域大小且与sigmaSpace五官,否则d正比于sigmaSpace.
borderType=BORDER_DEFAULT: 用于推断图像外部像素的某种边界模式,有默认值BORDER_DEFAULT.

void QuickDemo::bilateralFilter_Demo(Mat& image) {
	Mat dst;
	bilateralFilter(image, dst, 0, 100.0, 10.0);
	imshow("双边滤波", dst);
}

在这里插入图片描述

1.5、方框滤波

boxFilter( InputArray src, OutputArray dst, int ddepth,
                Size ksize, Point anchor = Point(-1,-1),
                bool normalize = true,
                int borderType = BORDER_DEFAULT )

src:输入图像

dst:输出图像

ddepth:输出图像的深度,-1 代表使用原图深度

ksize: 滤波内核的大小。一般这样写Size(w, h)来表示内核的大小,Size(10, 10)就表示 10x10 的核大小

anchor = Point(-1,-1) :表示锚点(即被平滑的那个点),注意他有默认值Point(-1,-1)
如果这个点坐标是负值的话,就表示取核的中心为锚点,所以默认值Point(-1,-1)表示这个锚点在核的中心。

normalize = true:默认值为true,一个标识符,表示内核是否被其区域归一化(normalized)了

borderType =BORDER_DEFAULT:用于推断图像外部像素的某种边界模式。有默认值BORDER_DEFAULT,我们一般不去管它。

二、自定义掩码

在这里插入图片描述

Mat kernel_ = (Mat_<char>(3, 3) << 0, -1, 0, 
							      -1, 5, -1, 
		                           0, -1, 0);
void filter2D(
InputArray src,     输入图像
OutputArray dst,     输出图像,和输入图像具有相同的尺寸和通道数量
int ddepth,      目标图像深度,为-1时保持输入图像通道深度
InputArray kernel,    卷积核
Point anchor=Point(-1,-1),表示过滤点在内核中的相对位置的内核锚;锚应位于内核内;默认值(-1-1)表示锚点位于内核中心。
double delta=0,     在储存目标图像前可选的添加到像素的值,默认值为0
int borderType=BORDER_DEFAULT   默认值是BORDER_DEFAULT,即对全部边界进行计算。
);

在这里插入图片描述

void QuickDemo::custom_mask_Demo(Mat& image) {
	// 自定义filter函数实现
	int offset = image.channels();
	int cols = (image.cols - 1) * offset;
	int rows = image.rows;
	Mat dst = Mat::zeros(image.size(), image.type());
	for (int row = 1; row < (rows - 1); row++) {
		const uchar* previous = image.ptr<uchar>(row-1);
		const uchar* current = image.ptr<uchar>(row);
		const uchar* next = image.ptr<uchar>(row+1);
		uchar* output = dst.ptr<uchar>(row);
		for (int col = offset; col < cols; col++) {
			output[col] = saturate_cast<uchar>(5 * current[col] - (current[col - offset] + current[col + offset] + previous[col] + next[col]));
		}
	}
	imshow("dst", dst);

	// opencv自带filter2D函数实现
	Mat dst2;
	Mat kernel_ = (Mat_<char>(3, 3) << 0, -1, 0, -1, 5, -1, 0, -1, 0);
	filter2D(image.clone(), dst2, image.depth(), kernel_);
	imshow("dst2", dst2);
}

可以看出dst2没有黑边了,边缘被处理了。
在这里插入图片描述

三、边缘处理

在卷积开始之前增加边缘像素,填充的像素值为0或者RGB黑色,比如3x3在
四周各填充1个像素的边缘,在卷积处理之后再去掉这些边缘,这样就确保图像的边缘被处理

void copyMakeBorder(
InputArray src,     // 输入图像
OutputArray dst,  // 输出图像
int top,       // 填充边缘长度,一般上下左右都取相同值
int bottom,
int left,
int right,
int borderType,   // 填充类型
const Scalar& value = Scalar() // 边框颜色值,边框类型=BUALE_CONTER时才有用
)

openCV中的处理方法是:

BORDER_DEFAULT  - 默认的处理(镜像边界像素:1234|4321) BORDER_CONSTANT – 填充边缘用指定像素值
BORDER_REPLICATE – 填充边缘像素用已知的边缘像素值。(复制边界像素:1234|4444) BORDER_WRAP –
用另外一边的像素来补偿填充 使用参数

BORDER_CONSTANT = 0
BORDER_REPLICATE = 1
BORDER_REFLECT = 2
BORDER_REFLECT_101 = 4,
BORDER_REFLECT101 = BORDER_REFLECT_101,
BORDER_DEFAULT = BORDER_REFLECT_101,
BORDER_WRAP = 3,
BORDER_TRANSPARENT = 5,

源文件 quick_demo.cpp:实现类与公共函数

void QuickDemo::edge_process_Demo(Mat& image) {
	Mat dst0, dst1;
	copyMakeBorder(image, dst0, 5, 5, 5, 5, BORDER_REFLECT);
	copyMakeBorder(image, dst1, 5, 5, 5, 5, BORDER_CONSTANT,Scalar(0,255,255));
	imshow("REFLECT", dst0);
	imshow("CONSTANT", dst1);
}

在这里插入图片描述

四、Sobel算子

实现步骤:

x轴方向求导 —— y轴方向求导 —— 最终结果为二者相加

函数原型:

Sobel(src,ddepth,dx,dy,ksize=3,…)

离散微分算子(discrete differentiation operator),用来计算图像灰度的近似梯度
Soble算子功能集合高斯平滑和微分求导
一阶微分算子,求导算子,在水平和垂直两个方向上求导,得到图像X方法与Y方向梯度图像
在这里插入图片描述

代码案例:

chess = cv2.imread('chess.png')
# 求y方向边缘
dy = cv2.Sobel(chess, cv2.CV_64F, 1, 0, ksize=5)
# 求x方向边缘
dx = cv2.Sobel(chess, cv2.CV_64F, 0, 1, ksize=5)
# 二者相加
result = dy + dx

cv2.imshow('chess', chess)
cv2.imshow('dy', dy)
cv2.imshow('dx', dx)
cv2.imshow('result', result)
cv2.waitKey(0)

在这里插入图片描述

从上图可以明显看出,当dx设置为1时,求得y方向上的边缘信息,反之也是,最终二者相加的结果也就是Sobel算子的结果。不能一开始就设定dx,dy为1,这样子不能达到该效果;

五、Scharr算子

定义:与Sobel类似,但使用的kernel值不同,并且只能为3x3,只能求x方向或y方向一个方向的边缘信息;
由于Sobel算子求取导数的近似值,kernel=3时不是很准确,图像中较弱的边缘提取效果较差,OpenCV使用改进版本Scharr函数,算子如上右图:

例如一个 3 * 3 的 Sobel 算子,在梯度角度水平或垂直方向时,其不精确性就非常明显。Scharr 算子是对 Sobel 算子差异性的增强,两者之间的在检测图像边缘的原理和使用方式上相同。

而 Scharr 算子的主要思路是通过将模版中的权重系数放大来增大像素值间的差异,也是计算 x 或 y 方向上的图像差分
sobel,Scharr算子等此类算子都是:输出图像深度 >= 输入图像深度 。
在这里插入图片描述

void Sobel(
InputArray src,     输入图像(单通道)
OutputArray dst,     输出图像
int ddepth,       输出图像深度 (>= 输入图像深度)
int dx,         x梯度(几阶导数)一般为012,其中0表示这个方向上没有求导
int dy,         y梯度(几阶导数)
int ksize = 3,      滤波窗口大小(357…)
double scale = 1,    是否缩放,默认=1.0
double delta = 0,     偏移常数
int borderType = BORDER_DEFAULT )  图像边缘处理方式。默认值=cv2.BORDER_DEFAULT

在经过处理后,需要用 convertScaleAbs() 函数将其转回原来的uint8形式,否则将无法显示图像,而只是一副灰色的窗口。

void convertScaleAbs(
InputArray src,       输入图像
OutputArray dst,    输出uint8类型图片
double alpha = 1,     伸缩系数
double beta = 0     偏移值:加到结果上的一个值
)

由于Sobel算子是在两个方向计算的,最后还需要用cv::addWeighted(src1, alpha, src2, beta, gamma, dst)函数将其组合起来。

//头文件 quick_opencv.h:声明类与公共函数
#pragma once
#include <opencv2\opencv.hpp>
using namespace cv;

class QuickDemo {
public:
	...
	void edge_extract_Demo(Mat& image1);
	void laplance_Demo(Mat& image1);
	void canny_Demo(Mat& image1);
};
//主函数调用该类的公共成员函数
#include <opencv2\opencv.hpp>
#include <quick_opencv.h>
#include <iostream>
using namespace cv;


int main(int argc, char** argv) {
	Mat src = imread("D:\\Desktop\\jianbian.png");
	if (src.empty()) {
		printf("Could not load images...\n");
		return -1;
	}
	QuickDemo qk;
	qk.edge_extract_Demo(src1);
	qk.laplance_Demo(src1);
	qk.canny_Demo(src1);
	waitKey(0);
	destroyAllWindows();
	return 0;
}
//源文件 quick_demo.cpp:实现类与公共函数
void QuickDemo::edge_extract_Demo(Mat& image) {
	Mat gau_dst, gray_dst, xgrad, ygrad;
	GaussianBlur(image, gau_dst, Size(3, 3), 10);
	cvtColor(gau_dst, gray_dst, COLOR_BGR2GRAY);

	//Sobel(gray_dst, xgrad, -1, 1, 0, 3);
	//Sobel(gray_dst, ygrad, -1, 0, 1, 3);

	//Sobel(gray_dst, xgrad, CV_16S, 1, 0, 3);
	//Sobel(gray_dst, ygrad, CV_16S, 0, 1, 3);

	Scharr(gray_dst, xgrad, CV_16S, 1, 0, 3);
	Scharr(gray_dst, ygrad, CV_16S, 0, 1, 3);
	convertScaleAbs(xgrad, xgrad);
	convertScaleAbs(ygrad, ygrad);

	Mat xygrad;
	addWeighted(xgrad, 0.5, ygrad, 0.5, 0, xygrad);
	imshow("xgrad", xgrad);
	imshow("ygrad", ygrad);
	imshow("xygrad", xygrad);

	Mat xy_grad = Mat::zeros(xgrad.size(),xgrad.type());
	int width = xgrad.cols;
	int height = xgrad.rows;
	for (int h = 0; h < height; h++) {
		uchar* current_x = xgrad.ptr<uchar>(h);
		uchar* current_y = ygrad.ptr<uchar>(h);
		uchar* current_d = xy_grad.ptr<uchar>(h);
		for (int w = 0; w < width; w++) {
			*current_d++ = saturate_cast<uchar>(*current_x++ + *current_y++);
		}
	}
	imshow("xy_grad", xy_grad);
}

输出图像深度:-1(与原图保持一致)
在这里插入图片描述
输出图像深度:CV_16S 方向梯度细节更多了。

在这里插入图片描述
使用自定义函数直接相加结果(右): (使用addWeighted函数,各方向梯度0.5的权重组合发虚:左)
在这里插入图片描述
测试scharr()效果:细节更加丰富
在这里插入图片描述

六、拉普拉斯算子

优点:可同时求得两个方向的边缘;

缺点:对噪音比较敏感,一般需要先进行去噪在调用拉普拉斯算子;

函数原型:

Laplacian(img,ddepth,ksize=1)
在二阶导数的时候,最大变化处的值为零即边缘是零值。通过二阶导数计算,依据此理论我们可以计算图像二阶导数,提取边缘。
在这里插入图片描述

void Laplacian(
InputArray src,      输入图像(单通道)
OutputArray dst,      输出图像
int ddepth,        输出图像深度 (>= 输入图像深度)
int ksize = 1,       滤波窗口大小(357…)
double scale = 1,     是否缩放,默认=1.0
double delta = 0,     偏移常数
int borderType = BORDER_DEFAULT   图像边缘处理方式
)

一般处理流程

高斯模糊 – 去噪声GaussianBlur()
转换为灰度图像cvtColor()
拉普拉斯 – 二阶导数计算Laplacian()
取绝对值convertScaleAbs()
显示结果

void QuickDemo::laplance_Demo(Mat& image) {
	Mat gau_dst, gray_dst, laplance_dst, ygrad;

	GaussianBlur(image, gau_dst, Size(3, 3), 10);
	cvtColor(gau_dst, gray_dst, COLOR_BGR2GRAY);

	Laplacian(gray_dst, laplance_dst, CV_16S, 3, 1.0, 0);
	convertScaleAbs(laplance_dst, laplance_dst);

	threshold(laplance_dst, laplance_dst, 0, 255, THRESH_OTSU | THRESH_BINARY);
	imshow("laplance_dst", laplance_dst);
}

在这里插入图片描述

chess = cv2.imread('chess.png')
result = cv2.Laplacian(chess, cv2.CV_64F, ksize=5)

cv2.imshow('chess', chess)
cv2.imshow('result', result)
cv2.waitKey(0)

在这里插入图片描述
从效果上看,比起Sobel步骤更加简单,并且效果也比较好,缺点就是如果噪声过多的话效果会比较差

十、Canny算法

实现步骤:

1、使用5x5高斯滤波消除噪音;

2、使用Sobel计算图像梯度的方向(0°、45°、90°、135°);

3、取局部极大值;

4、阈值计算;

函数原型:

Canny(img,minVal,maxVal,…)

其中的minVal和maxVal代表边缘的阈值,两者差值过大的话会损失一定的边缘信息;

代码案例:

img = cv2.imread('1.jpg')
result = cv2.Canny(img, 100, 200)

cv2.imshow('org', img)
cv2.imshow('result', result)
cv2.waitKey(0)

在这里插入图片描述
Canny算法介绍 - 非最大信号抑制
在这里插入图片描述
T1, T2为阈值,凡是高于T2的都保留,凡是小于T1都丢弃,从高于T2的像素出发,凡是大于T1而且相互连接的,都保留。最终得到一个输出二值图像。
推荐的高低阈值比值为 T2: T1 = 3:1/2:1其中T2为高阈值,T1为低阈值

void Canny(
InputArray image,        输入图像(单通道)
OutputArray edges,     输出图像
double threshold1,      阈值T1
double threshold2,     阈值T2 一般为 2*T1
int apertureSize = 3,     Soble算子的size窗口大小 
bool L2gradient = false   默认false L1归一化,Ture则为L2归一化
);

一般处理流程

高斯模糊 - GaussianBlur
灰度转换 - cvtColor
计算梯度 – Sobel/Scharr
非最大信号抑制
高低阈值输出二值图像

void QuickDemo::canny_Demo(Mat& image) {
	Mat gau_dst, gray_dst, grad_dst;

	GaussianBlur(image, gau_dst, Size(3, 3), 10);
	cvtColor(gau_dst, gray_dst, COLOR_BGR2GRAY);

	Canny(gray_dst, grad_dst, 50.0, 100.0, 3, false);
	imshow("grad_dst", grad_dst);
}

在这里插入图片描述

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

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

相关文章

深入理解线程池

一、线程池 1.1、线程池的优势 降低资源消耗。 通过重复利用已创建的线程降低线程创建和销毁造成的损耗 提高响应速度 当任务到达时&#xff0c;任务可以不需要等到线程创建就能立即执行 提高线程的可管理性 线程是稀缺资源&#xff0c;如果无限制的创建&#xff0c;不仅…

【雕爷学编程】Arduino动手做(82)---Mini MP3 Player播放器模块2

37款传感器与模块的提法&#xff0c;在网络上广泛流传&#xff0c;其实Arduino能够兼容的传感器模块肯定是不止37种的。鉴于本人手头积累了一些传感器和执行器模块&#xff0c;依照实践出真知&#xff08;一定要动手做&#xff09;的理念&#xff0c;以学习和交流为目的&#x…

Keepalived热备、Keepalived+LVS、HAProxy监控及后端服务器健康检查、负载均衡调度器对比

day02 day02KeepAlived高可用集群配置高可用的web集群监控本机80端口&#xff0c;实现主备切换实现原理实施配置高可用、负载均衡的web集群配置高可用、负载均衡HAProxy配置haproxy负载均衡调度器比较LVS&#xff08;Linux Virtual Server&#xff09;NginxHAProxy KeepAlive…

C++将字符或程序运行的记录保存进txt

#include <iostream>#include <fstream>int main() {std::string path_ini "D:\\ookkk\\";std::ofstream os; //创建一个文件输出流对象os.open("log.txt");//将对象与文件关联std::cout << "helo" << std::endl;s…

Java数据列表分页查询算法

一个程序员一生中可能会邂逅各种各样的算法&#xff0c;但总有那么几种&#xff0c;是作为一个程序员一定会遇见且大概率需要掌握的算法。今天就来聊聊这些十分重要的“必抓&#xff01;”算法吧~其中数据库查询分页算法是每个后端开发者必备的算法技能。 一、前言 昨天复用了…

前端(十)——深入剖析 Vuex:Vue.js 应用的状态管理神器

&#x1f642;博主&#xff1a;小猫娃来啦 &#x1f642;文章核心&#xff1a;深入研究vuex中的各种细节 文章目录 什么是vuexvuex的工作原理使用 Vuex 可以带来以下好处&#xff1a;集中式 vuex中的状态&#xff0c;它存储在哪里&#xff1f;如何改变&#xff1f;Vuex 和 Red…

成为“AI+的UGC社交平台”,亚马逊云科技助力博宇盖乐向“3D UGC社交门户”迈进

随着元宇宙浪潮逐渐升温&#xff0c;以玩家为主导的UGC游戏平台获得空前关注。多元化的视觉呈现方式&#xff0c;人人可参与、交互的玩法生态&#xff0c;具有UGC属性的游戏平台在极大提升玩家参与度、增加游戏趣味性的同时&#xff0c;也为游戏行业的内容创作带来了新的想象空…

SkyWalking链路追踪中Trace概念以及Trace与span的关系

基本概念 在SkyWalking链路追踪中&#xff0c;Trace&#xff08;追踪&#xff09;是指一个请求或者一个操作从开始到结束的完整路径。它涵盖了分布式系统中所有相关组件的调用关系和性能信息。 具体来说&#xff0c;Trace包含了一系列的span&#xff08;跨度&#xff09;&…

Godot 4 着色器 - Shader调试

我之前用OpenCV进行图像相关处理&#xff0c;觉得已经很不错&#xff0c;结合GDI可以实现流畅的动画效果 直到近来用Shader后才发现&#xff0c;着色器更上一层楼&#xff0c;原来这是入了GPU的坑 Shader编程限制很多&#xff0c;各种不支持&#xff0c;看在它性能不错功能炫…

曲线长度预测神经网络设计与实现

在本文中&#xff0c;我们使用深度神经网络 (DNN) 解决几何中的一个基本问题&#xff1a;曲线长度的计算。 我们从监督学习方法的示例中学习了几何属性。 由于最简单的几何对象是曲线&#xff0c;因此我们重点学习平面曲线的长度。 为此&#xff0c;重建了基本长度公理并建立了…

Nacos搭建和使用保姆级教程

Nacos是集配置中心&#xff0c;注册中心功能于一体的Spring Cloud必备中间件&#xff0c;好用又省钱&#xff0c;简直绝了。 首先&#xff0c;配置中心&#xff0c;可选的方案有Apollo&#xff0c;但是得另外部署。 其次&#xff0c;注册中心&#xff0c;可选的方案有Eureka,…

【Java】JVM运行流程以及垃圾回收处理

目录 1.JVM简介 2.JVM 和《Java虚拟机规范》 3.JVM运行流程 1.类加载器 1.一个类的生命周期 2.双亲委派模型 2.JVM运行时数据区 1.方法区&#xff08;线程共享&#xff09; JDK 1.8 元空间的变化 运行时常量池 2.堆&#xff08;线程共享&#xff09; 2.1演示OOM异常…

王道考研数据结构--5.顺序栈

前言 日期&#xff1a;2023.7.25 书籍&#xff1a;2024年数据结构考研复习指导&#xff08;王道考研系列&#xff09; 内容&#xff1a;实现顺序栈的基本实现&#xff0c;主要功能如下&#xff1a; ❶ 栈的数据结构 ❷ 出栈 ❸ 入栈 ❹ 判栈空 ❺ 读栈顶 1.顺序栈的定义 //1.顺…

AP5216 DC-DC降恒流驱动IC LED电动摩托汽车 转向灯刹车灯雾灯驱动

产品描述 AP5216 是一款 PWM工作模式, 高效率、外围简单、内置功率管&#xff0c;适用于5V&#xff5e;100V输入的高精度降压 LED 恒流驱动芯片。输出最大功率可达9W&#xff0c;最大电流 1.0A。AP5216 可实现全亮/半亮功能切换&#xff0c;通过MODE 切换&#xff1a;全亮/半亮…

`MySQL`压缩包中的目录结构

MySQL压缩包中的目录结构如下&#xff1a; docs:存放文档和说明文件。include:存放头文件&#xff0c;用于在源代码中包含其他文件或库的函数、变量声明等。lib:存放库文件&#xff0c;包括MySQL客户端库和其他依赖库。bin:存放可执行文件&#xff0c;如MySQL服务器、客户端工…

jQuery入门到实战

jQuery入门到实战 &#x1f607;博主简介&#xff1a;我是一名正在攻读研究生学位的人工智能专业学生&#xff0c;我可以为计算机、人工智能相关本科生和研究生提供排忧解惑的服务。如果您有任何问题或困惑&#xff0c;欢迎随时来交流哦&#xff01;&#x1f604; ✨座右铭&…

iOS transform rotate总结

研究了一下transform的旋转设置&#xff0c;调了半天还以为是旋转写错了&#xff0c;发现是两个不同的view对象写错了&#xff0c;不管怎么说&#xff0c;还是记录一下旋转相关的操作吧。 参数都是弧度。 以一个图片来举例。 let img UIImageView.init() img.image UIImage…

计算机科学cs/电子信息ei面试准备——数学基础/线性代数复习

1. 中值定理 中值定理是反映函数与导数之间联系的重要定理&#xff0c;也是微积分学的理论基础&#xff0c;在许多方面它都有重要的作用&#xff0c;在进行一些公式推导与定理证明中都有很多应用。中值定理是由众多定理共同构建的&#xff0c;其中拉格朗日中值定理是核心&…

未来行星探索希望:新型多脚机器人-团队版

机器人正在探索一个模拟的外星环境 即使一个机器人失败了&#xff0c;其余的团队成员也可以抵消它的损失。 背景 虽然探测器取得了令人难以置信的发现&#xff0c;但它们的轮子可能会拖慢它们的速度&#xff0c;而不稳定的地形可能会导致损坏。虽然没有东西可以取代“毅力号”…

使用Jenkinsfile实现接口自动化测试持续集成

这里写目录标题 一、Jenkins Pipeline1、什么是流水线类型&#xff1f;2、流水线几个步骤: 二、用Jenkinsfile的方式去执行代码1、将jenkinsfile推送到远程仓库2、配置流水线 三、Jenkinsfile中post的使用1、背景和目的2、jenkinsfile文件编写3、构建job4、发送钉钉5、发送邮件…