C++OpenCV(2):图像处理基础概念与操作

news2024/10/7 4:23:00

🔆 文章首发于我的个人博客:欢迎大佬们来逛逛
🔆 OpenCV项目地址及源代码:点击这里

文章目录

  • 图形读取与显示
    • 加载图片
    • 显示图片
    • 打印图片信息
    • 保存图片
  • 色彩模型转换
    • RGB颜色模型
    • HSV颜色模型
    • HLS模型
    • LAB模型
  • 图像像素读写操作
  • 像素算数运算
  • 图形文字绘制
    • 绘制线
    • 绘制圆
    • 绘制矩形
    • 绘制椭圆
    • 绘制文字
    • 其他绘制函数

图形读取与显示

通过 imread 我们可以读取一个图片

其形式如下:

void imshow(const String& winname, InputArray mat);

而我们需要传递一个InputArray类型的参数,实际上就是 cv::Mat

如果创建cv::Mat呢?

可以通过它的很多的构造函数

先来了解一下图片的颜色通道

  • 颜色通道
    • RGB 图像有4 个默认通道:红色、绿色和蓝色各有一个通道,以及一个用于编辑图像复合通道(主通道)
  • 彩色深度
    • 8位色,每个像素所能显示的彩色数为2的8次方,即256种颜色。
    • 16位增强色,16位彩色,每个像素所能显示的彩色数为2的16次方,即65536种颜色。
    • 24位真彩色,每个像素所能显示的彩色数为24位,即2的24次方,约1680万种颜色。
    • 32位真彩色,即在24位真彩色图像的基础上再增加一个表示图像透明度信息的Alpha通道。
      • Alpha通道:一张图片的透明和半透明度

我们使用如下的形式来描述它的通道类型:

CV_<bit_depth>(S|U|F)C<number_of_channels>

其中:

  • bit_depth:位数,就是我们上面讲的彩色深度
  • S|U|F:即 signed ,unsigned int,float 来存储
  • number_of_channels:通道,有单通道,双通道,三通道,和四通道等等

加载图片

Mat类型的结构如下:

class  Mat
{
 
public/*
 		flag: 
 		1.数字签名 
 		2.维度
 		3.通道数
 		4.连续性
 	*/
	int flags;					
	int dims; 					//数据维数
	int rows,cols; 				//数据行列
	uchar *data;				//存储的数据		
    const uchar* datastart;		//数据开始
    const uchar* dataend;		//数据结束
    const uchar* datalimit;		//数据边界
	//其他成员  
 	//.....
 	//其他方法
 	//.....
 public: 		//构造方式
    // 默认构造函数 Mat A;
    Mat ()
    // 常用构造函数 Mat A(10,10,CV_8UC3);
    Mat (int rows, int cols, int type)
    //Mat A(300, 400, CV_8UC3,Scalar(255,255,255));
    Mat (int ndims, const int *sizes, int type, const Scalar &s)
    Mat (Size size, int type)
    Mat (int rows, int cols, int type, const Scalar &s)
    Mat (Size size, int type, const Scalar &s)
    Mat (int ndims, const int *sizes, int type)
    Mat (const Mat &m)
    Mat (int rows, int cols, int type, void *data, size_t step=AUTO_STEP)
    Mat (Size size, int type, void *data, size_t step=AUTO_STEP)
    Mat (int ndims, const int *sizes, int type, void *data, const size_t *steps=0)
    Mat (const Mat &m, const Range &rowRange, const Range &colRange=Range::all())
    //Mat D (A, Rect(10, 10, 100, 100) );
    Mat (const Mat &m, const Rect &roi)
    Mat (const Mat &m, const Range *ranges)
    
};

我们使用如下的几种方式来加载图片:

  • CV_8UC1:单通道
  • Scalar:使用BGR形式
  • clone/copyTo:从另一个Mat拷贝
void testShow() {
	cv::Mat	m1(200, 200, CV_8UC1);
	cv::imshow("1", m1);
	//std::cout << m << '\n';
	cv::Mat m2(200, 200, CV_8UC3, cv::Scalar(255, 0, 255));
	cv::imshow("2", m2);

	cv::Mat m3 = m2.clone();
	cv::imshow("3", m3);

	cv::Mat m4;
	m3.copyTo(m4);	
	cv::imshow("4", m4);

	//imread
	cv::Mat m5 = cv::imread("images/mm.png", cv::ImreadModes::IMREAD_GRAYSCALE);
	cv::imshow("5", m5);
}

显示图片

我们使用函数:imshow

我们已经直到了它的第二个参数是一个类型,用来表示以何种形式显示图片:**cv::ImreadModes**

Mat imread( const String& filename, int flags = IMREAD_COLOR );
/****************************************************************
*				filename: 文件路径
*				flags   : 显示方式
*****************************************************************/
enum ImreadModes {
       IMREAD_UNCHANGED            = -1,	//按原样返回加载的图像(带有alpha通道,否则会被裁剪)
       IMREAD_GRAYSCALE            = 0, 	//单通道灰度图像
       IMREAD_COLOR                = 1, 	//3通道BGR彩色图像 
       IMREAD_ANYDEPTH             = 2, 	//16位/32位图像,其他则转换为8位
       IMREAD_ANYCOLOR             = 4, 	//图像以任何可能的颜色格式读取
       IMREAD_LOAD_GDAL            = 8, 	//gdal驱动程序加载映像
       IMREAD_REDUCED_GRAYSCALE_2  = 16,	//单通道灰度图像,并将图像大小减小1/2 
       IMREAD_REDUCED_COLOR_2      = 17,	//3通道BGR彩色图像,使图像大小减小1/2
       IMREAD_REDUCED_GRAYSCALE_4  = 32,	//单通道灰度图像,并将图像尺寸减小1/4
       IMREAD_REDUCED_COLOR_4      = 33,	//3通道BGR彩色图像,使图像大小减小1/4
       IMREAD_REDUCED_GRAYSCALE_8  = 64,	//单通道灰度图像,并将图像尺寸减小1/8
       IMREAD_REDUCED_COLOR_8      = 65,	//3通道BGR彩色图像,使图像大小减小1/8
       IMREAD_IGNORE_ORIENTATION   = 128	//不要根据EXIF的方向标志旋转图像
};

打印图片信息

我们可以打印Mat的信息,因为它实际上就是一个矩阵,我们可以采用多种形式来格式化输出

  • C语言形式
  • numpy形式
  • python形式

….

void testPrint() {
	cv::Mat m(10, 10, CV_8UC1);
	std::cout << "Mat: \n"<<m << '\n';
	//格式化
	std::cout << "C: \n" << cv::format(m, cv::Formatter::FMT_C);
	std::cout << "numpy: \n" << cv::format(m, cv::Formatter::FMT_NUMPY);
}

保存图片

使用函数: imwrite

第一个参数为保存的图片的路径,第二个参数为保存的图片。

其中路径我们可以使用 cv::String 来传递,就是个字符串。

void testSaveFile(cv::String filename) {
	auto m = cv::imread("./images/dog.png" ,cv::ImreadModes::IMREAD_GRAYSCALE);	
	cv::imshow("dog", m);
	cv::imwrite(filename, m);
}

色彩模型转换

什么是色彩模型?

颜色模型指的是某个三维颜色空间中的一个可见光子集,它包含某个色彩域的所有色彩。一般而言,任何一个色彩域都只是可见光的子集,任何一个颜色模型都无法包含所有的可见光(通俗一点讲就是表示颜色的一种方式

RGB颜色模型

在计算机体系中,最常见的色彩模型就是**RGB颜色**模型。

它具有三维坐标的模型形式:

在这里插入图片描述


  • RGB16:每个像素用16个比特位表示,占2个字节
    • RGB565:RGB分量分别使用5位、6位、5位:

在这里插入图片描述

  • RGB555:RGB分量分别使用5位、5位、5位:

在这里插入图片描述
对于RGB555,如何获取各个5位上的值,即分别获取 R,G,B所代表的值?
通过位运算即可获取。

   /*
   RGB 颜色模型
   */
   struct XColor {
   	unsigned int color : 15;
   };
   void getRGB555() {
   	XColor col{};
   	col.color = 0b110000010111100;
   	std::cout << "R: " << (col.color >> 10) << '\n';
   	std::cout << "G: " << ((col.color & 0x3F0) >> 5) << '\n';
   	std::cout << "B: " << (col.color & 0x1F) << '\n';
   }
  • RGB24格式:每个像素用24比特位表示,占3个字节,在内存中RGB各排列顺序为:BGR:

在这里插入图片描述

  • RGB32格式:每个像素用32比特位表示,占4个字节,R,G,B分量分别用8个bit表示,存储顺序为B,G,R,最后8个字节保留

    • ARGB32:本质就是带alpha通道的RGB24,与RGB32的区别在与,保留的8个bit用来表示透明,也就是alpha的值

    在这里插入图片描述

    • 对于**RGB32**,如何获取各个8位上的值,即分别获取 R,G,B,Alpha所代表的值?

      • 通过位运算即可获取。
      void getRGB32() {
      	int color = 0x0F0A2B0C;
      	std::cout << "B: " << (color >> 24) << '\n';
      	std::cout << "G: " << ((color & 0x00FF0000) >> 16) << '\n';
      	std::cout << "R: " << ((color & 0x0000FF00) >> 8) << '\n';
      	std::cout << "Alpha: " << (color & 0x000000FF) << '\n';
      }
      

HSV颜色模型

HSV(Hue, Saturation,Value)也被称为六角锥体模型,即色调,饱和度,明度

在这里插入图片描述

将RGB转换为HSV模型:

  • **cvtColor**函数:将图像从一种颜色模型转换为另一个。
  • 起到关键作用的是第三个参数:cv::ColorConversionCodes 是一个枚举,表示了你想要从谁转换到谁,这里我们让BGR形式转换为HSV形式。
cv::Mat res;
cv::cvtColor(m1, res, cv::ColorConversionCodes::COLOR_BGR2HSV);
cv::imshow("hsv", res);

在这里插入图片描述

在这里插入图片描述


HLS模型

HLS模型分别是色调,亮度,饱和度

在这里插入图片描述

上图可以看出,固定一个颜色(H),那么随着饱和度(S,Chroma)的增加,颜色越来越深。

cv::cvtColor(m1, res, cv::ColorConversionCodes::COLOR_BGR2HLS);
cv::imshow("hls", res);

在这里插入图片描述

在这里插入图片描述


LAB模型

Lab颜色模型由三个要素组成,一个要素是**亮度**(L),a 和b是两个颜色通道。

  • **a**包括的颜色是从深绿色(低亮度值)到灰色(中亮度值)再到亮粉红色(高亮度值)
  • **b**是从亮蓝色(低亮度值)到灰色(中亮度值)再到黄色(高亮度值)。
  • 因此,这种颜色混合后将产生具有明亮效果的色彩。
    在这里插入图片描述
cv::cvtColor(m1, res, cv::ColorConversionCodes::COLOR_BGR2Lab);
cv::imshow("Lab", res);

在这里插入图片描述

在这里插入图片描述

还有很多的颜色模型都可以在 cvtColor这个函数中找到。


图像像素读写操作

openCV基本类型介绍:

  • 基本类型:
typedef unsigned uint;
typedef signed char schar;
typedef unsigned char uchar;
typedef unsigned short ushort;
  • 封装类型:Vec类似于std::vector,只不过可以指定其大小,并且命名规则为 cv:: Vec大小+ 类型
typedef Vec<uchar, 2> Vec2b;
typedef Vec<uchar, 3> Vec3b;
typedef Vec<uchar, 4> Vec4b;

typedef Vec<short, 2> Vec2s;
typedef Vec<short, 3> Vec3s;
typedef Vec<short, 4> Vec4s;

typedef Vec<ushort, 2> Vec2w;
typedef Vec<ushort, 3> Vec3w;
typedef Vec<ushort, 4> Vec4w;

typedef Vec<int, 2> Vec2i;
typedef Vec<int, 3> Vec3i;
typedef Vec<int, 4> Vec4i;
typedef Vec<int, 6> Vec6i;
typedef Vec<int, 8> Vec8i;

图像是由像素掉构成的,因此我们可以获取图像的每一个像素,这个像素是由(i,j)确定的,即在图片宽度与高度的范围下,每一个行的每一列都可以是一个像素。

我们使用 Mat 的 at 函数来获取某个位置的像素值。

注意像素具有channels的区别。

  • 如果是单通道: 则直接获取 uchar 表示一个像素(一字节)。
  • 如果是三通道: 则需要获取Vec3b 表示三个像素,可以通过[0],[1],[2]来分别操作。

以下操作对图片转换为负片,使用 255 - 当前像素值

#include <iostream>
#include <opencv2/opencv.hpp>

class ImgPixel {
public:
	ImgPixel(std::string filename):m(cv::imread(filename)){}
	void show(std::string title) {
		cv::imshow(title, m);
	}
	void Visit_By_Array() {
		auto dims = m.channels(); //获取通道数
		for (int i = 0; i < m.rows; i++) {
			for (int j = 0; j < m.cols; j++) {
				if (dims == 1) {
					//如果是一通道,则直接操作
					uchar rets = m.at<uchar>(i, j);
					rets = 255 - rets;
				}
				if (dims == 3) {
					cv::Vec3b rets = m.at<cv::Vec3b>(i, j);
#if 0
					m.at<cv::Vec3b>(i, j)[0] = 255 - rets[0]; //转换为负片
					m.at<cv::Vec3b>(i, j)[1] = 255 - rets[1];
					m.at<cv::Vec3b>(i, j)[2] = 255 - rets[2];
#else 
					//安全类型转换: 超过255的赋值为 255 小于0的赋值为 0
					m.at<cv::Vec3b>(i, j)[0] = cv::saturate_cast<uchar>(rets[0] + 100);
					m.at<cv::Vec3b>(i, j)[1] = cv::saturate_cast<uchar>(rets[1] + 100);
					m.at<cv::Vec3b>(i, j)[2] = cv::saturate_cast<uchar>(rets[2] + 100);
#endif
				}
			}
		}
	}
private:
	cv::Mat m;
};
int main(){
	ImgPixel img("dog.png");
	img.show("origin");
	img.Visit_By_Array();
	img.show("convert1");

	cv::waitKey(0);
	return 0;
}

安全类型转换:saturate_cast<T> 是openCV的一种安全转换函数,当我们对像素执行加减乘除的时候,有可能会超出 [ 0 , 255 ] [0,255] [0,255]
的范围,因此使用此函数来保证不会越界。

实际上这个函数就是:

  • 超过255:转为255
  • 小于0:转为0
template<> inline uchar saturate_cast<uchar>(int v)          { return (uchar)((unsigned)v <= UCHAR_MAX ? v : v > 0 ? UCHAR_MAX : 0); }

像素算数运算

图像可以进行像素之间的算数运算,跟我们上节的对像素的简单减法是一样的:

我们有专门的函数:

  • add:像素加
  • subtract:像素减
  • multiply:像素乘
  • divide:像素除
  • addWeighted:对图片执行: α ⋅ i m g 1 + β ⋅ i m g 2 = r e s \alpha\cdot img_1 + \beta\cdot img_2 = res αimg1+βimg2=res 的操作,其中的 α \alpha α β \beta β就是透明度

除了基本的运算,还有二进制运算

  • and:像素按位与
  • or:按位或
  • **not:**按位取反
  • xor:按位异或

测试如下:

需要两个原图片执行下面的这些操作,我使用的图片是:(注意尺寸要一样)

在这里插入图片描述

然后自行执行下面代码。

在这里插入图片描述

#include <iostream>
#include <opencv2/opencv.hpp>

class ImgOperation {
public:
	ImgOperation() :m1(cv::imread("dog.png")), m2(cv::imread("text.jpg")) {}
	void testAdd(std::string title="add") {
		cv::add(m1, m2, res);
		cv::imshow(title, res);
		cv::waitKey();
	}
	void testSub(std::string title = "subtract") {
		cv::subtract(m1, m2, res);
		cv::imshow(title, res);
		cv::waitKey();
	}
	void testMul(std::string title = "multiply") {
		cv::multiply(m1, m2, res);
		cv::imshow(title, res);
		cv::waitKey();
	}
	void testDivide(std::string title = "divide") {
		cv::divide(m1, m2, res);
		cv::imshow(title, res);
		cv::waitKey();
	}
	void testAddWeighted(std::string title="AddWeighted") {
		cv::addWeighted(m1, 0.1, m2, 0.9, 0, res);
		cv::imshow(title, res);
		cv::waitKey();
	}
	//BitWise
	void testBitWise() {
		cv::Mat _and, _or, _xor, _not;
		cv::bitwise_and(m1, m2, _and);
		cv::bitwise_or(m1, m2, _or);
		cv::bitwise_xor(m1, m2, _xor);
		cv::bitwise_not(m1, _not);

		cv::imshow("and", _and);
		cv::imshow("or", _or);
		cv::imshow("xor", _xor);
		cv::imshow("not", _not);
	}
private:
	cv::Mat m1;
	cv::Mat m2;
	cv::Mat res;
};

int main()
{
	ImgOperation opt;
	//opt.testAdd();
	//opt.testSub();
	//opt.testMul();
	//opt.testDivide();
	//opt.testAddWeighted();	
	opt.testBitWise();

	cv::waitKey();
	return 0;
}

图形文字绘制

绘制线

使用**line**函数,原型如下:

void line(InputOutputArray img, Point pt1, Point pt2, const Scalar& color,int thickness = 1, int lineType = LINE_8, int shift = 0);
//线的样式
enum LineTypes {
    FILLED  = -1,
    LINE_4  = 4, //!< 4-connected line
    LINE_8  = 8, //!< 8-connected line
    LINE_AA = 16 //!< antialiased line
};
/*******************************************************************
*			img: 			绘制在那个图像上
*			pt1:			起点
*			pt2:			终点
*			color:			颜色
*			thickness:		厚度(宽度) 
*			lineType:		线的样式
*					FILLED: 线填充的
*					LINE_4:	4邻接连接线
*					LINE_8: 8邻接连接线
*					LINE_AA:反锯齿连接线(高斯滤波)
*			shift: 			坐标点小数点位数(可忽略不写)
*********************************************************************/

在执行 imshow的之前,在图片上画一条线:

void testDrawLine() {
		//绘制线
		cv::line(m, cv::Point(0, 0), cv::Point(300, 300), cv::Scalar(0,255,0), 3, cv::LineTypes::LINE_AA);
	}

在这里插入图片描述


绘制圆

使用**circle函数来绘制或者填充圆**

void circle(InputOutputArray img, Point center, int radius,const Scalar& color, int thickness = 1,int lineType = LINE_8, int shift = 0);
//线的样式
enum LineTypes {
    FILLED  = -1,
    LINE_4  = 4, //!< 4-connected line
    LINE_8  = 8, //!< 8-connected line
    LINE_AA = 16 //!< antialiased line
};
/*******************************************************************
*			img: 			绘制在那个图像上
*			center:			圆心坐标
*			radius:			半径
*			color:			颜色
*			thickness:		厚度(宽度)
*								-1: 	填充圆
*								其他值:  空心
*			lineType:		 线的样式
*					FILLED: 线填充的
*					LINE_4:	4邻接连接线
*					LINE_8: 8邻接连接线
*					LINE_AA:反锯齿连接线(高斯滤波)
*			shift: 			坐标点小数点位数(可忽略不写)
*********************************************************************/

效果如下:

  • 填充效果需要把thickness置为-1。
void testDrawCircle() {
		cv::circle(m, cv::Point(150, 150), 50, cv::Scalar(0, 255, 0),-1); //填充圆
		cv::circle(m, cv::Point(150, 150), 52, cv::Scalar(0, 0, 255), 2, 
							cv::LineTypes::LINE_AA); //空心圆
	}

在这里插入图片描述


绘制矩形

使用rectangle函数来绘制矩形。

void rectangle(InputOutputArray img, Rect rec,const Scalar& color, int thickness = 1,int lineType = LINE_8, int shift = 0);
/*******************************************************************
*			img: 			绘制在那个图像上
*			rec:			矩形大小  Rect(x,y,w,h);  
*					x,y:	起始坐标
*					w,h:	宽度和高度
*			color:			颜色
*			thickness:		厚度(宽度)
*								-1: 	填充矩形
*								其他值:  空心矩形
*			lineType:		线的样式
*					FILLED: 线填充的
*					LINE_4:	4邻接连接线
*					LINE_8: 8邻接连接线
*					LINE_AA:反锯齿连接线(高斯滤波)
*			shift: 			坐标点小数点位数(可忽略不写)
*********************************************************************/

效果如下:

void testDrawRectangle() {
		cv::rectangle(m, cv::Rect(0, 0, 50, 50), cv::Scalar(100, 45, 20),-1);
	}

在这里插入图片描述


绘制椭圆

使用ellipse来绘制椭圆:

void ellipse(InputOutputArray img, Point center, Size axes,double angle, double startAngle, double endAngle,
const Scalar& color, int thickness = 1,int lineType = LINE_8, int shift = 0);
/*******************************************************************
*			img: 			绘制在那个图像上
*			center:			椭圆圆心
*			axes:			矩形内置椭圆
*			angle:			倾斜角
*			startAngle:		扩展的弧度 0
*			endAngle:		 扩展的弧度  360
*			color:			颜色
*			thickness:		线宽度
*								-1: 	填充矩形
*								其他值:  空心矩形
*			lineType:		线的样式
*					FILLED: 线填充的
*					LINE_4:	4邻接连接线
*					LINE_8: 8邻接连接线
*					LINE_AA:反锯齿连接线(高斯滤波)
*			shift: 			坐标点小数点位数(可忽略不写)
*********************************************************************/

效果如下:

void testDrawEllipse() {
		cv::ellipse(m, cv::Point(100, 100),cv::Size(20,80),
						180,0,360, cv::Scalar(54, 54, 43));
		cv::ellipse(m, cv::Point(100, 100), cv::Size(20, 80), 
						90, 0, 360, cv::Scalar(54, 54, 43),-1);
	}

在这里插入图片描述


绘制文字

使用**putText来绘制文字,注意不支持中文!!!!!!!!!!!!!**

void putText( InputOutputArray img, const String& text, Point org,int fontFace, double fontScale, Scalar color,int thickness = 1, int lineType = LINE_8,bool bottomLeftOrigin = false );
/*******************************************************************
*			img: 			绘制在那个图像上
*			text:			绘制文字
*			org:			文本框左下角
*			fontFace:		字体
*			fontScale:		缩放
*			color:			颜色
*			thickness		线宽度
*			lineType:		线的样式
*					FILLED: 线填充的
*					LINE_4:	4邻接连接线
*					LINE_8: 8邻接连接线
*					LINE_AA:反锯齿连接线(高斯滤波)
*			bottomLeftOrigin: 		起点位置
*								true:  左上角  反转倒立显示
*								false: 左下角  正常显示
*********************************************************************/
//opencv 不识别汉字
//fontFace: 字体
enum HersheyFonts {
    FONT_HERSHEY_SIMPLEX        = 0, //!< normal size sans-serif font   //灯芯体
    FONT_HERSHEY_PLAIN          = 1, //!< small size sans-serif font
    FONT_HERSHEY_DUPLEX         = 2, //!< normal size sans-serif font (more complex than FONT_HERSHEY_SIMPLEX)
    FONT_HERSHEY_COMPLEX        = 3, //!< normal size serif font
    FONT_HERSHEY_TRIPLEX        = 4, //!< normal size serif font (more complex than FONT_HERSHEY_COMPLEX)
    FONT_HERSHEY_COMPLEX_SMALL  = 5, //!< smaller version of FONT_HERSHEY_COMPLEX
    FONT_HERSHEY_SCRIPT_SIMPLEX = 6, //!< hand-writing style font
    FONT_HERSHEY_SCRIPT_COMPLEX = 7, //!< more complex variant of FONT_HERSHEY_SCRIPT_SIMPLEX
    FONT_ITALIC                 = 16 //!< flag for italic font
};

测试如下:

void testDrawText(const std::string& name) {
		cv::putText(m,
			name,
			cv::Point(10, 200),
			cv::HersheyFonts::FONT_HERSHEY_COMPLEX,
			1.0,
			cv::Scalar(50,50,255),
			2,
			cv::LineTypes::LINE_AA,
			false); //翻转
	}

在这里插入图片描述


其他绘制函数

绘制多边形线:

  • polylines

绘制填充多边形:

  • fillPoly

文本参考

百度百科_全球领先的中文百科全书

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

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

相关文章

python机器学习(二)特征工程、K-近邻算法、KNN工作流程、scikit-learn实现K近邻算法、K值选择、距离计算、KD树

特征工程 把特征转换为机器容易识别的数据&#xff0c;把特征a转化为机器容易读懂、量化的语言 归一化Min-Max 将原始数据映射到[0,1]之间 X ′ x − m i n m a x − m i n X \frac{x-min}{max-min} X′max−minx−min​ 但是归一化是有弊端的&#xff0c;比如有一个值错误…

OJ练习第142题——路径总和 II

113. 路径总和 II 力扣链接&#xff1a;113. 路径总和 II 题目描述 给你二叉树的根节点 root 和一个整数目标和 targetSum &#xff0c;找出所有 从根节点到叶子节点 路径总和等于给定目标和的路径。 叶子节点 是指没有子节点的节点。 示例 Java代码&#xff08;深度优先搜…

基于linux下的高并发服务器开发(第三章)- 3.8 线程同步

sellticket.c /*使用多线程实现买票的案例。有3个窗口&#xff0c;一共是100张票。 */#include <stdio.h> #include <pthread.h> #include <unistd.h>// 全局变量&#xff0c;所有的线程都共享这一份资源。 int tickets 100;void * sellticket(void * arg)…

后处理材质球:黄金螺旋分割线和参考图

后处理材质球&#xff1a;黄金螺旋分割线和参考图 Begin Object Class/Script/UnrealEd.MaterialGraphNode Name"MaterialGraphNode_0"Begin Object Class/Script/Engine.MaterialExpressionLinearInterpolate Name"MaterialExpressionLinearInterpolate_1&qu…

(202307)wonderful-sql:初识数据库(task1)

学习知识 初识数据库 关系型数据库简介 特点是由行和列组成的二维表来管理数据&#xff0c;这种类型的 DBMS 称为关系数据库管理系统&#xff08;Relational Database Management System&#xff0c;RDBMS&#xff09;。本课程将向大家介绍使用 SQL 语言的数据库管理系统&am…

No5:学习过程中基础语法积累

文章目录 基础语法&#xff1a;对象对象构建和数据封装 集合列表截取输出&#xff08;特色是数据可变即可重新赋值&#xff09;元组截取输出&#xff08;元组特色是数据不可变&#xff09;字典&#xff08;根据key取value&#xff09; 字符串函数 基础语法&#xff1a;对象 对…

【动态规划part04】| 背包问题理论基础、416.分割等和子集

目录 &#x1f388;背包问题理论基础 &#x1f45c;01背包 ✨二维dp数组01背包 ✨一维dp数组01背包&#xff08;滚动数组&#xff09; &#x1f388;LeetCode416.分割等和子集 &#x1f388;背包问题理论基础 &#x1f45c;01背包 有n件物品和一个最多能背重量为w 的背…

AUTOSAR从入门到精通-【应用篇】基于 LIN 总线的汽车自动天窗防夹控制系统的设计与实现

目录 前言 天窗控制系统的 LIN 总线 2.1 LIN 总线概述 2.2 LIN 总线协议规范 2.3 防夹控制系统的 LIN 总线 2.4 系统 LIN 网络测试 天窗防夹控制系统整体设计方案 3.1 天窗防夹控制系统功能 3.2 控制系统总体设计 3.2.1 系统结构 3.2.2 天窗防夹控制器 3.2.3 天窗传…

小黑子—JavaWeb:第二章 Maven与MyBatis

JavaWeb入门2.0 1.Maven1.1 Maven 简介1.2 Maven 安装配置1.3 Maven 基本使用1.3.1 Maven常用命令1.3.2 Maven生命周期 1.4 IDEA 配置 Maven1.4.1 配置 Maven 环境1.4.2 Maven 坐标详情1.4.3 IDEA 创建Maven项目1.4.4 IDEA 导入Maven文件1.4.5 配置Maven-Helper 插件 1.5 依赖管…

逻辑斯特回归

*分类是离散的&#xff0c;回归是连续的 下载数据集 trainTrue&#xff1a;下载训练集 逻辑斯蒂函数保证输出值在0-1之间 能够把实数值映射到0-1之间 导函数类似正态分布 其他饱和函数sigmoid functions 循环神经网络经常使用tanh函数 与线性回归区别 塞戈马无参数&#x…

《嵌入式 - 工具》J-link读写MCU内部Flash

1 J-Link简介 J-Link是SEGGER公司为支持仿真ARM内核芯片推出的JTAG仿真器。配合IAR EWAR&#xff0c;ADS&#xff0c;KEIL&#xff0c;WINARM&#xff0c;RealView等集成开发环境支持所有ARM7/ARM9/ARM11,Cortex M0/M1/M3/M4, Cortex A5/A8/A9等内核芯片的仿真&#xff0c;是学…

VirtualBox 7.0.10 使用宿主机物理硬盘

方法&#xff1a; 利用virtualbox的管理工具&#xff0c;将宿主机脱机后的物理硬盘&#xff0c;映射为一个vmdk&#xff0c;然后在vitrualbox中注册该vmdk&#xff0c;然后分配给虚拟机使用。 1. 右键单击window桌面左下角&#xff0c;选择 Windows PowerShell (管理员) 2. c…

第一章 函数的概念

文章目录 考点1、定义域2、对应法则 一、函数的概念1、自变量 x , 因变量 y&#xff0c;一一对应&#xff0c;因此有公式 y f (x)2、定义域具体函数的定义域 &#xff08;送分题&#xff09; 真题1、2、3、4、抽象函数的定义域 真题1、2、 3、根据函数的对应法则求函数表达式题…

会声会影VideoStudio2023中文旗舰版有哪些新功能及最低系统配置要求

会声会影VideoStudio2023中文旗舰版使用起来很有趣。它很容易使用&#xff0c;但仍然给你很多功能和力量。会声会影VideoStudio2023中文旗舰版让我与世界分享我的想法&#xff01;“这个产品的功能非常多&#xff0c;我几乎没有触及它的表面&#xff0c;我可以做大量的编辑、色…

js ==运算规则

let a {name: zhangsan,valueOf(){return 100;} }; let b 100; console.log(ab); //true let a {value: 1,valueOf: function() {return this.value;} };console.log(a 1 && a 2 && a 3); // 输出 true

macOS Sonoma 14 beta 3 (23A5286i) ISO、IPSW、PKG 下载,公共测试版现已推出

macOS Sonoma 14 beta 3 (23A5286i) ISO、IPSW、PKG 下载&#xff0c;公共测试版现已推出 本站下载的 macOS 软件包&#xff0c;既可以拖拽到 Applications&#xff08;应用程序&#xff09;下直接安装&#xff0c;也可以制作启动 U 盘安装&#xff0c;或者在虚拟机中启动安装…

树莓派安装ROS

ROS&#xff0c;树莓派如何快速部署ROS 版本查看 检查Raspbian版本的最简单方法是利用终端。 在开始之前&#xff0c;请确保已经开启了一个终端会话。 在Raspbian中使用一个简单的命令来获取当前版本。 要查看当前安装的Raspbian版本信息&#xff0c;需要做的就是执行下面的…

RT1052的介绍及MDK

文章目录 RT1052 核心板的资源型号为&#xff1a;RT1052CVL5B。GPIO端口原理LDOEEPROM 复位电路启动模式设置电路BootLoader地址 开发环境搭建新建 基于 FSL 库的 MDK5 工程软件下载SDK包SDK包内容boards 文件夹CMSIS 文件夹devices 文件夹middleware 文件夹&#xff1a; 新建工…

解决Git拉取代码仓库时显示文件名太长无法创建的问题解决

问题描述 拉取鸿蒙仓库应用示例代码时&#xff0c;鸿蒙应用示例代码&#xff0c;发现能下载成功&#xff0c;但是会报一个错误&#xff0c;错误截图和信息如下所示&#xff1a; 报错信息&#xff1a; try/src/main/ets/pages/pagelevelstagemanagement/multicompomentssync/ …

Redis的9种数据类型与数据持久化

系列文章传送门&#xff1a; 【七天入门数据库】第一天 MySQL的安装部署 【七天入门数据库】第二天 数据库理论基础 【七天入门数据库】第三天 MySQL的库表操作 【七天入门数据库】第四天 数据操作语言DML 一、Redis的9种数据类型的基本操作 &#xff08;一&#xff09;k…