c++视频图像处理
打开视频或摄像头
打开指定视频
/*VideoCapture(const String &filename, apiPreference);filename:读取的视频或者图像序列的名称apiPreference:读取数据时设置的属性*/
VideoCapture video; //定义一个空的视频对象
video.open("H:/BaiduNetdiskDownload/01.mp4");
// 判断视频有没有成功打开if (!video.isOpened()) {cout << "视频打开失败";return -1;}
打开摄像头
VideoCapture video(1); //打开一个摄像头
视频的相关操作
通过get获取视频数据
将视频流赋值给mat对象
Mat mat;video >> mat; bool isColor = (mat.type() == CV_8UC3); //判断视频是否为3通道彩色
输出视频的帧率
VideoWriter 视频写入
filename:保存视频的地址和文件名,包含视频格式
fourcc:压缩帧的4字符编解码器代码
fps:保存视频的帧率,即视频中每秒图像的张数
framSize:视频帧的尺寸
isColor:保存视频是否为彩色视频
VideoWriter writer;int codec = VideoWriter::fourcc('M', 'J', 'P', 'G'); //选择MJPG的编码格式double fps = 25.0; //设置视频的帧率string filename = "file.avi"; // 视频的名和格式writer.open(filename, codec, fps, mat.size(),isColor); //创建保存文件的视频流if (!writer.isOpened()) { // 判断视频流是否正常打开cout << "视频打开失败";return -1;}
捕捉摄像头中内容,写入倒视频中
#include <iostream>
#include <opencv2/opencv.hpp>
#include <opencv2/core.hpp>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/highgui.hpp>#pragma comment(lib,"opencv_world4100d.lib")using namespace std;
using namespace cv;int main(int argc, char** argv) {// 创建一个 VideoCapture 对象,参数 0 表示默认摄像头VideoCapture cap(0);// 检查摄像头是否成功打开if (!cap.isOpened()) {std::cerr << "Error: Could not open the camera." << std::endl;return -1;}// 获取摄像头的帧宽度和高度int frame_width = static_cast<int>(cap.get(cv::CAP_PROP_FRAME_WIDTH));int frame_height = static_cast<int>(cap.get(cv::CAP_PROP_FRAME_HEIGHT));double fps = cap.get(cv::CAP_PROP_FPS);// 帧率不能小于0if (fps <= 0) fps = 30.0;std::string output_file = "F:/output.avi";int fourcc = cv::VideoWriter::fourcc('X', 'V', 'I', 'D');cv::VideoWriter writer(output_file, fourcc, fps, cv::Size(frame_width, frame_height));if (!writer.isOpened()) {std::cerr << "Error: Could not open the output video file for write." << std::endl;return -1;}// 创建一个窗口来显示视频cv::namedWindow("Camera Feed", cv::WINDOW_AUTOSIZE);while (true) {cv::Mat frame;// 捕获一帧cap >> frame;// 检查帧是否为空if (frame.empty()) {std::cerr << "Error: Blank frame grabbed." << std::endl;break;}// 显示帧cv::imshow("Camera Feed", frame);writer.write(frame);// 检查是否按下了 'q' 键来退出循环if (cv::waitKey(10) == 'q') {break;}}// 释放摄像头并关闭所有窗口cap.release();writer.release();cv::destroyAllWindows();return 0;
}
颜色空间转换
三种存取数据的区间
- 8U–存储0-255的数据类型
- 32F–存储0-1(将0-1区间映射为0-255,大于1的部分映射为白色,小于0的部分映射为黑色)
- 64F–存储0-1
convertTo
m:输出图像
rtype:转换后数据类型
alpha:缩放系数
beta:平移系数
转换公式:alpha*I(x,y)+ beta
// 将0-255的图像转为0-1mat.convertTo(mat2, CV_32F, 1/255.0, 0);
RGB转灰度图公式:Gray=R0.3+G0.59+B*0.11
图像格式转换cvtColor
src:待转换颜色模型的原始图像
dst:转换颜色模型后的目标图像。
code:颜色空间转换的标志,如由RGB空间到HSV空间。
dstCn:目标图像中的通道数,如果参数为0,则从src和代码中自动导出通道数。
Mat HSV;// 将RGB转为HSVcvtColor(mat, HSV, COLOR_BGR2HSV);
图像转换
CV_BGR2GRAY:将BGR格式的图像转换为灰度图。
CV_BGR2HSV:将BGR格式的图像转换为HSV格式。
CV_BGR2LAB:将BGR格式的图像转换为LAB格式。
CV_BGR2Luv:将BGR格式的图像转换为Luv格式。
CV_BGR2RGB:将BGR格式的图像转换为RGB格式(注意,OpenCV默认读取的图像是BGR格式,所以这个函数在某些情况下很有用)。
CV_BGR2XYZ:将BGR格式的图像转换为XYZ格式。
CV_BGR2YUV:将BGR格式的图像转换为YUV格式。
CV_BGR2YCrCb:将BGR格式的图像转换为YCrCb格式。
通道管理
split多通道分离
split(
InputArray m, //可以输入mat型
OutputArrayOfArrays mv
)
m:待分离的多通道图像
mv:分离后的单通道图像,为向量vector形式
merge多通道合并
merge(
InputArrayOfArrays mv,
OutputArray dst )
mv:需要合并的图像向量vector,其中每个图像必须拥有相同的尺寸和数据类型
dst:合并后输出的图像,通道数等于所有输入图像的通道数的总和
合并两个矩阵,取同一位置中较小的值
min(
InputArray src1,
InoytArray sec2,
OutputArray dst )
合并两个矩阵,取同一位置中较大的值
max(
InputArray src1,
InoytArray sec2,
OutputArray dst )
找出矩阵中的最值
minMaxLoc(
InputArray src, //输入单通道矩阵
CV_OUT double* minVal, //指向最小值的指针,如果不需要,则使用NULL
CV_OUT double* maxVal =0, //指向最大值的指针,如果不需要,则使用NULL
CV_OUT Point* minLoc =0, //指向最小值位置的指针,如果不需要,则使用NULL
CV_OUT Point* maxLoc = 0, //指向最大值位置的指针,如果不需要,则使用NULL
InputArray mask =noArray() //掩码矩阵,用于标记寻找上述四个值的范围,参数默认值为noArray,表示寻找范围是矩阵中所有数据
)
与或非运算
非运算
bitwise_not( //非运算InputArray src, //输入矩阵OutputArray dst, //输出矩阵InputArray mask = noArray() //掩码区域
)
与运算
bitwise_and( //与运算InputArray src1, //输入矩阵1InputArray src2, //输入矩阵2OutputArray dst, // 输出矩阵InputArray mask = noArray());//掩码矩阵
或运算
bitwise_or( //或运算InputArray src1, //输入矩阵1InputArray src2, //输入矩阵2OutputArray dst, // 输出矩阵InputArray mask = noArray());//掩码矩阵
)
阈值化(二值化)
threshold( //图像二值化
InputArray src, //待二值化图像,图像只能是CV_8U和CV_32F两种数据类型
OutputArray dst, //二值化后的图像
double thresh, //阈值
double maxval, //二值化过程中的最大值,非必须参数
int type //二值化方式
);
adaptiveThreshold( //自适应阈值化,只支持灰度图InputArray src, //待二值化图像OutputArray dst, //输出图像double maxValue, //二值化的最大值int adaptiveMethod, //自适应确定阈值的方法,分为均值法ADAPTIVE_THRESH_MEAN_C和高斯法ADAPTIVE_THRESH_GAUSSIAN_Cint thresholdType, //选择二值化方法int blockSize, //自适应确定阈值的像素邻域大小double C); //从平均值或者加权平均值中减去的常数
LUT查找表
LUT(
InputArray src, //输入图像,类型只能是8U
InputArray lut, //256个像素的查找表,如果为多通道,通道数必须和输入图像通道数相同
OutputArray dst //输出矩阵,数据类型和查找表相同
);
图像尺寸缩放、翻转、拼接
图像尺寸缩放
resize(InputArray src, //输入图像OutputArray dst, //输出图像Size dsize, //输出图像的尺寸double fx = 0, //水平轴的比例因子,变为原来的几倍double fy = 0, //垂直轴的比例因子int interpolation = INTER_LINEAR //插值方法,INTER_AREA最近邻插值,INTER_LINEAR双线性插值,INTER_CUBIC三线性插值
);flip( 图像翻转InputArray src, //输入图像OutputArray dst, //输出图像int flipCode //翻转方式标志,数值大于0表示绕y轴翻转,数值等于0表示围绕x轴翻转,数值小于0表示围绕两个轴翻转
);
resize(INTER_AREA,INTER_LINEAR,INTER_CUBIC)hconcat(//横向拼接InputArray src1, // 输入图像 InputArray src2, //输入图像,需要两个输入图像高度相同OutputArray dst //输出图像
) vconcat(//纵向拼接InputArray src1, // 输入图像 InputArray src2, //输入图像,需要两个输入图像高度相同OutputArray dst //输出图像
)
仿射变换和旋转
// 仿射变换:由平移,缩放,旋转,翻转和错切组合得到,也叫三点变换
warpAffine( 仿射变换InputArray src, //输入图像OutputArray dst, //输出图像InputArray M, //2*3变换矩阵,仿射变换矩阵Size dsize, //输出图像尺寸int flags = INTER_LINEAR, //插值方法标志int borderMode = BORDER_CONSTANT, //像素边界外推方法的标志const Scalar& borderValue = Scalar()); //填充边界使用的数值,默认情况下为0
像素边界外推方法
BORDER_CONSTANT = 0,用特定值填充//!< iiiiii|abcdefgh|iiiiiii
BORDER_REPLICATE = 1,两端复制填充//!< aaaaaa|abcdefgh|hhhhhhh
BORDER_REFLECT = 2, 倒叙填充//!< fedcba|abcdefgh|hgfedcb
BORDER_WRAP = 3, 正序填充//!< cdefgh|abcdefgh|abcdefg
BORDER_REFLECT_101 = 4, 不包含边界值倒叙填充//!< gfedcb|abcdefgh|gfedcba
BORDER_TRANSPARENT = 5, //随机填充!< uvwxyz|abcdefgh|ijklmno
BORDER_REFLECT101 = BORDER_REFLECT_101, //!与BORDER_REFLECT_101相同
BORDER_DEFAULT = BORDER_REFLECT_101, //!与BORDER_REFLECT_101相同
BORDER_ISOLATED = 16 //!< 不关心感兴趣区域之外的部分
c++中并没有直接进行图像旋转的函数,需要求取一个旋转变换的仿射矩阵,通过仿射矩阵实现图像的旋转
getRotationMatrix2D( 图像旋转,返回一个2*3的矩阵
Point2f center, 图像旋转的中心位置
double angle, 图像旋转的角度,正值为逆时针旋转
double scale 两个轴的比例因子,可以实现旋转过程中的图像缩放,不缩放输入1
);
图像旋转的计算公式
三点对应方式计算仿射变换矩阵
getAffineTransform(
const Point2f src[], 原图像的三个点坐标
const Point2f dst[] 仿射变换后的三个点坐标
);
透视变换(透视投影,又叫四点变换)
从一个点出发把一个平面内人形状投影到另一个平面上
计算公式:
getPerspectiveTransform( 计算透视变换矩阵
const Point2f src[], 原图像中的三个坐标
const Point2f dst[], 目标图像中的三个像素坐标
int solveMethod = DECOMP_LU 计算透视变换矩阵的方法
);
计算透视变换矩阵的方法DECOMP_LU = 0, 最佳主轴元素的高斯消元法 DECOMP_SVD = 1, 奇异值分解法 DECOMP_EIG = 2, 特征值分解法 DECOMP_CHOLESKY = 3, Cholesky分解法DECOMP_QR = 4, QR分解法DECOMP_NORMAL = 16 使用正规方程公式,可以去前面的标志一起使用warpPerspective( 透视变换函数InputArray src, 输入图像OutputArray dst,InputArray M, 3*3的透视变换矩阵Size dsize, 输出图像尺寸int flags = INTER_LINEAR, 插值方式 int borderMode = BORDER_CONSTANT, 像素边界外推方法的标志 const Scalar& borderValue = Scalar() 填充边界使用的数值,默认为0);
绘制图形
绘制直线
line( InputOutputArray img, //绘制的图像Point pt1, //起点坐标Point pt2, //终点坐标const Scalar& color, //颜色int thickness = 1, //宽度int lineType = LINE_8, //边界类型int shift = 0 //中心坐标的半径数值中的小数点数
);
边界类型:
FILLED = -1, 填充型LINE_4 = 4, //!< 4-connected line 四连接LINE_8 = 8, //!< 8-connected line 8连接LINE_AA = 16 //!< antialiased line
绘制圆形
circle(InputOutputArray img, Point center, int radius, 半径长度const Scalar& color, int thickness = 1, 线的宽度,-1为绘制实心圆int lineType = LINE_8,int shift = 0
);
绘制椭圆
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);
矩形绘制
rectangle(InputOutputArray img,Point pt1, Point pt2,const Scalar& color, int thickness = 1,int lineType = LINE_8, int shift = 0);
绘制多边形
fillPoly(InputOutputArray img, const Point** pts, 所有顶点坐标(可以是多重数组,绘制多个多边形)const int* npts, 定点数int ncontours, 绘制的多边形的个数const Scalar& color, int lineType = LINE_8, int shift = 0,Point offset = Point());
绘制文字
putText(InputOutputArray img, const String& text, Point org, //文字字符串左下角像素的坐标int fontFace, double fontScale, Scalar color,int thickness = 1, int lineType = LINE_8,bool bottomLeftOrigin = false
);
ROI分割和拷贝
img(Range(int start, //区间的开始int end; //区间的结束 ),Range(int start, //区间的开始int end; //区间的结束 )
)Rect_(_Tp _x, //左上角x坐标_Tp _y, //左上角y坐标_Tp _width, //宽_Tp _height) //高
矩阵存储图
浅拷贝:只拷贝矩阵头
mat1=mat2
深拷贝:拷贝所有内容
cv::copyTo
copyTo(InputArray src,OutputArray dst, InputArray mask);Mat::copyToMat mat1;mat.copyTo(OutputArray dst,InputArray mask) const
图像金字塔
高斯图像金字塔:不断下采样
拉普拉斯金字塔:第k层的高斯图像下采样,再上采样,然后上采样和第k层的高斯图像求和得到拉普拉斯金字塔
pyrDown( //下采样InputArray src, OutputArray dst,const Size& dstsize = Size(), int borderType = BORDER_DEFAULT //填充方式);pyrUp( 上采样InputArray src,OutputArray dst,const Size& dstsize = Size(), int borderType = BORDER_DEFAULT);
创建滑动条和鼠标监控
创建滑动条
createTrackbar(const String& trackbarname, const String& winname, //创建滑动条的窗口的名称int* value, //反应当前滑块的位置int count, //最大值TrackbarCallback onChange = 0, //回调函数void* userdata = 0 //传递给回调函数的参数);
案例代码
Mat img;void callBack(int value, void*) {float a = value / 100;Mat img2 = img * a;imshow("img", img2);
}int main()
{img = imread("H:/1732413934315.png");namedWindow("img");imshow("img", img);int value = 100;createTrackbar("滑动条名称","img",&value,200,callBack,0);waitKey(0);return 0;
}
鼠标监控
setMouseCallback( 鼠标时间响应函数const String& winname, MouseCallback onMouse, void* userdata = 0)MouseCallback(int event, 鼠标响应事件标志,瞬间动作int x, int y, int flags, 鼠标相应标识,长时间的操作void* userdata 传递给回调函数的可选参数)鼠标响应时间标志enum MouseEventTypes {EVENT_MOUSEMOVE = 0, //!< 鼠标指针再窗口上移动EVENT_LBUTTONDOWN = 1, //!<按下鼠标左键EVENT_RBUTTONDOWN = 2, //!< 按下鼠标右键EVENT_MBUTTONDOWN = 3, //!< 按下鼠标中键EVENT_LBUTTONUP = 4, //!< 释放鼠标左键EVENT_RBUTTONUP = 5, //!< 释放鼠标右键EVENT_MBUTTONUP = 6, //!< 释放鼠标中键EVENT_LBUTTONDBLCLK = 7, //!< 双击鼠标左键EVENT_RBUTTONDBLCLK = 8, //!< 双击鼠标右键EVENT_MBUTTONDBLCLK = 9, //!< 双击鼠标中键EVENT_MOUSEWHEEL = 10,//!< 正值表示向前滚动,负值表示向后滚动EVENT_MOUSEHWHEEL = 11 //!< 正值表示向左滚动,负值表示向右滚动鼠标相应标识EVENT_FLAG_LBUTTON = 1, //!< 按住左键拖拽EVENT_FLAG_RBUTTON = 2, //!< 按住右键拖拽EVENT_FLAG_MBUTTON = 4, //!< 按住中键拖拽EVENT_FLAG_CTRLKEY = 8, //!< 按下ctrl键EVENT_FLAG_SHIFTKEY = 16,//!< 按下SHIFT键EVENT_FLAG_ALTKEY = 32 //!< 按下ALT键normalize( 归一化InputArray src, OutputArray dst, double alpha = 0, double beta = 1, int norm_type = NORM_MINMAX, int dtype = -1, InputArray mask = noArray()
);NORM_MINMAX: 数组的数值被线性变换到alpha和beta之间(通常是0到1)。NORM_L2 : :归一化后的值 = 像素值 / sqrt(所有像素值平方和)NORM_INF : 归一化后的值 = 像素值 / 最大绝对值像素值NORM_L1 : 归一化后的值 = 像素值 / (所有像素值绝对值的和)calcHist( 统计图像像素const Mat* images,int nimages,const int* channels, //需要统计哪些区域InputArray mask,SparseMat& hist, int dims,const int* histSize, const float** ranges, //每个图像通道中灰度值的取值范围bool uniform = true, //直方图是否均匀bool accumulate = false //是否累积统计直方图,是否分别统计每个通道
);equalizeHist( 直方图均衡化InputArray src, 输入图像必须是8UC1OutputArray dst);LUTLUT(图像直方图匹配,将图像分布映射为指定分布InputArray src, InputArray lut, 变换矩阵OutputArray dst
);matchTemplate(InputArray image, 只能为8U或32F格式,两个输入图像类型必须相同InputArray templ,OutputArray result,int method, 匹配方法 InputArray mask = noArray());匹配方法
TM_SQDIFF = 0, 平方差匹配法 TM_SQDIFF_NORMED = 1, 归一化平方差匹配法 TM_CCORR = 2, 相关匹配法TM_CCORR_NORMED = 3, 归一化相关匹配法 TM_CCOEFF = 4, 系数匹配法 TM_CCOEFF_NORMED = 5 归一化相关系数匹配法
求积分图像
integral(InputArray src, OutputArray sum, 标准求和积分图像OutputArray sqsum, 平方求和积分图像OutputArray tilted, 倾斜45°积分图像 int sdepth = -1, 标准求和和倾斜求和积分图像输出类型 int sqdepth = -1 平方求和积分图像数据类型
);
漫水填充算法
1. 选择填充算法步骤
2. 以种子点为中心,判断4邻域或8邻域的像素值与种子点像素值的差值,将差值小于阈值的像素点添加进区域内
3. 将新加入的像素点作为新的种子点,反复执行第二步,知道没有新的像素点杯添加进区域
floodFill( InputOutputArray image, InputOutputArray mask,Point seedPoint, Scalar newVal, 归入种子点区域内像素点的像素值CV_OUT Rect* rect = 0, 种子点漫水填充区域的最小矩形边界 Scalar loDiff = Scalar(), 添加进种子点区域条件的下界差值Scalar upDiff = Scalar(), 添加进种子点区域条件的上界差值int flags = 4 漫水填充方法
);
分水岭分割算法
1. 首先对图像像素的灰度级进行排序,确定灰度值较小的像素点,改像素点即为开始注水点
2. 淹没过程:对每个最低点开始不断注水,不断掩膜周围的像素点,不同注水处的水汇集在一起,形成分割线watershed(InputArray image, InputOutputArray markers
);
角点检测
Harris角点
首先定义一个矩形区域,计算区域内像素值之和,移动区域,计算像素值之和,如果变化大,认为是角点cornerHarris(Harris角点检测InputArray src, OutputArray dst, int blockSize, 邻域大小int ksize, sobel算子的半径 double k, 权重系数int borderType = BORDER_DEFAULT
);drawKeypoints(角点绘制InputArray image,const std::vector<KeyPoint>& keypoints, 关键点左边和方向InputOutputArray outImage,const Scalar& color = Scalar::all(-1),DrawMatchesFlags flags = DrawMatchesFlags::DEFAULT
);
相关文章:

c++视频图像处理
打开视频或摄像头 打开指定视频 /*VideoCapture(const String &filename, apiPreference);filename:读取的视频或者图像序列的名称apiPreference:读取数据时设置的属性*/ VideoCapture video; //定义一个空的视频对象 video.open("H:/BaiduNetdiskDownlo…...

音视频入门基础:MPEG2-TS专题(8)——TS Header中的适配域
注:本文有部分内容引用了维基百科:https://zh.wikipedia.org/wiki/MPEG2-TS 一、引言 当TS Header中的adaptation_field_control属性的值为10或11 时,TS Header包含adaptation field(适配域): 根据《T-RE…...

基于stm32单片机的教室节能系统设计
功能描述 0. STM32F103C8T6单片机为控制核心 1. OLED液晶显示当前年 月 日 时 分 秒 星期 2. 按键可以设置定时时间 3. 按键可以设置用电开关的开启和关闭时间,实现设备的节能 4. 通过红外遥控可以打开关闭空调设备(通过继电器开关闭合模拟&#x…...
mini主机通过内网穿透做成服务器
文章目录 简介1.ubuntu 的ssh server 安装2.ubuntu 的docker 安装3.ubuntu的curl的安装4.ubuntu的frp客户端安装5.ubuntu的docker compose安装6.声明 简介 主要目的 本地设备做成服务器,实现ssh远程登录以及内网穿透设备总成本1千多元(其实部分设备可以…...

智能桥梁安全运行监测系统守护桥梁安全卫士
一、方案背景 桥梁作为交通基础设施中不可或缺的重要组成部分,其安全稳定的运行直接关联到广大人民群众的生命财产安全以及整个社会的稳定与和谐。桥梁不仅是连接两地的通道,更是经济发展和社会进步的重要纽带。为了确保桥梁的安全运行,桥梁安…...

Selenium和Pyppeteer有什么区别?
Selenium和Pyppeteer都是自动化测试工具,它们可以模拟用户在浏览器中的操作,但它们之间存在一些关键的区别: Selenium 跨浏览器支持:Selenium支持多种浏览器,包括Chrome、Firefox、Internet Explorer等,而…...
82从零开始学Java之异常处理机制简介
作者:孙玉昌,昵称【一一哥】,另外【壹壹哥】也是我哦 CSDN博客专家、万粉博主、阿里云专家博主、掘金优质作者 前言 大家可以想一个问题,有没有谁能够做到开发项目时一个错误都不发生?如果谁能够做到这一点,那他可能真的是“天才”!但实际上,任何人都不可能在项目开发…...

Git上传本地项目到远程仓库(gitee/github)
目录 序言一、创建git本地版本库二、连接远程仓库(以gitee为例)三、将项目提交到git(本地)版本库1.由工作区添加到暂存区2.由暂存区添加到版本库 四、将代码由本地仓库上传到 gitee远程仓库1.获取远程库与本地同步2.把当前分支 ma…...

华为仓颉编程环境搭建
1、仓颉介绍 摘自华为官方:仓颉编程语言作为一款面向全场景应用开发的现代编程语言,通过现代语言特性的集成、全方位的编译优化和运行时实现、以及开箱即用的 IDE 工具链支持,为开发者打造友好开发体验和卓越程序性能。 其具体特性表现为&am…...
UE5 Line Trace By Channel(通道线条追踪)节点
在 Unreal Engine 5 (UE5) 中,Line Trace By Channel 是一个常用于进行物理射线检测(raycasting)的节点。它会沿着一条从起点到终点的直线发射一条射线,并检测射线与世界中任何物体的碰撞。这个节点广泛应用于枪械射击、检测物体、…...

DroneCAN 最新开发进展,Andrew在Ardupilot开发者大会2024的演讲
本文是Andrew演讲的中文翻译,你可以直接观看视频了解演讲的全部内容,此演讲视频的中文版本已经发布在Ardupilot社区的Blog板块,你可以在 Arudpilot官网(https://ardupilot.org) 获取该视频: 你也可以直接通过Bilibili链…...

UDP客户端服务器通信
在这篇博客中,我们将探索 UDP(用户数据报协议) 通信,简要地说,UDP 是一种无连接、快速但不可靠的通信协议,适用于需要快速数据传输但对丢包容忍的场景,比如视频流和在线游戏。就像《我是如此相信…...
适合中小型公司的自动化测试的测试框架,OpenSourceTest
适合中小型公司的自动化测试的测试框架,OpenSourceTest 文档地址: http://docs.opensourcetest.cn/代码仓库: https://github.com/chineseluo/opensourcetest安装方式: pip3 install opensourcetest -i https://pypi.tuna.tsin…...
实现跨语言通信:Rust 和 Thrift 的最佳实践
前言 在分布式系统中,服务之间高效且安全的通信至关重要。Apache Thrift 是一个被广泛应用的跨语言 RPC(远程过程调用)框架,它支持多种编程语言,包括 Rust。Rust 以其卓越的性能和内存安全保障,成为越来越…...
js判断空对象
1. 使用 Object.keys() 方法 Object.keys(obj) 方法返回一个包含对象可枚举属性名称的数组。如果返回的数组长度为 0,表示对象为空。 const isEmpty (obj) > Object.keys(obj).length 0;// 示例 const emptyObject {}; const nonEmptyObject { key: value …...

visionpro官方示例分析(一) 模板匹配工具 缺陷检测工具
1.需求:找出图像中的这个图形。 2.步骤 使用CogPMAlignTool工具,该工具是模板匹配工具,见名知意,所谓模板匹配工具就是说先使用该工具对一张图像建立模板,然后用这个模板在其他图像上进行匹配,匹配上了就说…...

PyCharm中Python项目打包并运行到服务器的简明指南
目录 一、准备工作 二、创建并设置Python项目 创建新项目 配置项目依赖 安装PyInstaller 三、打包项目 打包为可执行文件 另一种打包方式(使用setup.py) 四、配置服务器环境 五、上传可执行文件到服务器 六、在服务器上运行项目 配置SSH解释…...

cocos creator 3.8 合成大西瓜Demo 11
界面上的Node节点: 背景 警戒线 三面墙 初始位置节点 水果容器 先分组吧,墙 地板 水果 创建预制体 先挂一个脚本 刚体碰撞器先弄上再说 import { _decorator, Component, Node } from cc; const { ccclass, property } _decorator;ccclass(FruitData) e…...

Vue前端开发-动态插槽
不仅父组件可以通过插槽方式访问并控制子组件传入的数据,而且可以控制传入父组件时插槽的名称,从而使不同的插槽根据名称的不同,使用场景也不同,例如在一个小区详细页中,可以根据小区类型,调用不同名称的详…...

使用easyexcel导出复杂模板,同时使用bean,map,list填充
背景 在使用easyexcel导出时,如果遇到一个模板中同时存在 一部分是实体类中的字段,另外部分是列表的字段,需要特殊处理一下,比如下面的模板: 这里面 user, addr 是实体类(或者map)…...

label-studio的使用教程(导入本地路径)
文章目录 1. 准备环境2. 脚本启动2.1 Windows2.2 Linux 3. 安装label-studio机器学习后端3.1 pip安装(推荐)3.2 GitHub仓库安装 4. 后端配置4.1 yolo环境4.2 引入后端模型4.3 修改脚本4.4 启动后端 5. 标注工程5.1 创建工程5.2 配置图片路径5.3 配置工程类型标签5.4 配置模型5.…...

Vue3 + Element Plus + TypeScript中el-transfer穿梭框组件使用详解及示例
使用详解 Element Plus 的 el-transfer 组件是一个强大的穿梭框组件,常用于在两个集合之间进行数据转移,如权限分配、数据选择等场景。下面我将详细介绍其用法并提供一个完整示例。 核心特性与用法 基本属性 v-model:绑定右侧列表的值&…...
前端倒计时误差!
提示:记录工作中遇到的需求及解决办法 文章目录 前言一、误差从何而来?二、五大解决方案1. 动态校准法(基础版)2. Web Worker 计时3. 服务器时间同步4. Performance API 高精度计时5. 页面可见性API优化三、生产环境最佳实践四、终极解决方案架构前言 前几天听说公司某个项…...

大型活动交通拥堵治理的视觉算法应用
大型活动下智慧交通的视觉分析应用 一、背景与挑战 大型活动(如演唱会、马拉松赛事、高考中考等)期间,城市交通面临瞬时人流车流激增、传统摄像头模糊、交通拥堵识别滞后等问题。以演唱会为例,暖城商圈曾因观众集中离场导致周边…...

ServerTrust 并非唯一
NSURLAuthenticationMethodServerTrust 只是 authenticationMethod 的冰山一角 要理解 NSURLAuthenticationMethodServerTrust, 首先要明白它只是 authenticationMethod 的选项之一, 并非唯一 1 先厘清概念 点说明authenticationMethodURLAuthenticationChallenge.protectionS…...

NFT模式:数字资产确权与链游经济系统构建
NFT模式:数字资产确权与链游经济系统构建 ——从技术架构到可持续生态的范式革命 一、确权技术革新:构建可信数字资产基石 1. 区块链底层架构的进化 跨链互操作协议:基于LayerZero协议实现以太坊、Solana等公链资产互通,通过零知…...
今日科技热点速览
🔥 今日科技热点速览 🎮 任天堂Switch 2 正式发售 任天堂新一代游戏主机 Switch 2 今日正式上线发售,主打更强图形性能与沉浸式体验,支持多模态交互,受到全球玩家热捧 。 🤖 人工智能持续突破 DeepSeek-R1&…...

成都鼎讯硬核科技!雷达目标与干扰模拟器,以卓越性能制胜电磁频谱战
在现代战争中,电磁频谱已成为继陆、海、空、天之后的 “第五维战场”,雷达作为电磁频谱领域的关键装备,其干扰与抗干扰能力的较量,直接影响着战争的胜负走向。由成都鼎讯科技匠心打造的雷达目标与干扰模拟器,凭借数字射…...
Rapidio门铃消息FIFO溢出机制
关于RapidIO门铃消息FIFO的溢出机制及其与中断抖动的关系,以下是深入解析: 门铃FIFO溢出的本质 在RapidIO系统中,门铃消息FIFO是硬件控制器内部的缓冲区,用于临时存储接收到的门铃消息(Doorbell Message)。…...

GC1808高性能24位立体声音频ADC芯片解析
1. 芯片概述 GC1808是一款24位立体声音频模数转换器(ADC),支持8kHz~96kHz采样率,集成Δ-Σ调制器、数字抗混叠滤波器和高通滤波器,适用于高保真音频采集场景。 2. 核心特性 高精度:24位分辨率,…...