ISP图像信号处理——白平衡校正和标定介绍以及C++实现

news2024/10/5 19:20:23

从数码相机直接输出的未经过处理过的RAW图到平常看到的JEPG图有一系列复杂的图像信号处理过程,称作ISP(Image Signal Processing)。这个过程会经过图像处理和压缩

参考文章1:http://t.csdn.cn/LvHH5

参考文章2:http://t.csdn.cn/c97t5

参考文章3:http://t.csdn.cn/UbAOu

http://t.csdn.cn/HuI67参考文章4:http://t.csdn.cn/HuI67

参考文章(下面整理的笔记):Understanding White Balance Control - 知乎 (zhihu.com)

人眼具有颜色恒常性,可以避免光源变化带来的颜色变化,但是图像传感器不具备这种特性,从而造成色偏,白平衡就是需要校正这个颜色的偏差。

颜色恒常性是指在照度发生变化的条件下人们对物体表面颜色的知觉趋于稳定的心理倾向。

色温描述的是具有一定表面温度的“黑体”(blackbody)的辐射光的光谱特性。简单的理解就是颜色随温度的变化规律,比如生铁就是黑色,加热会变成橘红色,继续加热到液态会呈现偏白的颜色,这种随温度而产生的颜色变化就光谱特性。

白平衡校正

  • 手动白平衡:在拍照前通过拍摄一个18度灰的卡片,然后计算出当时环境的白平衡增益值对后面的图片进行校正;

  • 自动白平衡:相机通过本身的算法,通过获取的图像自动计算出增益值对图像进行校正的方式。

AWB(Automatic White Balance),自动白平衡理解

为了将拍摄场景中的白色物体在显示时正确还原为白色,首先需要知道真实的白色物体在sensor RGB 空间中呈现什么颜色。常用的方法是通过实验标定标准白色在一些典型色温下呈现的sensor RGB 颜色,然后通过几个标定的色温点可以外推白色在所有可能色温下呈现的颜色,从而建立场景色温与sensor RGB 白色的对应关系,这个对应关系通常用白平衡增益来描述。

白平衡增益通常记为(R/G, B/G),即红色和蓝色相对于绿色的比例。目前对白平衡增益存在两种不同的定义:

1.一部分厂家将(R/G, B/G)定义为sensor捕捉到的图像中红色和蓝色的统计值,因此在高色温(如D65)下B/G大于R/G。

海思的光源的色温曲线(普朗克曲线)表现为下图所示的形状。

通过对不同sensor的色温曲线标定数据可知:在D50-D65之间 R/G、B/G的比值基本相近,相差不大。在低色温的时候,主要是G和B分量在改变,在高色温的时候主要是G和B分量在改变。

以海思的色温曲线为例:从直角双曲线的两个坐标方向来看,在D50-D65这个R/G、B/G为分界点,沿着R/G的方向看,最后应该会有一个B/G的饱和点。同理,沿B/G方向看,R/G也会有一个饱和点,饱和区域的时候其两个坐标方向上看应该呈现一条类似接近直线的曲线段。

或者也可以这么理解:

色温越低,R/G的比值越大,B/G的比值越小,当R/G达到某一阈值后,B/G则缓慢变小直至达到一个最小值而不再改变。

同理,色温越高,B/G的比值越大,R/G的比值越小,当B/G达到某一阈值后,R/G则缓慢变小直至达到一个最小值而不再改变。

直角双曲线靠近坐标的部分与坐标轴近似平行的直线段,比较符合色温曲线的变化规律。

根据G/R和G/B用直角双曲线函数拟合的图像和海思的普朗克曲线十分相似,如下图所示。

在这种定义下,D65光源下的白色具有较大的B/G统计值。

2.另一部分厂家则将(R/G, B/G)定义成为了使sensor捕捉的图像达到白平衡需要施加的增益系数,因此在高色温下B/G小于R/G。

在这种定义下,D65光源下的白色需要较大的R/G增益才能达到白平衡。

以R/G,B/G值代表增益系数,而非图像的统计值,在此定义下,白平衡标定的大致过程是:

  • 以标定好的若干个色温点(A, TL84, D50, D65, D75等)为核心可以拟合出一条色温曲线
  • 以色温曲线上的点为圆心,以一定半径画椭圆,可以得到一些列椭圆。
  • 所有椭圆所覆盖的(R/G,B/G)集合就认为是真实场景中的白色物体在全部色温下的可能值。不落在这个范围内的颜色不认为是白色。

某些特殊光源(如CWF)光谱特征偏离黑体光谱较大,因此需要单独标定。

一个好的白平衡算法需要能够检测出画面中存在的特殊场景并加以针对性的强化。点云分析是一种非常有效的提取图像特征的方法,但由于需要分析每一个像素的白平衡增益,所以计算量非常大。

理想的白平衡控制时序如下图所示,其基本流程是:

  1. 在第N帧图像结束时ISP硬件采集关于白平衡的统计信息
  2. 白平衡算法根据第N帧的统计数据预测第N+1帧的控制参数
  3. 摄像机固件在第N+1帧图像到达之前将白平衡控制参数写入ISP硬件寄存器
  4. 第N+1帧图像使用新的白平衡参数进行曝光

但是实际上由于两帧的时间间隔往往很小,不容易保证算法完成一系列的计算和配置,因此实际的白平衡控制往往采用隔帧生效的时序,其基本流程如下图所示

  1. 在第N帧图像结束时ISP硬件采集关于白平衡的统计信息
  2. 在第N+1帧开始后,白平衡算法根据第N帧的统计数据预测第N+2帧的控制参数,需要在第N+1帧结束前完成所有计算
  3. 摄像机固件在第N+2帧图像到达之前将新的白平衡控制参数写入ISP硬件寄存器
  4. 第N+2帧图像使用新的白平衡参数进行曝光

白平衡校正算法

1.灰度世界算法

基于一个假说:任一幅图像,当它有足够多的色彩变化,则它的RGB分量的均值会趋于相等。这是一个在自动白平衡方面应用极为广泛的理论。对此算法的流程如下:

  • 计算各个颜色通道的平均值;
  • 寻找一个参考值K,一般情况选取Gmean;
  • 计算Rgain = Gmean/Rmean, Bgain = Gmean/Bmean;
  • 对图像中的每个像素都乘以对应的gain值进行校正;
  • 以下C++代码,不知道本人缺少什么运行条件,在自己电脑上最后显示结果不太理想;大家也可以试试,该代码出自:http://t.csdn.cn/edydD
//自动白平衡  //灰度世界算法
void GrayWorldAlgorithm(Mat& src,Mat& dst)
{
    assert(3==src.channels());

    //求BGR分量均值
    auto mean = mean(src);

    //需要调整的BGR分量的增益
    float gain_B(0),gain_G(0),gain_R(0);
    float K = (mean[0]+mean[1]+mean[2])/3.0f;
    gain_B = K/mean[0];
    gain_G = K/mean[1];
    gain_R = K/mean[2];

    vector<Mat> channels;
    split(src,channels);

    //调整三个通道各自的值
    channels[0] = channels[0]*gain_B;
    channels[1] = channels[1]*gain_G;
    channels[2] = channels[2]*gain_R;

    //通道合并
    cv::merge(channels,dst);
}

下面的灰度世界法是本人自己根据理解写的,但是显示结果存疑。有点怀疑是不是BGR的赋值跟输入图像的拜尔分布有关,赋值顺序有误?有能力者找到错误的可以帮我纠出(感谢感谢):

//灰度世界法,输入三通道彩色图
Mat awbgray(Mat img_rgb8)
{
	Mat img_awb = Mat::zeros(height, width, CV_32FC3);
	Mat imgR = Mat::zeros(height, width, CV_8UC1);
	Mat imgG = Mat::zeros(height, width, CV_8UC1);
	Mat imgB = Mat::zeros(height, width, CV_8UC1);

	double Rsum=0, Gsum=0,Bsum=0;
	/*unsigned char* srcdata;
	unsigned char *dstdata;*/
	for (int row = 0; row < height; row++)
	{
		//ptr得到行数据的头指针,得到row行指针
		/*uchar* data = img_awb.ptr<uchar>(row);*/
		Vec3b* inptr = img_rgb8.ptr<Vec3b>(row);
		for (int col = 0; col < width; col++)
		{
			//BGGR分布?
			//imgB.at<Vec3b>(row, col)[0]   b通道
			/*uchar bdata = data[col * img_awb.channels() + 0];*/
			imgB.at<uchar>(row, col) = (*(inptr + col))[0];
			imgG.at<uchar>(row, col) = (*(inptr + col))[1];
			imgR.at<uchar>(row, col) = (*(inptr + col))[2];
			
			Bsum += imgB.at<uchar>(row, col);
			Gsum += imgG.at<uchar>(row, col);
			Rsum += imgR.at<uchar>(row, col);
		}
	}
	double Rmean=0, Gmean=0, Bmean = 0;
	Rmean = Rsum / (height * width);
	Gmean = Gsum / (height * width);
	Bmean = Bsum / (height * width);
	double K = (Rmean + Gmean + Bmean) / 3;
	cout << "Rmeanvalue:" << Rmean << endl;
	cout << "Gmeanvalue:" << Gmean << endl;
	cout << "Bmeanvalue:" << Bmean << endl;
	cout << "rgbmeanvalue:" << K << endl;
	double Rgain = K / Rmean;
	double Ggain = K / Gmean;
	double Bgain = K / Bmean;

	//重新调整计算RGB值
	for (int row = 0; row < height; row++)
	{
		Vec3b* inptr = img_rgb8.ptr<Vec3b>(row);
		Vec3f* outptr = img_awb.ptr<Vec3f>(row);
		for (int col = 0; col < width; col++)
		{
			(*(outptr + col))[2] = Rgain * (*(inptr + col))[2];
			(*(outptr + col))[1] = Ggain * (*(inptr + col))[1];
			(*(outptr + col))[0] = Bgain * (*(inptr + col))[0];
		}
	}
	//convertScaleAbs(img_awb, img_awb);//转为CV_8UC1
	/*imshow("img_awb", img_awb);
	waitKey(0);*/
	return img_awb;
}

该方法运行得到的结果,通过图像监视观察函数中的图像变化,放大可以查看像素值,没有在VS安装的可以自行安装Imagewatch,安装教程:VS2022安装Image Watch插件_image watch for visual studio 2022_Aqder的博客-CSDN博客

感觉处理后的结果不太理想,不知道是不是代码有误,可指出。

(左为输入,右为输出,不是一一对应的截图):

2.完美反射法

(perfect Reflector)基于这样一种假设,一幅图像中最亮的像素相当于物体有光泽或镜面上的点,它传达了很多关于场景照明条件的信息。如果景物中有纯白的部分,那么就可以直接从这些像素中提取出光源信息。因为镜面或有光泽的平面本身不吸收光线,所以其反射的颜色即为光源的真实颜色,这是因为镜面或有光泽的平面的反射比函数在很长的一段波长范围内是保持不变的。那么在这个假设下,图像中就一定存在一个纯白色的的像素或者最亮的点。

完美反射法就是利用这种特性来对图像进行调整。算法执行时,将待检测图像中亮度最高的像素作为参考白点,以此点为基础就可计算出gain值从而进行校正。完美反射算法流程如下:
  (1)遍历原始图像,统计RGB三通道之和的直方图;
  (2)遍历原始图像,找到RGB三通道各自的最大值Bmax、Gmax、Rmax
  (3)设定比例 r ,对RGB之和的直方图进行倒叙遍历,找到使白点像素个数超过总像素个数比例的阈值,T;
  (4)遍历原始图像,计算RGB之和大于 T 的像素,各个通道取平均,得到Bavg、Gavg、Ravg;
  (5)遍历原始图像,分别计算RGB三通道的调整值Aout=A / Aavg * Amax;
  (6)防溢出处理,这里可以采用简单的截断即可。

有看到其他博文资料不使用比例和阈值的完美反射法,但是运行结果和上面一样存疑。

设定比例r为10%,使用C++,代码如下:

​
//白平衡校正,完美反射法,使用比例r和阈值T,
Mat awbreflect2(Mat img_rgb8)
{
	int histrgbsum[255 * 3 + 1] = { 0 };
	double Rmax = 0, Gmax = 0, Bmax = 0;
	//uchar maxrgb[3] = { 0 };
	for (int row = 0; row < height; row++)
	{
		const uchar* inptr = img_rgb8.ptr<uchar>(row);
		for (int col = 0; col < width; col++)
		{
			//统计RGB三通道之和的直方图
			int sum = *(inptr + 3 * col) + *(inptr + 3 * col + 1) + *(inptr + 3 * col + 2);
			histrgbsum[sum]++;
			//找到RGB三通道各自的最大值Bmax、Gmax、Rmax
			Bmax = max(Bmax, (double)*(inptr + 3 * col));
			Gmax = max(Gmax, (double)*(inptr + 3 * col + 1));
			Rmax = max(Rmax, (double)*(inptr + 3 * col + 2));
			/*maxrgb[0] = max(maxrgb[0], *(inptr + 3 * col));
			maxrgb[1] = max(maxrgb[1], *(inptr + 3 * col+1));
			maxrgb[2] = max(maxrgb[2], *(inptr + 3 * col+2));*/
		}
	}

	//设定比例r为10%
	double num = 0,ratio=0.1;
	int threshold = 0;
	int len = 0;
	len=sizeof(histrgbsum) / sizeof(histrgbsum[0]);
	//int len = end(histrgbsum) - begin(histrgbsum);
	cout << "histagram length:" << len << endl;
	for (len; len >= 0; len--)
	{
		num += histrgbsum[len];
		//计算R+G+B的数量超过像素总数的ratio的像素值
		if (num > height * width * ratio)
		{
			//使白点像素个数超过总像素个数的比例时,为阈值T
			threshold = len;
			break;
		}
	}

	//计算RGB之和大于 T 的像素,对大于阈值的像素各通道取平均,得到Bavg、Gavg、Ravg;
	double Rsum = 0, Gsum = 0, Bsum = 0;
	double Ravg = 0, Gavg = 0, Bavg = 0;
	int pixnum = 0;
	for (int row = 0; row < height; row++)
	{
		const uchar* inptr = img_rgb8.ptr<uchar>(row);
		for (int col = 0; col < width; col++)
		{
			//计算RGB之和,上面的局部变量又用一遍
			int sum = *(inptr + 3 * col) + *(inptr + 3 * col + 1) + *(inptr + 3 * col + 2);
			if (sum > threshold)
			{
				Bsum += *(inptr + 3 * col);
				Gsum += *(inptr + 3 * col + 1);
				Rsum += *(inptr + 3 * col + 2);
				pixnum++;
			}
		}
	}
	Ravg = Rsum / (double)pixnum;
	Gavg = Gsum / (double)pixnum;
	Bavg = Bsum / (double)pixnum;
	//创建与输入图像一样大小类型的矩阵
	Mat img_awb = Mat::zeros(img_rgb8.size(), img_rgb8.type());
	//量化0-255,重新计算RGB值,分别计算RGB三通道的调整值Aout=A / Aavg * Amax
	double Rout = 0, Gout = 0, Bout = 0;
	for (int row = 0; row < height; row++)
	{
		const uchar* inptr = img_rgb8.ptr<uchar>(row);
		uchar* outptr = img_awb.ptr<uchar>(row);
		for (int col = 0; col < width; col++)
		{
			Bout = (double)*(inptr + 3 * col) / Bavg * Bmax;
			Gout = (double)*(inptr + 3 * col+1) / Gavg * Gmax;
			Rout = (double)*(inptr + 3 * col+2) / Ravg * Rmax;
			Bout = min(max((double)0, Bout), (double)255);
			Gout = min(max((double)0, Gout), (double)255);
			Rout = min(max((double)0, Rout), (double)255);
			//将计算好的RGB值赋给新矩阵
			*(outptr + 3 * col) = (uchar)Bout;
			*(outptr + 3 * col+1) = (uchar)Gout;
			*(outptr + 3 * col+2) = (uchar)Rout;
		}
	}
	return img_awb;

}

​

断点运行之后,图像监视下白平衡处理后得到的结果(左输入,右输出,不是一一对应的截图):

3.动态阈值法

YUV颜色空间(亦称YCrCb)主要用于优化彩色视频信号的传输,Y表示亮度,U和V表示色度(色调和饱和度)。亮度是通过RGB输入信号来建立的,方法是将RGB信号的特定部分叠加到一起。“色度”则定义了颜色的两个方面─色调与饱和度,分别用Cr和Cb来表示。其中,Cr反映了RGB输入信号红色部分与RGB信号亮度值之间的差异。而Cb反映的是RGB输入信号蓝色部分与RGB信号亮度值之同的差异。

动态阈值算法通过将RGB变化到YCrCb颜色空间进行分析来确定白点,其选择参考白点的阈值是动态变化的。我们通过对图片的YCrCb坐标空间的分析,可以找到一个接近白色的区域,该区域是包含着参考白点的,通过设定一个阈值来规定某些点为参考白点。因此该算法是一个动态的自适应白平衡算法。

白平衡算法通常分为两步:白色点的检测,白色点的调整。本方法采用一个动态的阀值来检测白色点。详细算法过程参考如下:

  1. 把图像w*h从RGB空间转换到YCrCb空间。转换公式如下:

  2. 通过限定YUV的区域来判断是否为白点,通过四个限制条件俩限制白点,满足条件的点就是白点,参与后续的计算,否则,点直接舍弃。                                                                       (1)首先,为了增强算法的鲁棒性,将图像分为12部分,把图像分成宽高比为4:3个块(块数可选)。                                                                                                                                       (2)然后对每个块,分别计算Cr,Cb的平均值Mr,Mb。                                   (3)再对每个块,根据Mr,Mb,用下面公式分别计算Cr,Cb的方差Dr,Db。(4)最后 判定每个块的近白区域(near-white region)。判别准则为:其中sign为符号函数,即正数返回1,负数返回0。

  3. 设一个“参考白色点”的亮度矩阵RL,大小为w*h。
         若符合判别式,则作为“参考白色点”,并把该点(i,j)的亮度(Y分量)值赋给RL(i,j);

         若不符合,则该点的RL(i,j)值为0。

  4. 上面几步为白点检测,下面几步为白点调整:

(1)选取参考“参考白色点”中最大的10%的亮度(Y分量)值,并选取其中的最小值Lu_min;

(2)调整RL,若RL(i,j)<Lu_min, RL(i,j)=0; 否则,RL(i,j)=1;

(3)分别把R,G,B与RL相乘,得到R2,G2,B2。 分别计算R2,G2,B2的平均值,得到Rav,Gav,Bav;

(4)得到调整增益: Ymax=double(max(max(Y));

Rgain=Ymax/Rav;

Ggain=Ymax/Gav;

Bgain=Ymax/Bav;

(5)调整原图像:Ro= R*Rgain; Go= G*Ggain; Bo= B*Bgain。

实现代码本人未尝试,C++可以参考(过程较为复杂):

OpenCV图像处理专栏十一 | IEEE Xplore 2015的图像白平衡处理之动态阈值法 (qq.com)

4.其他算法

除了上面比较常见的几种,还有基于模糊逻辑,基于色温,基于边缘和多方法融合法等等。

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

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

相关文章

打造综合性品牌阵地 阿里元境引领元宇宙营销创新升级

9月21日&#xff0c;由中国商务广告协会主办&#xff0c;中国商务广告协会元宇宙营销应用研究工作委员会、南京大学中德社会计算研究所、南京大学中德数字营销实验室联合主办的“聚力共生”元宇宙学术及商业应用论坛启幕。阿里元境副总经理、市场负责人史敏君出席了论坛“多元聚…

SSE 推送技术

1、简介 Server-Sent Events&#xff08;SSE&#xff09;技术&#xff0c;它是一种用于实现服务器向客户端实时单向推送数据的Web技术。 SSE基于HTTP协议&#xff0c;允许服务器将数据以事件流&#xff08;Event Stream&#xff09;的形式发送给客户端。客户端通过建立持久的HT…

一些数学公式的几何意义

三角函数平方和公式&#xff1a; 三角函数中的平方和公式有三个形式&#xff1a; 第一种&#xff1a;&#xff1b; 接着两边同时除以可以得到第二种&#xff1a;; 或第一种同时除以可以得到第三种&#xff1a;。 首先我们做一个单位圆&#xff0c;我们学三角函数的时候应该…

当两界交汇:前端开发、后端开发与全栈开发的对比与选择

编程世界就像一座大城市&#xff0c;前端开发和后端开发就像城市的两个不同街区。在这两个街区&#xff0c;前端和后端开发都有自己的价值和机会。 一、引言 有些人更喜欢在前端创造令人印象深刻的用户界面&#xff0c;而有些人更喜欢处理数据和系统逻辑。在选择时&#xff…

Topaz Gigapixel AI6.3.2(图片无损放大)

Topaz Gigapixel AI是一款功能实用的图像无损放大工具。它的特色之处在于&#xff0c;通过使用先进的深度学习方法&#xff0c;它能够将照片放大高达600%&#xff0c;同时完美保留图像的质量。 此外&#xff0c;Topaz Gigapixel AI还具有一些其他的特色功能。 它能自动进行面…

ABB DDC779BE02 3BHE006805R0002 控制主板模块

ABB DDC779BE02 3BHE006805R0002 控制主板模块用于自动化和控制系统中&#xff0c;它们可能具有以下一些常见特点和功能&#xff1a; 处理能力&#xff1a;ABB DDC779BE02 3BHE006805R0002 控制主板模块通常具有强大的处理能力&#xff0c;可以执行复杂的控制算法和逻辑。 多种…

软件测试之网站测试怎么做?有什么作用?

网站测试是指对一个已经搭建好的网站进行功能、性能、安全等方面的测试。作为一家专注于软件测试的公司&#xff0c;我们清楚地知道网站测试在整个软件开发过程中的重要性。   一、网站测试怎么做?   1、确保测试环境的稳定和一致性&#xff0c;包括操作系统、浏览器版本等…

AnV-X6使用及总结

目录 1 简介2 安装3 基础概念3.1 画布Graph3.2 基类Cell3.3 节点Node3.4 边Edge 4 使用4.1 创建节点4.2 节点连线4.3 事件系统 5 总结 1 简介 AntV是一个数据可视化&#xff08;https://x6.antv.antgroup.com/&#xff09;的工具&#xff08;https://antv.vision/zh/ &#xf…

IPv6的主要优势有哪些?

第一&#xff0c;明显地扩大了地址空间。IPv6采用128位地址长度&#xff0c;几乎可以不受限制地提供IP地址&#xff0c;从而确保了端到端连接的可能性。 第二&#xff0c;提高了网络的整体吞吐量。由于IPv6的数据包可以远远超过64k字节&#xff0c;应用程序可以利用最大传输单元…

RFID技术引领汽车零部件加工新时代

RFID技术的兴起引领了汽车零部件加工领域的新时代&#xff0c;作为一种利用无线电频率进行自动识别的技术&#xff0c;RFID技术能够快速、准确地识别物体并获取相关数据&#xff0c;在汽车零部件加工中&#xff0c;RFID技术具有重要的应用价值&#xff0c;可以提高生产效率、降…

idea环境下如何打包可运行jar?

工作中有时候偶尔写一些工具类、小程序&#xff0c;可是java程序员制作一个可运行jar实在折腾&#xff0c;利用idea开发环境&#xff0c;可以快速打包自己的可运行jar。具体怎么操作呢&#xff1f; 创建一个空白的java项目并完成自己的程序开发 完成java代码&#xff1a; /**…

Vue以及整合ElementUI

初始化vue项目 #vue 脚手架使用 webpack 模板初始化一个 appname 项目 vue init webpack appname启动 vue 项目 #项目的 package.json 中有 scripts&#xff0c;代表我们能运行的命令 npm start npm run dev #启动项目 npm run build&#xff1a;将项目打包项目结构 运行流程…

【AI视野·今日Robot 机器人论文速览 第四十二期】Wed, 27 Sep 2023

AI视野今日CS.Robotics 机器人学论文速览 Wed, 27 Sep 2023 Totally 48 papers &#x1f449;上期速览✈更多精彩请移步主页 Interesting: &#x1f4da;***Tactile Estimation of Extrinsic Contact,基于触觉的外部接触估计与稳定放置 (from 三菱电机) Daily Robotics Pape…

这才是连锁商店的必杀技,你的太Low了!

随着社会的不断发展和技术的进步&#xff0c;视频监控系统在各个领域的应用变得越来越广泛。无论是商业、政府、教育还是个人领域&#xff0c;视频监控系统都扮演着重要的角色。 此外&#xff0c;视频监控系统不仅提供了安全性和保护&#xff0c;还为各种管理和监测任务提供了强…

华为云云耀云服务器L实例评测 | 实例评测使用之硬件参数评测:华为云云耀云服务器下的硬件参数查询

华为云云耀云服务器L实例评测 &#xff5c; 实例评测使用之硬件参数评测&#xff1a;华为云云耀云服务器下的硬件参数查询 介绍华为云云耀云服务器 华为云云耀云服务器 &#xff08;目前已经全新升级为 华为云云耀云服务器L实例&#xff09; 华为云云耀云服务器是什么华为云云耀…

网络安全(黑客技术)自学内容

前言 一、什么是网络安全 网络安全可以基于攻击和防御视角来分类&#xff0c;我们经常听到的 “红队”、“渗透测试” 等就是研究攻击技术&#xff0c;而“蓝队”、“安全运营”、“安全运维”则研究防御技术。 无论网络、Web、移动、桌面、云等哪个领域&#xff0c;都有攻与防…

MySQL - DML数据增删改

功能介绍&#xff1a; DML&#xff08;Data Manipulation Language&#xff09;数据操作语言&#xff0c;用来对数据库中表的数据记录进 行增、删、改操作。 添加数据&#xff08;INSERT&#xff09; 基本语法&#xff1a;insert into 表名(字段列表) values (值列表); …

数据分发服务(DDS, Data Distribution Service)简介

什么是DDS &#xff1f; 工业物联网成熟的数据连接标准 OMG 数据分发服务 (DDS™) 是一个中间件协议和 API 标准&#xff0c;用于来自 Object Management Group (OMG) 的以数据为中心的连接。它将系统的组件集成在一起&#xff0c;提供业务和关键任务物联网 (IoT) 应用程序所…

一招教你控制python多线程的线程数量

大家早好、午好、晚好吖 ❤ ~欢迎光临本文章 如果有什么疑惑/资料需要的可以点击文章末尾名片领取源码 在使用python的多线程爬虫&#xff0c;当时爬取一个图片网站&#xff0c;开启多线程后&#xff0c;并没有限制线程的数量&#xff0c; 也就是说&#xff0c;如果下载1000张…

SAP PO运维(五):系统用户授权

1、访问 SAP PO 服务器和用户管理 访问服务器:http://hostname:port/startPage然后选择“用户管理” 2、创建新用户账号 3、授予权限