在MacOS上Qt配置OpenCV并进行测试
目录
一.Qt环境准备
二.在Qt项目中加载Opencv库并编写代码测试
1.使用Opencv加载图片
(1)在Qt中创建一个新项目
(2)在.pro文件中链接OpenCV库
(3)添加新资源文件
(4)在mainwindow.cpp中编写代码在窗口加载图片
(5)代码中使用的OpenCV函数分析
1)cv::imdecode()函数
2)cv::namedWindow()函数
3)cv::imshow()函数
4)cv::waitKey()函数
5)cv::destroyWindow()函数
2.使用Opencv加载视频
(1)使用Qt创建一个新项目
(2)在.pro文件中链接OpenCV库
(3)在mainwindow.cpp中编写代码
(4)代码中使用的OpenCV函数分析
1)cv::VideoCapture
参考文档:
一.Qt环境准备
上一篇博客我讲了如何下载配置OpenCV库,但是在Qt5.15.2使用OpenCV库时,出现了一个问题就是我下载的Qt5.15.2是x86架构的,不能对OpenCV库进行链接,而OpenCV库是arm架构的
直接使用Qt5.15.2编译链接OpenCV库链接头文件是可以的,但是使用OpenCV代码就不能成功链接编译了

因此需要下载Qt6.3.1版本的, Qt6.3.1版本是arm架构的

下载完成后打开Qt Creator在Qt版本里面加入Qt6.3.1的qmake
一般是在下载的Qt版本文件bin目录下

再在构建配套(Kit)中加入Qt6.3.1版本的构建配套

这样Qt环境就搭建好了
二.在Qt项目中加载Opencv库并编写代码测试
1.使用Opencv加载图片
(1)在Qt中创建一个新项目




选择Qt6.3.1(arm)


(2)在.pro文件中链接OpenCV库

#链接OpenCV头文件
INCLUDEPATH +=/usr/local/include/
INCLUDEPATH +=/usr/local/include/opencv4/
INCLUDEPATH +=/usr/local/include/opencv4/opencv2
#链接OpenCV库文件
LIBS += -L/usr/local/lib -lopencv_gapi \-lopencv_stitching -lopencv_aruco -lopencv_bgsegm -lopencv_bioinspired \-lopencv_ccalib -lopencv_dnn_objdetect -lopencv_dnn_superres -lopencv_dpm \-lopencv_highgui -lopencv_face -lopencv_freetype -lopencv_fuzzy -lopencv_hfs \-lopencv_img_hash -lopencv_line_descriptor -lopencv_quality -lopencv_reg \-lopencv_rgbd -lopencv_saliency -lopencv_sfm -lopencv_stereo -lopencv_structured_light \-lopencv_phase_unwrapping -lopencv_superres -lopencv_optflow -lopencv_surface_matching \-lopencv_tracking -lopencv_datasets -lopencv_text -lopencv_dnn -lopencv_plot \-lopencv_videostab -lopencv_videoio -lopencv_xfeatures2d -lopencv_shape -lopencv_ml \-lopencv_ximgproc -lopencv_video -lopencv_xobjdetect -lopencv_objdetect \-lopencv_calib3d -lopencv_imgcodecs -lopencv_features2d -lopencv_flann -lopencv_xphoto \-lopencv_photo -lopencv_imgproc -lopencv_core
(3)添加新资源文件





(4)在mainwindow.cpp中编写代码在窗口加载图片
#include "ui_mainwindow.h"
#include <opencv2/opencv.hpp>
#include <QDebug>
#include <QFile>
MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{ui->setupUi(this);//以只读的方式打开图片文件QFile file(":/img/tree.jpg");if(!file.open(QFile::ReadOnly)) {qDebug() << "打开图片失败";}//将整个图片文件内容读取到一个 QByteArray 对象中QByteArray photo = file.readAll();cv::Mat img = cv::imdecode(std::vector<char>(photo.begin(), photo.end()), cv::IMREAD_COLOR);//判定图片是否加载成功if(img.empty()){qDebug() << "没有找到照片";}cv::namedWindow("tree", cv::WINDOW_AUTOSIZE);cv::imshow("tree", img);cv::waitKey(0); //cv::waitKey(10000);cv::destroyWindow("tree");
}MainWindow::~MainWindow()
{delete ui;
}
运行结果:

(5)代码中使用的OpenCV函数分析
1)cv::imdecode()函数
//cv::Mat是OpenCV用于处理所有图像类型的结构
//cv::imdecode() 函数将 QByteArray 转换为 OpenCV 的图像格式 cv::Mat,以便进一步处理,cv::IMREAD_COLOR表示以彩色模式加载图像cv::Mat img = cv::imdecode(std::vector<char>(photo.begin(), photo.end()), cv::IMREAD_COLOR);
函数原型:
Mat cv::imdecode (InputArray buf, int flags);
Mat cv::imdecode (InputArray buf, int flags, Mat *dst);
函数功能: 从内存的缓存区中读取图片
参数: buf:一个数组或字节数组flags:用来指定图像加载的标志,通过这个参数,可以控制图像加载的一些行为和选项下面是falgs的枚举类型:enum cv::ImreadModes {cv::IMREAD_UNCHANGED = -1, //按图像原样加载图像cv::IMREAD_GRAYSCALE = 0, //以灰度模式加载图像cv::IMREAD_COLOR = 1, //以彩色模式加载图像cv::IMREAD_ANYDEPTH = 2, //以原始深度加载图像cv::IMREAD_ANYCOLOR = 4, //以任意颜色模式加载图像,返回一个3通道图像cv::IMREAD_LOAD_GDAL = 8, //使用gdal驱动程序加载图像 cv::IMREAD_REDUCED_GRAYSCALE_2 = 16, //将图像转换为单通道灰度图像,图像尺寸减小1/2cv::IMREAD_REDUCED_COLOR_2 = 17, //图像转换为3通道BGR彩色图像,图像大小减少1/2cv::IMREAD_REDUCED_GRAYSCALE_4 = 32, //将图像转换为单通道灰度图像,图像尺寸减小1/4cv::IMREAD_REDUCED_COLOR_4 = 33, //将图像转换为3通道BGR彩色图像,图像大小减少1/4cv::IMREAD_REDUCED_GRAYSCALE_8 = 64, //将图像转换为单通道灰度图像,图像尺寸减小1/8cv::IMREAD_REDUCED_COLOR_8 = 65, //将图像转换为3通道BGR彩色图像,图像大小减少1/8cv::IMREAD_IGNORE_ORIENTATION = 128 //不根据EXIF的方向标志旋转图像(EXIF(Exchangeable Image File Format)是一种图像文件格式,用于存储数字图像中的元数据信息,例如相机设置、拍摄日期和时间、地理位置等。)}dst(可选):用于接收解码后的图像数据
返回值:成功: 一个Mat类型的值失败: NULL
例子:
cv::Mat image; // 定义用于存储解码后图像的 cv::Mat 对象 cv::imdecode(buffer, flags, &image);通过传递
&image给cv::imdecode()函数的dst参数,解码后的图像数据将直接存储在image中也可以不使用第三个参数,直接使用返回值
cv::Mat image; // 定义用于存储解码后图像的 cv::Mat 对象 image = cv::imdecode(buffer, flags);
2)cv::namedWindow()函数
//cv::namedWindow():函数将会在屏幕上打开一个窗口,窗口名为tree,cv::WINDOW_AUTOSIZE是窗口的属性:窗口的大小与载入的图片大小一致,图片会被缩放大小来适应窗口大小cv::namedWindow("tree", cv::WINDOW_AUTOSIZE);
函数原型:
void cv::namedWindow(const String &winname,int flags = WINDOW_AUTOSIZE);
函数功能:函数namedWindow创建一个窗口,该窗口可用作图像和跟踪条的占位符。创建的窗口通过窗口名称来引用
参数:winname: 窗口标题,也是用于窗口标识符的窗口名称flags: 窗口标志下面是falgs的枚举类型:enum cv::WindowFlags {cv::WINDOW_NORMAL = 0x00000000, //用户可以调整窗口的大小(没有限制)/也可以将全屏窗口切换到正常大小cv::WINDOW_AUTOSIZE = 0x00000001, //用户无法调整窗口大小,窗口大小受显示图像的限制cv::WINDOW_OPENGL = 0x00001000, //支持opengl的窗口cv::WINDOW_FULLSCREEN = 1, //将窗口改为全屏cv::WINDOW_FREERATIO = 0x00000100, //图像尽可能地扩展(没有比例限制)cv::WINDOW_KEEPRATIO = 0x00000000, //保持图像原有的比例cv::WINDOW_GUI_EXPANDED =0x00000000, //状态栏和工具栏cv::WINDOW_GUI_NORMAL = 0x00000010 //默认的窗口模式,会在图像显示时以普通窗口的形式呈现,并提供基本的窗口操作,如调整大小、移动和关闭}
返回值:无返回值
3)cv::imshow()函数
//cv::imshow():函数将会创建一个窗口(如果这个窗口不存在,会自动调用cv::namedWindow()函数来新建一个窗口),调用cv::imshow()会将指定的图片绘制在窗口上cv::imshow("tree", img);
函数原型:
void cv::imshow(const String &winname, InputArray mat);
函数功能: 在指定窗口中显示图像
参数: winname: 指定的窗口对象mat: 展示的图像
返回值: 无返回值
4)cv::waitKey()函数
//cv::waitKey():系统暂停并等待键盘事件发生(如果传入的参数值大于零,就会等待该值的毫秒时间(如果在等待时间中有键盘事件发生,会立马继续执行后面的程序),然后继续执行后面程序,如果参数设置为0或负数,程序将会无限等待,直到有键盘事件发生)cv::waitKey(0); //cv::waitKey(10000);
函数原型:
int cv::waitKey (int delay = 0);
函数功能: 等待键盘事件发生
参数: delay: 以毫秒为单位的延迟。0是代表“永远”的特殊值
返回值:返回按下的键的代码,如果在指定时间之前没有按下键,则返回-1
5)cv::destroyWindow()函数
//cv::destroyWindow() 关闭指定的窗口并释放相关内存空间cv::destroyWindow("tree");
函数原型:
void cv::destroyWindow(const String &winname);
函数功能: 销毁指定的窗口
参数:winname: 要销毁的窗口名称
返回值:无返回值
2.使用Opencv加载视频
(1)使用Qt创建一个新项目







(2)在.pro文件中链接OpenCV库

#链接OpenCV头文件
INCLUDEPATH +=/usr/local/include/
INCLUDEPATH +=/usr/local/include/opencv4/
INCLUDEPATH +=/usr/local/include/opencv4/opencv2
#链接OpenCV库文件
LIBS += -L/usr/local/lib -lopencv_gapi \-lopencv_stitching -lopencv_aruco -lopencv_bgsegm -lopencv_bioinspired \-lopencv_ccalib -lopencv_dnn_objdetect -lopencv_dnn_superres -lopencv_dpm \-lopencv_highgui -lopencv_face -lopencv_freetype -lopencv_fuzzy -lopencv_hfs \-lopencv_img_hash -lopencv_line_descriptor -lopencv_quality -lopencv_reg \-lopencv_rgbd -lopencv_saliency -lopencv_sfm -lopencv_stereo -lopencv_structured_light \-lopencv_phase_unwrapping -lopencv_superres -lopencv_optflow -lopencv_surface_matching \-lopencv_tracking -lopencv_datasets -lopencv_text -lopencv_dnn -lopencv_plot \-lopencv_videostab -lopencv_videoio -lopencv_xfeatures2d -lopencv_shape -lopencv_ml \-lopencv_ximgproc -lopencv_video -lopencv_xobjdetect -lopencv_objdetect \-lopencv_calib3d -lopencv_imgcodecs -lopencv_features2d -lopencv_flann -lopencv_xphoto \-lopencv_photo -lopencv_imgproc -lopencv_core
(3)在mainwindow.cpp中编写代码
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <QDebug>
MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{ui->setupUi(this);//新建一个窗口,窗口名为scenery,窗口模式为cv::WINDOW_AUTOSIZEcv::namedWindow("scenery", cv::WINDOW_AUTOSIZE);cv::VideoCapture cap; //cv::VideoCapture类型用于打开视频文件//打开指定的视频文件if(!cap.open("/Users/liwanyu/Downloads/opencvDemo/day1/video/videoload/video/scenery.mp4")){qDebug() << "打开视频文件失败";}//打开网络视频//cap.open("https://vd2.bdstatic.com/mda-njqbvdg1h8kdqez1/720p/h264/1666686182583726512/mda-njqbvdg1h8kdqez1.mp4?v_from_s=hkapp-haokan-hna&auth_key=1703093507-0-0-fc2c4688c205be7eedb5e09162e45f57&bcevod_channel=searchbox_feed&pd=1&cr=2&cd=0&pt=3&logid=1907408427&vid=14746953470406117750&klogid=1907408427&abtest=");cv::Mat frame; //用于保存视频帧//在while循环中循环播放视频while(1){//视频文件按照帧从视频流中读出来,每33毫秒换帧,如果在这33毫秒中有键盘事件发生就退出视频帧播放cap.read(frame); //cap >> frameif(frame.empty()){break;}cv::imshow("scenery", frame);if(cv::waitKey(33)>=0){break;}}cv::destroyWindow("scenery"); //关闭指定的窗口并销毁其内存空间
}MainWindow::~MainWindow()
{delete ui;
}
运行结果:

(4)代码中使用的OpenCV函数分析
1)cv::VideoCapture
cv::VideoCapture
功能:用于从视频文件、图像序列或相机中捕获视频的类
Public Member Functions:
默认的空构造:
cv::VideoCapture::VideoCapture();
重载的构造:
cv::VideoCapture::VideoCapture(const String &filename, int apiPreference = CAP_ANY);功能:
打开视频文件或捕获摄像头设备或IP视频流(网络传输视频流),默认使用API首选项(CAP_ANY)进行视频捕获
参数:
filename:要打开的视频文件名、捕获设备的索引号(一般为0表示默认摄像头),或者是 IP 视频流地址
apiPreference:可选参数,用于指定视频捕获 API 的首选项。默认值为
CAP_ANY,表示尝试使用任何可用的视频捕获 API 来打开
cv::VideoCapture::VideoCapture(const String &filename, int apiPreference, const std::vector<int> ¶ms);功能:
打开视频文件或捕获摄像头设备或IP视频流(网络传输视频流),默认使用API首选项(CAP_ANY)进行视频捕获
参数:
filename:要打开的视频文件名、捕获设备的索引号(一般为0表示默认摄像头),或者是 IP 视频流地址
apiPreference:可选参数,用于指定视频捕获 API 的首选项。默认值为
CAP_ANY,表示尝试使用任何可用的视频捕获 API 来打开params:可选不定参数,以向底层视频捕获库传递附加的特定参数
例如:
cv::VideoCapture cap("video.mp4", cv::CAP_FFMPEG, {cv::CAP_PROP_FRAME_WIDTH, 640, cv::CAP_PROP_FRAME_HEIGHT, 480});在此示例中,传递了一组参数来设置所捕获视频帧的宽度和高度。使用了
cv::CAP_PROP_FRAME_WIDTH和cv::CAP_PROP_FRAME_HEIGHT,这些常量表示帧的宽度和高度属性,然后将期望的值分别设置为 640 和 480。这意味着设置了捕获的每个视频帧的宽度为 640 像素,高度为 480 像素。
cv::VideoCapture::VideoCapture(int index, int apiPreference = CAP_ANY);功能:
打开摄像机进行视频捕获
参数:
index:捕获设备的索引号,用于指定要打开的特定设备。通常情况下,0 表示默认摄像头,1 表示第二个摄像头,以此类推。如果你的系统上有多个摄像头或其他捕获设备,可以通过指定不同的索引号来选择打开哪个设备
apiPreference:可选参数,用于指定视频捕获 API 的首选项。默认值为
CAP_ANY,表示尝试使用任何可用的视频捕获 API 来打开
cv::VideoCapture::VideoCapture(int index, int apiPreference = CAP_ANY, int apiPreference, const std::vector<int> ¶ms);功能:
使用API首选项和不定参数打开摄像机进行视频捕获。
参数:
index:捕获设备的索引号,用于指定要打开的特定设备。通常情况下,0 表示默认摄像头,1 表示第二个摄像头,以此类推。如果你的系统上有多个摄像头或其他捕获设备,可以通过指定不同的索引号来选择打开哪个设备
apiPreference:可选参数,用于指定视频捕获 API 的首选项。默认值为
CAP_ANY,表示尝试使用任何可用的视频捕获 API 来打开params:可选不定参数,以向底层视频捕获库传递附加的特定参数
默认的析构函数:
virtual cv::VideoCapture::~VideoCapture();
其他成员函数:
virtual double cv::VideoCapture::get(int propld) const;功能:
返回指定的VideoCapture属性
参数:
propld:要获取属性的标识符(例如,如果
propId为CV_CAP_PROP_FRAME_WIDTH,则该函数将返回输入视频流的帧宽度)返回值:
返回值类型为
double,表示所请求属性的当前值
String cv::VideoCapture::getBackendName()const;功能:
用于返回使用的视频捕获后端API的名称
参数:
无参数
返回值:
成功:String类型的后端API名称
失败:NULL
bool cv::VideoCapture::getExceptionMode();功能:
用于获取异常模式的状态
参数:
无参数
返回值:
返回
true,则表示异常模式已启用,即当发生错误时,将抛出异常返回
false,则表示异常模式已禁用,即当发生错误时,不会抛出异常,而是通过错误码或其他方式通知用户
virtual bool cv::VideoCapture::grab();功能:
用于从输入视频流中抓取一帧图像,但不将其解码
参数:
无参数
返回值:
返回
true,则表示成功抓取了一帧图像返回
false,则表示未能成功抓取图像
virtual bool cv::VideoCapture::isOpened()const;功能:
用于检查当前视频捕获对象是否成功打开了视频文件或设备
参数:
无参数
返回值:
返回
true,则表示视频捕获对象已成功打开,并且可以从该对象读取视频帧返回
false,则表示视频捕获对象无法打开,可能是由于文件路径错误、设备未连接或者不支持的格式等原因
用于打开视频文件或设备的open函数:(open函数的参数和cv::VideoCapture:构造函数的参数一样就不再解释了)
virtual bool cv::VideoCapture::open(const String &filename, int apiPreference = CAP_ANY); virtual bool cv::VideoCapture::open(const String &filename, int apiPreference, const std::vector<int> ¶ms); virtual bool cv::VideoCapture::open(int index, int apiPreference = CAP_ANY); virtual bool cv::VideoCapture::open(int index, int apiPreference = CAP_ANY, int apiPreference, const std::vector<int> ¶ms);
重载的运算符函数:
virtual VideoCapture &operator>>(Mat &image);功能:
用于从视频流中读取一帧图像并将其存储到提供的
Mat对象中参数:
image:要存储读取帧的Mat对象。它将存储从视频流中读取的图像数据
virtual VideoCapture &operator>>(UMat &image);功能:
用于从视频流中读取一帧图像并将其存储到提供的
UMat对象中参数:
image:要存储读取帧的UMat对象。它将存储从视频流中读取的图像数据
virtual bool cv::VideoCapture::read(OutputArray image);功能:
用于从视频流中读取一帧图像并将其存储在提供的
OutputArray对象中参数:
image:要存储读取帧的OutputArray对象。它可以是Mat、UMat或其他可接受输出图像数据的对象类型返回值:
返回
true,则表示成功读取到一帧图像,并将其存储在提供的OutputArray对象中
返回false,则表示未能成功读取图像,可能是由于视频结束、读取错误或其他原因
virtual void cv::VideoCapture::release();功能:
用于释放视频捕获对象所占用的资源
参数:
无参数
返回值:
无返回值
virtual bool cv::VideoCapture::retrieve(OutputArray image, int flag=0);功能:
用于解码和获取当前抓取的视频帧
参数:
image:要存储解码后图像的
OutputArray对象。它可以是Mat、UMat或其他可接受输出图像数据的对象类型falg:可选参数,用于指定附加的操作标志。默认值为0
返回值:
返回
true,则表示成功解码当前抓取的视频帧,并将其存储在提供的OutputArray对象中返回
false,则表示未能成功解码视频帧
virtual bool cv::VideoCapture::set(int propId, double value);功能:
用于设置视频捕获对象的属性值
参数:
propId:要设置的属性的标识符。可以使用不同的标识符来设置不同的属性值。例如,如果propId为CV_CAP_PROP_FRAME_WIDTH,则代表设置输入视频流的帧宽度
value:要设置的属性值返回值:
返回
true,则表示成功设置属性的值返回
false,则表示无法设置属性的值,可能是由于不支持的属性或其他原因
void cv::VideoCapture::setExceptionMode(bool enable);功能:
用于设置异常模式的状态
参数:
enable:一个
bool值,表示是否启用异常模式。如果enable为true,则启用异常模式,即当发生错误时,将抛出异常 ;如果enable为false,则禁用异常模式,即当发生错误时,不会抛出异常,而是通过错误码或其他方式通知用户返回值:
无返回值
静态成员函数:
static bool cv::VideoCapture::waitAny(const std::vector< VideoCapture > &streams, std::vector< int > &readyIndex, int64 timeoutNs=0);功能:
静态成员函数,用于等待多个视频捕获对象中至少一个准备就绪(有可读取的帧)
参数:
streams:一个包含多个VideoCapture对象的std::vector,表示要等待的视频捕获对象列表。
readyIndex:一个空的std::vector<int>,用于存储准备就绪的视频捕获对象的索引。准备就绪的对象即有可读取的帧。
timeoutNs:可选参数,以纳秒为单位指定的超时时间。默认值为0,表示无限等待返回值:
返回
true,则表示至少一个视频捕获对象已准备就绪。返回
false,则表示在超时时间内没有可用的视频捕获对象
友元类:
friend class internal::VideoCapturePrivateAccessor
参考文档:
OpenCV: Image file reading and writing
OpenCV: High-level GUI
OpenCV: cv::VideoCapture Class Reference
相关文章:
在MacOS上Qt配置OpenCV并进行测试
目录 一.Qt环境准备 二.在Qt项目中加载Opencv库并编写代码测试 1.使用Opencv加载图片 (1)在Qt中创建一个新项目 (2)在.pro文件中链接OpenCV库 (3)添加新资源文件 (4)在mainw…...
java数据结构与算法刷题-----LeetCode167:两数之和 II - 输入有序数组
java数据结构与算法刷题目录(剑指Offer、LeetCode、ACM)-----主目录-----持续更新(进不去说明我没写完):https://blog.csdn.net/grd_java/article/details/123063846 思路 题目要求我们找到两个数相加的和,等于target指定的值。而…...
Linux:jumpserver V3的安装与升级(在线离线)(2)
官方文档写的非常详细,我这篇文章时间长了,会随着官方版本更新而落后 JumpServer - 开源堡垒机 - 官网https://www.jumpserver.org/安装和升级在官网也有详细的信息,我写本章是为了记录一下实验 我的系统是centos7.9 在线安装 在确定我们可…...
【GoLang】Go语言几种标准库介绍(一)
你见过哪些令你膛目结舌的代码技巧? 文章目录 你见过哪些令你膛目结舌的代码技巧?前言几种库bufio(带缓冲的 I/O 操作)特性示例 bytes (实现字节操作)特性示例 总结专栏集锦写在最后 前言 随着计算机科学的迅猛发展,编…...
短剧分销系统:月入百w的新模式
随着我国短剧的高速发展,越来越多的人进入到了短剧影视行业。本文旨在介绍短剧市场的发展前景以及短剧分销系统的设计和开发。 一、短剧发展背景 短剧具有时长短、剧情紧凑、节奏快、剧情新颖等特点,满足了国内观众的碎片化时间,在当下短视频…...
鞋服用户运营策略如何实现有效闭环?
实现长期价值和业务闭环是企业经营的关键。对于鞋服行业来说,如何基于客户旅程编排(Customer Journey Orchestration,简称 CJO)实现用户运营策略的有效闭环,提升长期价值呢? 本文围绕该主题,从鞋…...
简单工厂、工厂方法、抽象工厂和策略模式
摘要 本文简单介绍软件开发过程中面临的痛点和几个总体原则。详细介绍了简单工厂、工厂方法、抽象工厂和策略模式的实现,以及各种模式之间的相似、区别。 背景 开发面临哪些问题(痛点)? 相信做过大型软件开发的tx都遇到过以下类似…...
junit mocktio request打桩
Controller下request组装参数 HttpServletRequest request new MockHttpServletRequest(); ((MockHttpServletRequest) request).addHeader("router","login"); ((MockHttpServletRequest) request).addParameter("test","wwww"); …...
第十四节TypeScript 联合类型
1、简介 联合类型可以通过管道(|)将变量设置多种类型,赋值时可以根据设置的类型来赋值。 注意:只能赋值指定的类型,如果赋值其它类型就会报错的。 2、创建联合类型的语法格式: Type1|Type2|Type3 实例&a…...
[x86汇编语言]从实模式到保护模式第二版
下载汇编器:https://www.nasm.us/pub/nasm/releasebuilds/2.16.02rc6/win64/ mov ax, 0x3f add bx,ax add cx,ax 编译: C:\Users\HP>cd D:\BaiduNetdiskDownload\01b站\lizhong\myasm C:\Users\HP>D: D:\BaiduNetdiskDownload\01b站\lizhong…...
基本的逻辑门
前言 本篇文章介绍基本的逻辑门,然后给出C语言描述 逻辑门是在集成电路上的基本组件。简单的逻辑门可由晶体管组成。这些晶体管的组合可以使代表两种信号的高低电平在通过它们之后产生高电平或者低电平的信号。高、低电平可以分别代表逻辑上的“真”与“假”或二进…...
云原生系列3-Kubernetes
1、Kubernetes概述 k8s缩写是因为k和s之间有八个字符。k8s是基于容器技术的分布式架构方案。官网:https://kubernetes.io/zh-cn/ Google在 2014年开源了Kubernetes项目,Kubernetes是一个用于自动化部署、扩展和管理容器化应用程序的开源系统。同样类似的…...
R-列表、矩阵、数组转化为向量
目录 一、c()函数 二、unlist()函数 一、c()函数 c():对应的英文是combine. 当你使用c()函数时,它会将输入的对象连接成一个向量。因此,无论输入是矩阵、数组还是列表,c()函数都会将它们连接成一个简单的向量。因此ÿ…...
算法通关村-番外篇排序算法
大家好我是苏麟 , 今天带来番外篇 . 冒泡排序 BubbleSort 最基本的排序算法,最常用的排序算法 . 我们以关键字序列{26,53,48,11,13,48,32,15}看一下排序过程: 动画演示 : 代码如下 : (基础版) class Solution {public int[] sortArray(int[] nums) {for(int i …...
三种方式简单搭建http本地文件服务
有时候想写一个简单的html文件,然后加上一些image、js、css文件用于测试。希望有一个简单的http服务,总结了如下三种方式,欢迎讨论更多高效的方式。 (一)使用Web Server for Chrome浏览器扩展 之前写过一篇博文&#x…...
设计模式--适配器模式
实验8:适配器模式 本次实验属于模仿型实验,通过本次实验学生将掌握以下内容: 1、理解适配器模式的动机,掌握该模式的结构; 2、能够利用适配器模式解决实际问题。 [实验任务]:双向适配器 实现一个双向…...
Node.js教程-express框架
概述 Express是基于Node.js平台(建立在Node.js内置的http模块上),快速、开放、极简的Web开发框架。 中文官网 http://www.expressjs.com.cn/。 Github地址:https://github.com/orgs/expressjs。 Express核心特性: 可设置中间件来响应 HTTP…...
location.origin兼容
if (!window.location.origin) {window.location.origin window.location.protocol "//" window.location.hostname (window.location.port ? : window.location.port: );}...
spring boot集成mybatis和springsecurity实现权限控制功能
上一篇已经实现了登录认证功能,这一篇继续实现权限控制功能,文中代码只贴出来和上一篇不一样的修改的地方,完整代码可结合上一篇一起整理spring boot集成mybatis和springsecurity实现登录认证功能-CSDN博客 数据库建表 权限控制的意思就是根…...
按键修饰符
在键盘监听事件时,我们经常需要判断详细的按键,此时,可以为键盘相关的事件添加按键修饰符,例如: 键盘修饰符案例:...
DIY|Mac 搭建 ESP-IDF 开发环境及编译小智 AI
前一阵子在百度 AI 开发者大会上,看到基于小智 AI DIY 玩具的演示,感觉有点意思,想着自己也来试试。 如果只是想烧录现成的固件,乐鑫官方除了提供了 Windows 版本的 Flash 下载工具 之外,还提供了基于网页版的 ESP LA…...
WordPress插件:AI多语言写作与智能配图、免费AI模型、SEO文章生成
厌倦手动写WordPress文章?AI自动生成,效率提升10倍! 支持多语言、自动配图、定时发布,让内容创作更轻松! AI内容生成 → 不想每天写文章?AI一键生成高质量内容!多语言支持 → 跨境电商必备&am…...
10-Oracle 23 ai Vector Search 概述和参数
一、Oracle AI Vector Search 概述 企业和个人都在尝试各种AI,使用客户端或是内部自己搭建集成大模型的终端,加速与大型语言模型(LLM)的结合,同时使用检索增强生成(Retrieval Augmented Generation &#…...
springboot整合VUE之在线教育管理系统简介
可以学习到的技能 学会常用技术栈的使用 独立开发项目 学会前端的开发流程 学会后端的开发流程 学会数据库的设计 学会前后端接口调用方式 学会多模块之间的关联 学会数据的处理 适用人群 在校学生,小白用户,想学习知识的 有点基础,想要通过项…...
【Android】Android 开发 ADB 常用指令
查看当前连接的设备 adb devices 连接设备 adb connect 设备IP 断开已连接的设备 adb disconnect 设备IP 安装应用 adb install 安装包的路径 卸载应用 adb uninstall 应用包名 查看已安装的应用包名 adb shell pm list packages 查看已安装的第三方应用包名 adb shell pm list…...
Vue 模板语句的数据来源
🧩 Vue 模板语句的数据来源:全方位解析 Vue 模板(<template> 部分)中的表达式、指令绑定(如 v-bind, v-on)和插值({{ }})都在一个特定的作用域内求值。这个作用域由当前 组件…...
从物理机到云原生:全面解析计算虚拟化技术的演进与应用
前言:我的虚拟化技术探索之旅 我最早接触"虚拟机"的概念是从Java开始的——JVM(Java Virtual Machine)让"一次编写,到处运行"成为可能。这个软件层面的虚拟化让我着迷,但直到后来接触VMware和Doc…...
DAY 26 函数专题1
函数定义与参数知识点回顾:1. 函数的定义2. 变量作用域:局部变量和全局变量3. 函数的参数类型:位置参数、默认参数、不定参数4. 传递参数的手段:关键词参数5 题目1:计算圆的面积 任务: 编写一…...
数据结构第5章:树和二叉树完全指南(自整理详细图文笔记)
名人说:莫道桑榆晚,为霞尚满天。——刘禹锡(刘梦得,诗豪) 原创笔记:Code_流苏(CSDN)(一个喜欢古诗词和编程的Coder😊) 上一篇:《数据结构第4章 数组和广义表》…...
raid存储技术
1. 存储技术概念 数据存储架构是对数据存储方式、存储设备及相关组件的组织和规划,涵盖存储系统的布局、数据存储策略等,它明确数据如何存储、管理与访问,为数据的安全、高效使用提供支撑。 由计算机中一组存储设备、控制部件和管理信息调度的…...



