当前位置: 首页 > news >正文

学习OpenCV C++版

OpenCV C++

  • 1 数据载入、显示与保存
    • 1.1 概念
    • 1.2 Mat 类构造与赋值
    • 1.3 Mat 类的赋值
    • 1.4 Mat 类支持的运算
    • 1.5 图像的读取与显示
    • 1.6 视频加载与摄像头调用
    • 1.7 数据保存

参考:《OpenCV4快速入门》作者冯 振 郭延宁 吕跃勇

1 数据载入、显示与保存

1.1 概念

  1. Mat 类 : Mat 类用来保存矩阵类型的数据信息。Mat 类分为 矩阵头和指向存储数据的矩阵指针两部分。矩阵头中包含矩阵的尺寸、存储方法、地址和引用次数等(eg:(h,w,c,a),jpg,0001,2 + p)。在 OpenCV 中复制和传递图像时,只是复制了矩阵头和指向存储数据的指针,而非存放矩阵数据,从而节省计算机资源。
  2. 创建 Mat类
// 创建 Mat类
cv::Mat a;                   // 创建一个名为a的矩阵头
a = cv::imread('1.jpg');     // 向a中赋值图像数据,a的矩阵指针指向图像数据
cv::Mat b = a;               // 复制矩阵头,并命名为b// 用Mat 类只存储矩阵头和矩阵指针的优点?
// 通过a,b可以修改图像内容吗?
// 删除a对b有影响吗?
// 
  1. Mat 类可以存储的数据类型:double、float、uchar、unsigned char。用模版制定Mat类存放数据类型。
cv::Mat A = Mat_<double>(3,3); //创建一个3*3的矩阵用于存放double类型数据
cv::Mat B = Mat_<float>(640,640,256);
  1. 通过 OpenCV 数据类型创建 Mat 类
// 1. OpenCV 中的数据类型与取值范围
CV_8U        8位无符号整数       0~255     [0~2**8]
CV_8S        8位符号整数         −128~127  [-2**7~2**7-1]
CV_16U       16位无符号整数      0~65535   [0~2**16]
CV_16S       16位符号整数        −32768~32767  [-2**15~2**15-1]
CV_32S       32位符号整数        −2147483648~2147483647  [-2**32~2**32-1]
CV_32F       32位浮点整数        -FLT_MAX~FLT_MAX, INF, NAN
CV_64F       64位浮点整数        -DBL_MAX~DBL_MAX, INF, NAN// 2. OpenCV 还定义了通道 数标识,C1、C2、C3、C4、C512 分别表示单通道、双通道、3 通道和 4 通道// 3. OpenCV 中对图像数据类型的完整定义,例如 CV_8UC1 表示的是 8 位单通道数据,用于表示 8 位灰度图,而 CV_8UC3 表示的是 8 位 3 通道数据,用于表示 8 位彩色图。
cv::Mat a(640,480,CV_8UC3); // 创建一个640*480的3通道矩阵用于存放彩色图像
cv::Mat b(3,3,CV_8UC1);     // 创建一个3*3的8位无符号整数的单通道矩阵
cv::Mat c(3,3,CV_8U);       // 创建单通道矩阵,C1标识可以省略// 4. 错误
cv::Mat a = Mat_<CV_8U>(3,3);  // Mat_<>()模版只识别float、double、int等C++的数据类型
cv::Mat a(3,3,uchar);    // 据Mat类构造函数只能用只能用OpenCV 中的数据类型

1.2 Mat 类构造与赋值

  • 使用默认构造函数方式创建Mat
  • 根据输入矩阵尺寸和类型构造
  • 用 Size()结构构造 Mat 类
  • 利用已有矩阵构造 Mat 类
  • 构造已有 Mat 类的子类
  1. 使用默认构造函数方式创建Mat
cv::Mat::Mat(int rows,int cols,int type,const Scalar &  s)
// cv::Mat::Mat();cv::Mat a;
  1. 根据输入矩阵尺寸和类型构造
cv::Mat::Mat( int rows,int cols,int type)cv::Mat a(1280,1280,CV_32FC512);   
  1. 用 Size()结构构造 Mat 类
cv::Mat::Mat(Size size(cols, rows),int  type)cv::Mat a(Size(10,20),CV_8S3);      //构造一个行为640、列为480的3通道矩阵
cv::Mat b(Size(480,640),CV_32FC3);  //构造一个行为640、列为480的3通道矩阵
  1. 利用已有矩阵构造 Mat 类
cv::Mat::Mat( const Mat &  m);cv::Mat a(Size(10,20),CV_8S3); 
cv::Mat b(a);         // b复制了a的矩阵头,矩阵指针指向的是同一个地址
cv::Mat b=a;          // 同cv::Mat b(a)的效果一样
cv::Mat c=a.clone();  // c复制两个一模一样a,c更改数据,a不受影响。
  1. 构造已有 Mat 类的子类
    通过这种方式构造的 Mat 类与已
    有 Mat 类享有共同的数据,即如果两个 Mat 类中有一个数据发生更改,那么另一个也会随之更改。
cv::Mat::Mat(const Mat & m,const Range &  rowRange,const Range &  colRange = Range::all() )cv::Mat a(Size(10,20),CV_8S3); 
cv::Mat b(a,Range(2,5),Range(2,5));      // 从a中截取部分数据构造b  cv::Mat c(a,Range(2,5));                 // 默认最后一个参数构造c

1.3 Mat 类的赋值

  • 在构造时赋值的方法
  • 枚举法赋值示例
  • 循环法赋值
  • 类方法赋值
  • 利用数组进行赋值示例
  1. 在构造时赋值的方法
cv::Mat::Mat(int rows,int cols,int type,const Scalar &  s)
cv::Mat a(20,20,CV_8UC1,CV::Scalar(255,0,0));  //创建一个3通道矩阵,每个像素都是255,0,0
cv::Mat b(2,2,CV_8UC2,cv::Scalar(0,255)); //创建一个2通道矩阵,每个像素都是0,255
cv::Mat c(2, 2, CV_8UC1, cv::Scalar(255)); //创建一个单通道矩阵,每个像素都是 255// Scalar 结构中变量的个数一定要与定义中的通道数相对应。如果 Scalar 结 构中变量的个数大于通道数,则位置在大于通道数之后的数值将不会被读取, 例如执行 a(2, 2, CV_8UC2, Scalar(0,0,255))后,每个像素值都将是(0,0),而 255 不会被读取;如果 Scalar 结构中变量的个数小于通道数,则会以 0 补充。
  1. 枚举法赋值
    这种赋值方式是将矩阵中所有的元素一一列举,并用数据流的形式赋值给 Mat 类。
    在采用枚举法时,输入的数据个数一定要与矩阵元素个数相同,否则会现报错。本方法常适用于矩阵数据比较少的情况。
cv::Mat a=(Mat_<float>(2,4)<< 1.0,2.,3.,4.,5.,6.,7.,8.);
cv::Mat b=(Mat_<int>(2,2)<<2,4,9,16);
  1. 循环法赋值
    循环法赋值也是对矩阵中的每一个元素进行赋值,但是可以不在
    声明变量的时候进行赋值,而且可以对矩阵中的任意部分进行赋值。在给矩阵每个元素赋值的时候,赋值函数中声明的变量类型要与矩阵定义时的变量类型相同,
cv::Mat a=Mat_<int>(2,3);
for (int i=0;i<a.rows;++i)
{for (int j=0;j<a.cols;++j){c.at<int>(i,j)=i*j;}
}
  1. 类方法赋值
    在 Mat 类里,提供了可以快速赋值的方法,可以初始化指定的矩阵。
cv::Mat a = cv::Mat::eye(3,3,CV_8Uc1);
cv::Mat b = (cv::Mat_<int>(1,3)<<1,2,3);
cv::Mat c = cv::Mat::diag(b);
cv::Mat d = cv::Mat::ones(3,3,cv_8UC1);
cv::Mat 3 = cv::Mat::zerons(2,3,cv_8UC3);
  1. 利用数组进行赋值示例

这种赋值方式首先将需要存入 Mat 类中的变量存入一个数组中,之后通过设置 Mat 类矩阵的 尺寸和通道数将数组变量拆分成矩阵,这种拆分方式可以自由定义矩阵的通道数。当矩阵中的元素 数目大于数组中的数据时,将用−1.073 741 8e+08 填充赋值给矩阵;当矩阵中元素的数目小于数组 中的数据时,将矩阵赋值完成后,数组中剩余数据将不再赋值。由数组赋值给矩阵的过程是首先将 矩阵中第一个元素的所有通道依次赋值,之后再赋值下一个元素。

float a[8]={1,2,3,4,5,6,7,8};
cv::Mat b = cv::Mat(2,2,CV_8UC2,a);
cv::Mat c = cv::Mat(2,4,CV_8UC1,a);cv::Mat d = cv::Mat(2,2,CV_8UC1,a);
cv::Mat e = cv::Mat(3,4,CV_8UC3,a);

1.4 Mat 类支持的运算

  1. Mat 类的加减乘除运算,当两个 Mat 类变量进行加减运算时,必须保证两个矩阵中的数据类型是相同的。
cv::Mat a = (cv::Mat_<int>(3,3)<<1,2,3,4,5,6,7,8,9);
cv::Mat b = (cv::Mat_<int>(3,3)<<1,2,3,4,5,6,7,8,9);
cv::Mat c = (cv::Mat_<double>(3,3)<<1.,2.,3.,4.,5.,6.,7.,8.,9.);
cv::Mat d = (cv::Mat_<double>(3,3)<<1.1,2.2,3.2,4.4,5.5,6.6,7.7,8.8,9.9);
cv::Mat e,,f,g,h,i;
e = a+b; 
f = c-d;
g = 2*a;
h = d/2.3;
i = a-1;
  1. 两个 Mat 类矩阵的乘法运算
  • *:Mat 类中的数据类型必须是 CV_32FC1、 CV_64FC1、 CV_32FC2、 CV_64FC2 这 4 种中的一种。
  • dot():dot()方法 结果是一个 double 类型的变量,该运算的目的是求取一个行向量和一个列向量点乘。
  • mul():表示两个 Mat 类矩阵对应位的乘积。根据输出结果可以知道 mul() 方法运算结果同样是一个 Mat 类矩阵。
cv::Mat j,m;
double x;
j = c*d;             // 矩阵乘法,c的列数必须等于d的行数;
double x= a.dot(b);  // 内积
m = a.mul(b);        // 
  1. Mat 类矩阵常用的属性
'''
a[2,2,3]
[(1,2,3),(4,5,6)
(7,8,9),(10,11,12)]
'''
cv::Mat a(3,4,CV_32FC3);
a.cols         // 4
a.rows;        // 3
a.elemsize();  // 每个元素的字节数,32/8×channels()=12
a.step;        // 以字节为单位的矩阵的有效宽度,每个元素的字节数*cols=12*4=48,矩阵一行的字节数。
a.total;       // 矩阵中元素的个数 3*4*200
a.channels()   // 矩阵的通道数
  1. Mat 类元素的读取
  • 通过 at 方法读取 Mat 类矩阵中的元素
  • 通过指针 ptr 读取 Mat 类矩阵中的元素
  • 通过迭代器访问 Mat 类矩阵中的元素
  • 通过矩阵元素的地址定位方式访问元素

1)at 方法读取 Mat 类单通道矩阵元素。
单通道图像是一个二维矩阵,因此在 at 方法的最后给出二维平面坐标即可访问对应位置 元素

cv::Mat a = (cv::Mat_<uchar>(3, 3) << 1, 2, 3, 4, 5, 6, 7, 8, 9); 
int value = (int)a.at<uchar>(0, 0);

多通道矩阵每一个元素坐标处都是多个数据,因此引入一个变量用于表示同一元素的多个 数据。在 OpenCV 中,针对三通道矩阵,定义了 cv::Vec3b、cv::Vec3s、cv::Vec3w、cv::Vec3d、cv::Vec3f、 cv::Vec3i 共 6 种类型用于表示同一个元素的 3 个通道数据。b 是 uchar 类型的缩写、s 是 short 类型的缩写、w 是 ushort 类型的缩写、d 是 double 类型的缩写、f 是 float 类型的缩写、i 是 int 类型的缩写。OpenCV 也为二通道和四通道定义了对应的变量类型,其命名方式也遵循这个 命名规则,例如二通道和四通道的 uchar 类型分别用 cv::Vec2b 和 cv::Vec4b 表示。

2)at 方法读取 Mat 类多通道矩阵元素

cv::Mat b(3, 4, CV_8UC3, cv::Scalar(0, 0, 1));
cv::Vec3b vc3 = b.at<cv::Vec3b>(0, 0);   // vc3的数据类型要与b的数据类型一致,Vec3b中的b 是 uchar 类型的缩写
int first = (int)vc3.val[0];
int second = (int)vc3.val[1];
int third = (int)vc3.val[2];

3)指针 ptr 读取 Mat 类矩阵元素

cv::Mat b(3,4,CV_8UC3,cv::Scale(0,0,1));
for (int i=0;i<b.rows;++i)
{uchar* ptr = b.ptr<uchar>[i];for (int j=0;j<b.cols*b.channels;++j){cout<<(int)ptr[j]<<endl;}
}b.ptr<uchart>(2)[3]; // 第三行第4个数据

4)通过迭代器访问 Mat 类矩阵中的元素

cv::Mat a(3,4,CV_8UC3,cv::Scale(0,0,1));
cv::MatIterator_<uchar> it = a.begin<uchar>();
cv::MatIterator_<uchar> it_end = a.end<uchar>();
for (int i=0;it != it_end;++it)
{cout<<(int)(*it)<<"";if((++i%a.cols)==0){cout<<endl;}
}
  1. 通过矩阵元素的地址定位方式访问元素
cv::Mat a(3,4,CV_8UC3,cv::Scale(0,0,1));
(int)(*(a.data+a.step[0]*row+a.step[1]*col+channle));

1.5 图像的读取与显示

// imread()函数的原型
1. cv::Mat cv::imread(const String & filename,
2.                     int  flags=IMREAD_COLOR
3.                     )// 图像窗口函数 namedWindow
1. void cv::namedWindow(const String & winname,
2.                       int  flags = WINDOW_AUTOSIZE
3.                       )// 图像显示函数 imshow
1. void cv::imshow(const String & winname,
2.                  InputArray  mat
3.                  )// 图像显示时常
cv::waitKey(0)

1.6 视频加载与摄像头调用

1)视频数据的读取

cv :: VideoCapture :: VideoCapture(); //默认构造函数
cv :: VideoCapture :: VideoCapture(const String& filename,int apiPreference =CAP_ANY)
• filename:读取的视频文件或者图像序列名称。
• apiPreference:读取数据时设置的属性,例如编码格式、是否调用 OpenNI 等。

2)
VideoCapture.cpp 读取视频文件

#include<opencv2\opencv.hpp>
include<iostream>using namespace std;
using namespace cv;int main()
{system("color F0");   //更改输出界面颜色VideoCapture video("cup.mp4");  // 实例化一个视频if(video.isOpened())   // 判断视频是否可以正确读取{   // 显示视频属性cout << "视频中图像的宽度=" << video.get(CAP_PROP_FRAME_WIDTH) << endl;cout << "视频中图像的高度=" << video.get(CAP_PROP_FRAME_HEIGHT) << endl;cout << "视频帧率=" << video.get(CAP_PROP_FPS) << endl;cout << "视频的总帧数=" << video.get(CAP_PROP_FRAME_COUNT);}else{cout << "请确认视频文件名称是否正确" << endl;return -1;}while(1){Mat frame;video >> frame;   // 获取当前帧if(frame.empty()){break;}imshow("video",frame);waitKey(1000/video.get(CAP_PROP_FPS));}waitKey();return 0;
}

3)摄像头的直接调用

cv :: VideoCapture :: VideoCapture(int index,int apiPreference = CAP_ANY)#include<opencv2\opencv.hpp>
include<iostream>using namespace std;
using namespace cv;int main()
{system("color F0");   //更改输出界面颜色VideoCapture video(0);  // 实例化一个视频if(video.isOpened())   // 判断视频是否可以正确读取{   // 显示视频属性cout << "视频中图像的宽度=" << video.get(CAP_PROP_FRAME_WIDTH) << endl;cout << "视频中图像的高度=" << video.get(CAP_PROP_FRAME_HEIGHT) << endl;cout << "视频帧率=" << video.get(CAP_PROP_FPS) << endl;cout << "视频的总帧数=" << video.get(CAP_PROP_FRAME_COUNT);}else{cout << "请确认视频文件名称是否正确" << endl;return -1;}while(1){Mat frame;video >> frame;   // 获取当前帧if(frame.empty()){break;}imshow("video",frame);waitKey(1000/video.get(CAP_PROP_FPS));}waitKey();return 0;
}

1.7 数据保存

OpenCV 提供 imwrite()函数用于将 Mat 类矩阵保存成图像文件

  1. 图像的保存
1. bool cv :: imwrite(const String& filename,
2.                     InputArray img,
3.                     Const std::vector<int>& params =std::vector<int>()
4. )• filename:保存图像的地址和文件名,包含图像格式。
• img:将要保存的 Mat 类矩阵变量。
• params:保存图片格式属性设置标志。
  1. imgWriter.cpp 保存图像
#include <opencv2\opencv.hpp>
#include <iostream>using  namespace std;
using  namespace cv;void AlphaMat(Mat &mat)
{CV_Assert(mat.channels() == 4);for (int i = 0; i < mat.rows; ++i){for (int j = 0; j < mat.cols; ++j){Vec4b& bgra = mat.at<Vec4b>(i, j);bgra[0] = UCHAR_MAX; // 蓝色通道bgra[1] = saturate_cast<uchar>((float(mat.cols - j)) / ((float)mat.cols)* UCHAR_MAX); // 绿色通道bgra[2] = saturate_cast<uchar>((float(mat.rows - i)) / ((float)mat.rows) * UCHAR_MAX); // 红色通道bgra[3] = saturate_cast<uchar>(0.5 * (bgra[1] + bgra[2])); // Alpha 通道}}
}int main(int agrc, char** agrv)
{Mat mat(480, 640, CV_8UC4);AlphaMat(mat);// imwrite()函数中第三个参数设置方式vector<int> compression_params;compression_params.push_back(IMWRITE_PNG_COMPRESSION); //PNG格式图像压缩标志compression_params.push_back(9); //设置最高压缩质量bool result = imwrite("alpha.png", mat, compression_params);if (!result){cout<< "保存成 PNG 格式图像失败" << endl;return -1;}cout << "保存成功" << endl;return 0;
}

3)视频的保存

1. cv :: VideoWriter :: VideoWriter(); //默认构造函数
2. cv :: VideoWriter :: VideoWriter(const String& filename,
3.                                   int fourcc,
4.                                   double  fps,
5.                                   Size frameSize,
6.                                   bool  isColor=true
7. )
• filename:保存视频的地址和文件名,包含视频格式。
• fourcc:压缩帧的 4 字符编解码器代码,详细参数在表 2-7 中给出。
• fps:保存视频的帧率,即视频中每秒图像的张数。
• frameSize:视频帧的尺寸。
• isColor:保存视频是否为彩色视频。// 保存视频文件
#include<opencv2\opencv.hpp>
include<iostream>using namespace std;
using namespace cv;int main()
{Mat img;VideoCapture video(0);  // 实例化一个视频if(!video.isOpened())   // 判断视频是否可以正确读取{   cout << "打开摄像头失败,请确认摄像头是否安装成功return -1;}else{cout << "请确认视频文件名称是否正确" << endl;return -1;}video >> img; //获取图像//检测是否成功获取图像if (img.empty()){cout << "没有获取到图像" << endl;return -1;}bool isColor = (img.type() == CV_8UC3); //判断相机(视频)类型是否为彩色VideoWriter writer;int codec = VideoWriter::fourcc('M', 'J', 'P', 'G'); // 选择编码格式double fps = 25.0; //设置视频帧率string filename = "live.avi"; //保存的视频文件名称writer.open(filename, codec, fps, img.size(), isColor); //创建保存视频文件的视频流if (!writer.isOpened()) //判断视频流是否创建成功{cout << "打开视频文件失败,请确认是否为合法输入" << endl;return -1;}while(1){if (!video.read(img)){cout << "摄像头断开连接或者视频读取完成" << endl;break;}writer.write(img); //把图像写入视频流imshow("Live", img); //显示图像char c = waitKey(50);if (c == 27) //按“Esc”键退出视频保存{break;}return 0;
}

相关文章:

学习OpenCV C++版

OpenCV C 1 数据载入、显示与保存1.1 概念1.2 Mat 类构造与赋值1.3 Mat 类的赋值1.4 Mat 类支持的运算1.5 图像的读取与显示1.6 视频加载与摄像头调用1.7 数据保存 参考&#xff1a;《OpenCV4快速入门》作者冯 振 郭延宁 吕跃勇 1 数据载入、显示与保存 1.1 概念 Mat 类 : Ma…...

特权FPGA之PS/2键盘解码

0 故事背景 见过这种接口的朋友们&#xff0c;大概都已经成家立业了吧。不过今天我们不讨论这种接口的历史&#xff0c;只讲讲这种接口的设计。&#xff08;如果还没有成家的朋友也别生气&#xff0c;做自己想做的事情就对了&#xff01;&#xff09; 1 时序分析 数据帧格式如图…...

SpringBoot 接口限流Lua脚本接合Redis 服务熔断 自定义注解 接口保护

介绍 Spring Boot 接口限流是防止接口被频繁请求而导致服务器负载过重或服务崩溃的一种策略。通过限流&#xff0c;我们可以控制单位时间内允许的请求次数&#xff0c;确保系统的稳定性。限流可以帮助防止恶意请求、保护系统资源&#xff0c;并优化 API 的可用性&#xff0c;避…...

FPAG_BUFFER学习

在FPGA设计中&#xff0c;缓冲器&#xff08;Buffer&#xff09;是信号传输和管理的核心组件&#xff0c;用于处理输入/输出信号、时钟分配以及信号完整性。以下是FPGA中常见缓冲器的详细介绍&#xff0c;分类说明其功能、应用场景和设计注意事项&#xff1a; --- ### **1. 输…...

《认知觉醒》下篇·第六章第一节“清晰:一个观念,重构你的行动力” 总结

《认知觉醒》下篇第六章第一节“清晰&#xff1a;一个观念&#xff0c;重构你的行动力”的核心内容总结&#xff1a; 1. 清晰的力量&#xff1a;行动力的第一性原理 定义 清晰是对目标、路径和结果的明确认知&#xff0c;是破除拖延与内耗的核心前提。 模糊的代价&#xff1a; …...

idea手动创建resources文件夹

有时maven没有构建成功可能造成&#xff0c;resources文件夹不创建的现象 此时我们可以手动创建 手动创建...

Scala相关知识学习总结6

1、集合计算高级函数说明 - 过滤&#xff1a;遍历集合&#xff0c;提取满足特定条件的元素组成新集合。 - 转化/映射&#xff08;map&#xff09;&#xff1a;将集合里的每个元素应用到指定函数进行转换。 - 扁平化&#xff1a;文档未详细阐述其具体含义和操作。 - 扁平化映射&…...

IDEA 调用 Generate 生成 Getter/Setter 快捷键

快捷键不会用&#xff1f; 快捷键&#xff1a;AltInsert 全选键&#xff1a;CtrlA IDEA 调用 Generate 生成 Getter/Setter 快捷键 - 爱吃西瓜的番茄酱 - 博客园...

【SpringCloud】从入门到精通(下)

网关与路由 什么是网关&#xff1f;顾明思议&#xff0c;网关就是网络的关口。数据在网络间传输&#xff0c;从一个网络传输到另一网络时就需要经过网关来做数据的路由和转发以及数据安全的校验。 现在前端不能请求各个微服务地址&#xff0c;只能去请求网关 网关可以做安全控…...

深入探索 C++23:特性测试与编译器支持

文章目录 一、C23 新特性概览&#xff08;一&#xff09;语言特性&#xff08;二&#xff09;标准库特性 二、特性测试程序三、主流编译器支持情况&#xff08;一&#xff09;GCC&#xff08;二&#xff09;Clang&#xff08;三&#xff09;MSVC 四、开发者建议&#xff08;一&…...

Electron 应用太重?试试 PakePlus 轻装上阵

Electron 作为将 Web 技术带入桌面应用领域的先驱框架&#xff0c;让无数开发者能够使用熟悉的 HTML、CSS 和 JavaScript 构建跨平台应用。然而&#xff0c;随着应用规模的扩大&#xff0c;Electron 应用的性能问题逐渐显现——内存占用高、启动速度慢、安装包体积庞大&#xf…...

驱动程序无法通过使用安全套接字层(SSL)加密与 SQL Server 建立安全连接

驱动程序无法通过使用安全套接字层(SSL)加密与 SQL Server 建立安全连接 原因描述 项目中有使用到 SQL Server 数据库, 在启动项目时, 出现报错信息: 【驱动程序无法通过使用安全套接字层(SSL)加密与 SQL Server 建立安全连接。错误:“The server selected protocol version…...

Java 设计模式:原型模式详解

Java 设计模式&#xff1a;原型模式详解 原型模式&#xff08;Prototype Pattern&#xff09;是一种创建型设计模式&#xff0c;它通过复制现有对象来创建新对象&#xff0c;而无需依赖其具体类。这种模式特别适合创建复杂对象或需要频繁创建相似对象的场景。本文将详细介绍原…...

NLP高频面试题(三十七)——大模型训练和推理的显存估计

在训练和推理大型语言模型时,显存(GPU 内存)的需求是一个关键考虑因素。准确估计这些需求有助于选择合适的硬件配置,确保模型高效运行。 推理阶段的显存需求 在推理过程中,显存主要用于存储模型权重和中间激活值。模型权重的显存需求可以通过以下公式估算: 模型权重…...

PHP 阿里云oss 使用指南

1.介绍 把图片放到阿里云上的空间上&#xff0c;可以使用cdn加速。 可以在程序里直接调用 要使用阿里云 oss sdk &#xff0c;请先到阿里云下载 或用 copmposer 安装 相关链接&#xff1a; 安装OSS PHP SDK_对象存储(OSS)-阿里云帮助中心 composer require aliyuncs/oss…...

leetcode_面试题 02.07. 链表相交_java

面试题 02.07. 链表相交https://leetcode.cn/problems/intersection-of-two-linked-lists-lcci/ 1、题目 给你两个单链表的头节点 headA 和 headB &#xff0c;请你找出并返回两个单链表相交的起始节点。如果两个链表没有交点&#xff0c;返回 null 。 图示两个链表在节点 c…...

LeetCode 3375.使数组的值全部为 K 的最少操作次数:O(1)空间——排序+一次遍历

【LetMeFly】3375.使数组的值全部为 K 的最少操作次数&#xff1a;O(1)空间——排序一次遍历 力扣题目链接&#xff1a;https://leetcode.cn/problems/minimum-operations-to-make-array-values-equal-to-k/ 给你一个整数数组 nums 和一个整数 k 。 如果一个数组中所有 严格…...

紫光展锐5G SoC T8300:影像升级,「定格」美好世界

影像能力已成为当今衡量智能手机性能的重要标尺之一。随着消费者对手机摄影需求日益提升&#xff0c;手机厂商纷纷在影像硬件和算法上展开激烈竞争&#xff0c;力求为用户带来更加出色的拍摄体验。 紫光展锐专为全球主流用户打造的畅享影音和游戏体验的5G SoC——T8300&#x…...

java基础 关键字static

static static使用简介static结合类的生命周期1.加载2.链接(1) 验证&#xff08;Verification&#xff09;(2) 准备&#xff08;Preparation&#xff09;(3) 解析&#xff08;Resolution&#xff09; 3. 初始化4.使用5.卸载总结 staic作用总结静态变量静态代码块静态方法静态内…...

大数据学习(105)-大数据组件分析

&#x1f34b;&#x1f34b;大数据学习&#x1f34b;&#x1f34b; &#x1f525;系列专栏&#xff1a; &#x1f451;哲学语录: 用力所能及&#xff0c;改变世界。 &#x1f496;如果觉得博主的文章还不错的话&#xff0c;请点赞&#x1f44d;收藏⭐️留言&#x1f4dd;支持一…...

Spark运行

一文读懂Spark&#xff1a;从核心概念到实战编程 在大数据处理领域&#xff0c;Spark凭借其高效的计算能力和灵活的架构脱颖而出。今天&#xff0c;就来和大家深入聊聊Spark&#xff0c;帮助初学者快速入门。Spark采用经典的master - slave结构。Driver如同master&#xff0c;…...

在macOS的docker中如何安装及运行ROS2

1、macOS环境及版本 2、docker for macos版本 3、拉取ROS2镜像 docker pull ros:iron 4、查看容器 docker images 5、启动 ROS2 容器 docker run -it --rm ros:iron -it &#xff1a;以交互模式运行容器。 --rm &#xff1a;退出时自动删除容器&#xff08;测试时推荐&am…...

FFmpeg安装和使用

1. 安装与环境配置 Windows # 方法1&#xff1a;官网下载预编译二进制包 https://ffmpeg.org/download.html#build-windows 解压后添加bin目录到系统PATH# 方法2&#xff1a;通过Chocolatey安装 choco install ffmpegmacOS # 使用Homebrew安装 brew install ffmpegLinux # …...

基于多模态大模型的ATM全周期诊疗技术方案

基于多模态大模型的ATM全周期诊疗技术方案 1. 数据预处理模块 算法1:多模态数据融合伪代码 def multimodal_fusion(data_dict):# 输入:包含MRI、EEG、实验室指标的字典# 输出:对齐后的张量序列# 模态对齐aligned_data = temporal_alignment(data_dict,sampling_rate...

写时复制Copy-on-Write(COW)

简单理解写时复制 读的时候&#xff0c;直接访问原对象。 写的时候&#xff0c;对复制原对象&#xff0c;对副本进行写操作&#xff0c;最后将副本替换原对象。 写时复制多用于读多写少的场景&#xff0c;因为写操作是用悲观锁进行的&#xff0c;如果写的场景多&#xff0c;…...

S7-1200 PLC热电偶和热电阻模拟量模块

热电偶和热电阻模拟量模块 S7-1200 PLC有专用用于对温度进行采集的热电偶模块SM1231 TC和SM 1231RTD。热电偶模块有4AI和8AI两种&#xff0c;下面以SM1231 TC 4AI为例看一下接线图。 该模块一共有4个通道&#xff0c;每个通道有两个接线端子&#xff0c;比如0&#xff0c;0-。…...

ffmpeg函数简介(封装格式相关)

文章目录 &#x1f31f; 前置说明&#xff1a;FFmpeg 中 AVFormatContext 是什么&#xff1f;&#x1f9e9; 1. avformat_alloc_context功能&#xff1a;场景&#xff1a; &#x1f9e9; 2. avformat_open_input功能&#xff1a;说明&#xff1a;返回值&#xff1a; &#x1f9…...

操作数组的工具类

Arrays 它里面的每一个方法基本上都是static静态修饰的&#xff0c;如果想要调用里面的方法&#xff0c;不需要创建对象&#xff0c;直接用类名.就可以了 操作数组的工具类 方法&#xff1a; public static String toString&#xff08;数组&#xff09; 把数组拼接成…...

小刚说C语言刷题——第19讲 循环之continue和break

在循环中&#xff0c;当我们得到想要的答案时&#xff0c;这时我们可能要提前结束循环&#xff0c;这个时候我们就会用到break。而我们有时需要结束某一次循环时&#xff0c;我们可以用continue。 1.break语句 (1)在循环中想要提前终止循环&#xff0c;要用break。 (2)语法格…...

FairMOT复现过程中cython_bbox库问题

cython_bbox库就该这么安装_cython-bbox库就应该-CSDN博客...

记录学习的第二十四天

还是每日一题。 题解很巧&#xff0c;我根本想不到。 class Solution { public: int minOperations(vector<int>& nums, int k) { int count; int mnnums[0]; //接下来查找nums数组中最小值 for(int i1;i<nums.size();i) { if(nums[i]<mn) { mnnums[i]; } } …...

Kubernetes 入门篇之网络插件 calico 部署与安装

在运行kubeadm init 和 join 命令部署好master和node节点后&#xff0c;kubectl get nodes 看到节点都是NotReady状态&#xff0c;这是因为没有安装CNI网络插件。 kubectl get nodes NAME STATUS ROLES AGE VERSION k8s-master Not…...

HTTP 压力测试工具autocannon(AI)

简介 autocannon 是一款基于 Node.js 的高性能 HTTP 压力测试工具&#xff0c;适用于评估 Web 服务的并发处理能力和性能瓶颈。 一、工具特点 高性能‌&#xff1a;利用 Node.js 异步非阻塞机制模拟高并发请求‌。‌实时监控‌&#xff1a;测试过程中动态展示请求统计和性能…...

【面试】封装、继承、多态的具象示例 模板编程的理解与应用场景 链表适用的场景

文章目录 C面试&#xff1a;封装、继承、多态的具象示例1. 封装 (Encapsulation)2. 继承 (Inheritance)3. 多态 (Polymorphism)综合示例&#xff1a;封装、继承、多态 C模板编程的理解与应用场景我对模板编程的理解C中最常用的模板编程场景1. STL (标准模板库)2. 通用容器实现3…...

机器学习02——概要

一、简介 机器学习是一门在没有明确编程的情况下让计算机学习的科学。 监督学习是有目标的&#xff0c;输入数据对应明确的输出&#xff1b;无监督学习则是“探索”型的&#xff0c;模型的目标是从数据中发现潜在的模式或结构&#xff0c;而不需要预先知道标签。 二、机器学…...

常用的网络安全靶场、工具箱

转载&#xff1a;https://blog.csdn.net/zjzqxzhj/article/details/137945444 打CTF很好玩。可以试一下 1.CTF在线工具 1、CTF在线工具箱&#xff1a;http://ctf.ssleye.com/ 包含CTF比赛中常用的编码、加解密、算法。 2、CTF加解密工具箱&#xff1a;http://www.atoolbox.…...

excel中的VBA指令示例(一)

示例注释&#xff1a; Sub 宏1() sub是宏开头&#xff0c;宏1是宏的名称&#xff0c;自定义&#xff0c;在按钮中可指定用某个宏 后面是注释 Sheets("装配材料").Select ‘选择表 装配材料 Ce…...

神经网络 | 基于脉冲耦合神经网络PCNN图像特征提取与匹配(附matlab代码)

内容未发表论文基于脉冲耦合神经网络(PCNN)的图像特征提取与匹配研究 摘要 本文提出一种基于脉冲耦合神经网络(Pulse-Coupled Neural Network, PCNN)的图像特征提取与匹配方法。通过模拟生物视觉皮层神经元的脉冲同步发放特性,PCNN能够有效捕捉图像纹理与边缘特征。实验表…...

Linux 内核中的 TCP 早期多路分解机制解析

一、引言 在现代高性能网络环境中,Linux 内核需要快速处理大量的 TCP 数据包,同时保持低延迟和高吞吐量。为了实现这一目标,Linux 内核引入了 早期多路分解(Early Demultiplexing) 机制。这种机制允许内核在数据包进入传输层之前,快速找到对应的套接字(socket)并关联数…...

Yalmip工具箱(3)——错误类型

在yalmip中&#xff0c;不可避免地我们会遇到求解出问题的情况&#xff0c;理解和处理错误信息是至关重要的环节。在这里我们查看yalmip的所有错误类型&#xff08;详细见 yalmiperror.m 函数&#xff09; 函数概述 yalmiperror函数的主要作用是根据YALMIP产生的错误代码&…...

【KWDB 创作者计划】_KWDB:开源引领数据库创新变革

在数字化浪潮汹涌澎湃的当下&#xff0c;数据已然成为驱动各行各业发展的核心要素。数据库作为数据管理的关键工具&#xff0c;其性能、功能以及开放性&#xff0c;对企业和社会的数字化进程起着举足轻重的作用。KWDB&#xff0c;作为数据库领域的一颗璀璨新星&#xff0c;正以…...

HarmonyOS学习 实验八:显式动画与属性动画的实现

鸿蒙系统动画开发实战&#xff1a;显式动画与属性动画的探索 引言 在鸿蒙系统的开发过程中&#xff0c;动画效果是提升用户体验的重要一环。通过巧妙运用动画&#xff0c;可以使应用界面更加生动、交互更加流畅。鸿蒙系统提供了丰富的动画开发能力&#xff0c;其中显式动画和…...

高校智慧能源系统解决方案:推动绿色校园建设的智能化实践

高校智慧能源系统解决方案&#xff1a;推动绿色校园建设的智能化实践 一、建设背景&#xff1a;政策驱动与绿色发展需求 为响应国家“碳达峰、碳中和”战略目标&#xff0c;教育部印发《绿色低碳发展国民教育体系建设实施方案》&#xff0c;明确提出需完善校园能源管理体系&a…...

win日志

以第一个为例子 打开后&#xff0c;右上角&#xff08;将所有事件另存为xx)然后一般写今天的日期&#xff0c;进行备份 然后选择下语言即可 日志备份时间的选择&#xff08;根据实际情况选择日志时间&#xff09; 点击右侧事件属性&#xff0c;然后xml视图即可 常见的安全事件…...

嵌入式开发之51单片机入门(一)与LED灯的故事

得而不惜就该死。 --小泽 继续傻冒开始&#xff0c;这次的傻冒之旅是关于嵌入式的51单片机开发&#xff0c;这个系列只讲程序开发逻辑&#xff0c;如需初始环境安装配置&#xff0c;建议移步B站江协科技大佬&#xff0c;本系列也是对大佬所讲内容的复刻&#xff0c;同时添加一…...

TCP 与 UDP

TCP 与 UDP 的区别&#xff08;重要&#xff09; 是否面向连接&#xff1a;UDP 在传送数据之前不需要先建立连接。而 TCP 提供面向连接的服务&#xff0c;在传送数据之前必须先建立连接&#xff0c;数据传送结束后要释放连接。是否是可靠传输&#xff1a;远地主机在收到 UDP 报…...

Linux:进程地址空间

在讲述本篇文章之前&#xff0c;我们先来看一段代码。 从上图输出可以看到&#xff0c;我们的子进程继承了父进程的全局变量val&#xff0c;当子进程中的val产生了修改时&#xff0c;父进程的val值并没有变化&#xff0c;但父子进程在打印val的地址时&#xff0c;会发现val的地…...

【Linux】Linux 操作系统 - 03 ,初步指令结尾 + shell 理解

文章目录 前言一、打包和压缩二、有关体系结构 (考)面试题 三、重要的热键四、shell 命令及运行原理初步理解五、本节命令总结总结 前言 本篇文章 , 笔者记录的笔记内容包含 : 基础指令 、重要热键 、shell 初步理解 、权限用户的部分问题 。 内容皆是重要知识点 , 需要认真理…...

华为数通不同级别的认证路径和要求是什么?

一、认证路径 HCIA&#xff1a;无需前置认证&#xff0c;通过一门考试&#xff08;代码H12-811&#xff09;即可拿证。 HCIP&#xff1a;建议先通过HCIA-Datacom&#xff0c;再选择子方向&#xff08;如高级路由、安全&#xff09;。 HCIE&#xff1a;最好有hcia/hcip的基础…...

电子电气架构 --- 新能源汽车电子电气系统功能需求

我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 周末洗了一个澡,换了一身衣服,出了门却不知道去哪儿,不知道去找谁,漫无目的走着,大概这就是成年人最深的孤独吧! 旧人不知我近况,新人不知我过…...