学习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 概念
- Mat 类 : Mat 类用来保存矩阵类型的数据信息。Mat 类分为 矩阵头和指向存储数据的矩阵指针两部分。矩阵头中包含矩阵的尺寸、存储方法、地址和引用次数等(eg:(h,w,c,a),jpg,0001,2 + p)。在 OpenCV 中复制和传递图像时,只是复制了矩阵头和指向存储数据的指针,而非存放矩阵数据,从而节省计算机资源。
- 创建 Mat类
// 创建 Mat类
cv::Mat a; // 创建一个名为a的矩阵头
a = cv::imread('1.jpg'); // 向a中赋值图像数据,a的矩阵指针指向图像数据
cv::Mat b = a; // 复制矩阵头,并命名为b// 用Mat 类只存储矩阵头和矩阵指针的优点?
// 通过a,b可以修改图像内容吗?
// 删除a对b有影响吗?
//
- 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);
- 通过 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 类的子类
- 使用默认构造函数方式创建Mat
cv::Mat::Mat(int rows,int cols,int type,const Scalar & s)
// cv::Mat::Mat();cv::Mat a;
- 根据输入矩阵尺寸和类型构造
cv::Mat::Mat( int rows,int cols,int type)cv::Mat a(1280,1280,CV_32FC512);
- 用 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通道矩阵
- 利用已有矩阵构造 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不受影响。
- 构造已有 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 类的赋值
- 在构造时赋值的方法
- 枚举法赋值示例
- 循环法赋值
- 类方法赋值
- 利用数组进行赋值示例
- 在构造时赋值的方法
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 补充。
- 枚举法赋值
这种赋值方式是将矩阵中所有的元素一一列举,并用数据流的形式赋值给 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);
- 循环法赋值
循环法赋值也是对矩阵中的每一个元素进行赋值,但是可以不在
声明变量的时候进行赋值,而且可以对矩阵中的任意部分进行赋值。在给矩阵每个元素赋值的时候,赋值函数中声明的变量类型要与矩阵定义时的变量类型相同,
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;}
}
- 类方法赋值
在 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);
- 利用数组进行赋值示例
这种赋值方式首先将需要存入 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 类支持的运算
- 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;
- 两个 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); //
- 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() // 矩阵的通道数
- 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;}
}
- 通过矩阵元素的地址定位方式访问元素
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. bool cv :: imwrite(const String& filename,
2. InputArray img,
3. Const std::vector<int>& params =std::vector<int>()
4. )• filename:保存图像的地址和文件名,包含图像格式。
• img:将要保存的 Mat 类矩阵变量。
• params:保存图片格式属性设置标志。
- 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 数据保存 参考:《OpenCV4快速入门》作者冯 振 郭延宁 吕跃勇 1 数据载入、显示与保存 1.1 概念 Mat 类 : Ma…...
echarts图表相关
echarts图表相关 echarts官网折线图实际开发场景一: echarts官网 echarts官网 折线图 实际开发场景一: 只有一条折线,一半实线,一半虚线。 option {tooltip: {trigger: "axis",formatter: (params: any) > {const …...
idea自动部署jar包到服务器Alibaba Cloud Toolkit
安装插件:Alibaba Cloud Toolkit 配置服务器: 服务器配置: 项目启动Shell脚本命令: projectpd-otb.jar echo 根据项目名称查询对应的pid pid$(pgrep -f $project); echo $pid echo 杀掉对应的进程,如果pid不存在,则不执行 if [ …...
奥利司他
https://m.baidu.com/bh/m/detail/ar_9900965142893895938 奥利司他(四氢脂抑素)是一种众所周知的胰腺和胃脂肪酶不可逆抑制剂 生物活性:奥利司他(四氢脂抑素)是一种众所周知的胰腺和胃脂肪酶不可逆抑制剂。奥利司…...
Element Plus 图标使用方式整理
Element Plus 图标使用方式整理 以下是 Element Plus 图标的所有使用方式,包含完整代码示例和总结表格: 1. 按需引入图标组件 适用场景:仅需少量图标时,按需导入减少打包体积 示例代码: <template><div>…...
链路聚合+vrrp
1.链路聚合 作用注意事项将多个物理接口(线路)逻辑上绑定在一起形成一条逻辑链路,起到叠加带宽的作用1.聚合接口必须转发速率一致。2.聚合设备两端必须一致 配置命令 方法一 [Huawei]interface Eth-Trunk 0----先创建聚合接口,…...
Dynamics 365 Business Central Register Customer Payment 客户付款登记
#Dynamics 365 BC ERP# #D365 ERP# #Navision 前言 在实施过程,经常给客户介绍的 给客户付款一般用Payment Journal. 在客户熟悉系统运行后,往往会推荐客户使用Register Customer Payment.用这个function 工作会快很多,但出错的机会也比较大…...
Odoo免费开源ERP:企业销售过程中出现的问题
在企业未上线Odoo免费开源ERP时,企业销售过程中会存在失误。比如,许多销售订单都有如下问题:不当的定价、向客户过多地询问、处理订单延误、错过发货日期等。这些问题源于企业三个未集成的信息系统:销售管理系统、库存系统和财务系…...
手撕unique_ptr 和 shareed_ptr
文章目录 unique_ptrshared_ptr unique_ptr template<class T> class Unique_ptr { private:T* ptrNULL; public://1、删除默认的拷贝构造函数Unique_ptr(Unique_ptr& u) delete;//2、删除默认的复制构造Unique_ptr& operator(Unique_ptr& u) delete; …...
工会考试的重点内容是什么
工会考试的内容通常涵盖以下几个方面: 1、政治理论: 主要考查考生对马克思主义基本原理、中国特色社会主义理论体系、党的基本路线、方针、政策等方面的掌握程度。题型通常包括选择题、判断题和论述题。 2、法律法规: 这部分主要涉及国家…...
网络稳定性--LCA+最大生成树+bfs1/dfs1找最小边
1.最大生成树去除重边,只要最大的边成树 2.LCA查最近公共祖先,然后询问的lca(x,y)ff,分别从x,y向上找最小边 3.bfs1/dfs1就是2.中向上找的具体实现 #include<bits/stdc.h> using namespace std; #define N 100011 typedef long long ll; typede…...
混合并行技术在医疗AI领域的应用分析(代码版)
混合并行技术(专家并行/张量并行/数据并行)通过多维度的计算资源分配策略,显著提升了医疗AI大模型的训练效率与推理性能。以下结合技术原理与医疗场景实践,从策略分解、技术对比、编排优化及典型案例等维度展开分析: 一、混合并行技术:突破单卡算力限制 1. 并行策略三维分…...
【C++面向对象】封装(上):探寻构造函数的幽微之境
每文一诗 💪🏼 我本将心向明月,奈何明月照沟渠 —— 元/高明《琵琶记》 译文:我本是以真诚的心来对待你,就像明月一样纯洁无瑕;然而,你却像沟渠里的污水一样,对这份心意无动于衷&a…...
每日算法-250409
这是我今天的算法学习记录。 2187. 完成旅途的最少时间 题目描述 思路 二分查找 解题过程 为什么可以使用二分查找? 问题的关键在于寻找一个最小的时间 t,使得在时间 t 内所有公交车完成的总旅途次数 sum 大于等于 totalTrips。 我们可以观察到时间的单…...
如何实现文本回复Ai ChatGPT DeepSeek 式文字渐显效果?前端技术详解(附完整代码)
个人开发的塔罗牌占卜小程序:【问问塔罗牌】 快来瞧瞧吧! 一、核心实现原理 我们通过三步实现这个效果: 逐字渲染:通过 JavaScript 定时添加字符 透明度动画:CSS 实现淡入效果 光标动画:伪元素 CSS 动画…...
CompletableFuture高级模式详解
目录 CompletableFuture高级模式详解 1. CompletableFuture基础概念 1.1 什么是CompletableFuture? 1.2 异步编程基础 1.3 CompletableFuture与Future的对比 2. 创建CompletableFuture 2.1 基本创建方法 2.2 使用异步方法创建 2.3 指定执行器 3. 转换和链式操作 3.…...
【AI开源大模型工具链ModelEngine】【01】应用框架-源码编译运行
ModelEngine提供从数据处理、知识生成,到模型微调和部署,以及RAG(Retrieval Augmented Generation)应用开发的AI训推全流程工具链。 GitCode开源地址:https://gitcode.com/ModelEngineGitee开源地址:https…...
linux下截图工具的选择
方案一 gnome插件Screenshot Tool(截屏) ksnip(图片标注) gnome setting设置图片的默认打开方式为ksnip就可以快捷的将Screenshot Tool截屏的图片打开进行标记了。 但是最近我发现Screenshot Tool的延迟截图功能是有问题的&…...
每天记录一道Java面试题---day36
事务的基本特性和隔离级别 回答重点 事务基本特性ACID分别是: - 原子性指的是一个事务中的操作要么全部成功,要么全部失败。 - 一致性指的是数据库总是一个一致性的状态转换到另一个一致性的状态。比如A转账给B100块钱,假设A只有 90块&…...
Qt音频采集:QAudioInput详解与示例
1. 简介 QAudioInput是Qt Multimedia模块中用于音频采集的核心类,能够从麦克风等输入设备实时获取原始音频数据(PCM格式)。本文将通过原理讲解和代码示例,帮助开发者快速掌握音频采集的核心技术。 2. 核心功能 支持多种音频格式&…...
rkmpp 解码 精简mpi_dec_test.c例程
rkmpp 解码流程(除 MPP_VIDEO_CodingMJPEG 之外) 源码 输入h264码流 输出nv12文件 /** Copyright 2015 Rockchip Electronics Co. LTD** Licensed under the Apache License, Version 2.0 (the "License");* you may not use this file exce…...
怎么构造思维链数据?思维链提示工程的五大原则
我来为您翻译这篇关于思维链提示工程的文章,采用通俗易懂的中文表达: 思维链(CoT)提示工程是生成式AI(GenAI)中一种强大的方法,它能让模型通过逐步推理来解决复杂任务。通过构建引导模型思考过程的提示,思维链能提高输出的准确性…...
网络安全之-信息收集
域名收集 域名注册信息 站长之家 https://whois.chinaz.com/ whois 查询的相关网站有:中国万网域名WHOIS信息查询地址: https://whois.aliyun.com/西部数码域名WHOIS信息查询地址: https://whois.west.cn/新网域名WHOIS信息查询地址: http://whois.xinnet.com/domain/whois/in…...
JdbcTemplate基本使用
JdbcTemplate概述 它是spring框架中提供的一个对象,是对原始繁琐的JdbcAPI对象的简单封装。spring框架为我们提供了很多的操作模板类。例如:操作关系型数据的JdbcTemplate和MbernateTemplate,操作nosql数据库的RedisTemplate,操作消息队列的…...
pnpm 中 Next.js 模块无法找到问题解决
问题概述 项目在使用 pnpm 管理依赖时,出现了 “Cannot find module ‘next/link’ or its corresponding type declarations” 的错误。这是因为 pnpm 的软链接机制在某些情况下可能导致模块路径解析问题。 问题诊断 通过命令 pnpm list next 确认项目已安装 Next.js 15.2.…...
openEuler24.03 LTS下安装Spark
目录 安装模式介绍 下载Spark 安装Local模式 前提条件 解压安装包 简单使用 安装Standalone模式 前提条件 集群规划 解压安装包 配置Spark 配置Spark-env.sh 配置workers 分发到其他机器 启动集群 简单使用 关闭集群 安装YARN模式 前提条件 解压安装包 配…...
蓝桥杯真题——接龙序列
蓝桥杯2023年第十四届省赛真题-接龙数列 题目描述 对于一个长度为 K 的整数数列:A1, A2, . . . , AK,我们称之为接龙数列当且仅当 Ai 的首位数字恰好等于 Ai−1 的末位数字 (2 ≤ i ≤ K)。 例如 12, 23, 35, 56, 61, 11 是接龙数列;12, 2…...
使用 DeepSeek API 实现新闻文章地理位置检测与地图可视化
使用 DeepSeek API 实现新闻文章地理位置检测与地图可视化 | Implementing News Article Location Detection and Map Visualization with DeepSeek API 作者:zhutoutoutousan | Author: zhutoutoutousan 发布时间:2025-04-08 | Published: 2025-04-08 标…...
如何精准控制大模型的推理深度
论文标题 ThinkEdit: Interpretable Weight Editing to Mitigate Overly Short Thinking in Reasoning Models 论文地址 https://arxiv.org/pdf/2503.22048 代码地址 https://github.com/Trustworthy-ML-Lab/ThinkEdit 作者背景 加州大学圣迭戈分校 动机 链式推理能显…...
【力扣hot100题】(078)跳跃游戏Ⅱ
好难啊,我愿称之为跳崖游戏。 依旧用了两种方法,一种是我一开始想到的,一种是看答案学会的。 我自己用的方法是动态规划,维护一个数组记录到该位置的最少步长,每遍历到一个位置就嵌套循环遍历这个位置能到达的位置&a…...
