在matlab中使用UAV123官方toolkits测试自己的数据集
一、前言
最近需要将自己的跟踪代码在自己拍摄的数据集上进行测试,这里我选择使用 UAV123 官方 toolkits 进行配置。首先需要搞清楚这部分代码是如何运行的,精度图和成功率图是如何绘制出来的,然后再将自己的数据集加进去进行测试。
二、UAV123官方toolkits工作流程
本文以 UAV123 数据集为例查看 toolkits 的工作流程,共使用了 10 个跟踪器。
在绘制结果图时,首先需要将每个跟踪器在每个序列上的跟踪结果保存为一个 .mat 文件,然后运行根目录下的 perfPlot.m 文件进行结果图的绘制。直接来看 perfPlot.m 文件。
1. 准备工作
准备工作包括加载数据集中各序列的属性、绘图风格、图像序列、跟踪器等。
attPath = '...\UAV123\tracker_benchmark_v1.1\anno_uav123\att\'; % UAV123
首先需要设置一个 attpath 加载 att 文件夹。我们可以看到,att 文件夹下也放置着与数据集中图像序列数目相等的 txt 文件,且每个文件的名称即为图像序列的名称。与标注目标位置的 txt 文件不同,这里的 txt 文件中只含有 12 个非 0 即 1 的数字,分别对应着 UAV123 数据集的 12 种属性。若该序列包含某种属性,则该属性位置对应的值即为 1,否则为 0。12 种属性分别为:
%UAV123
attName={'Scale Variation' 'Aspect Ratio Change' 'Low Resolution' 'Fast Motion' 'Full Occlusion' 'Partial Occlusion' 'Out-of-View' 'Background Clutter' 'Illumination Variation' 'Viewpoint Change' 'Camera Motion' 'Similar Object'};attFigName={'SV' 'ARC' 'LR' 'FM' 'FOC' 'POC' 'OV' 'BC' 'IV' 'VC' 'CM' 'SOB'};
这里我根据 UAV123.json 文件中的信息对每种属性包含的图像序列进行了整理:
尺度变化(Scale Variation) | group1_2、car10、person8_1、person12_2、car3_s、car1_1、group3_1、car11、group1_3、group1_1、person11、car13、person8_2、group3_3、car1_3、car1_2、car1_s、group3_2、wakeboard10、car12、person10、group1_4、person15、car17、car15、person14_1、uav8、group3_4、person16、car14、person3、car3、car6_5、wakeboard1、group2_3、group2_2、car6_4、car2、car2_s、wakeboard2、group2_1、wakeboard3、car5、wakeboard7、car6_3、car6_2、wakeboard6、person17_2、car4、truck4_2、building2、wakeboard4、boat9、car4_s、boat8、car6、wakeboard5、person17_1、person17_1、truck4_1、car7、building3、person19_3、person1_s、wakeboard8、boat5、truck1、car8_2、boat4、wakeboard9、person19_2、car9、boat6、truck2、car8_1、boat7、person3_s、person19_1、bird1_3、boat3、person7_2、person5_1、bike1、boat2、bird1_2、person7_1、bike3、bike2、boat1、bird1_1、uav5、uav4、car18、person18、uav6、uav7、person21、uav3、car16_2、uav1_3、uav1_2、uav2、person4_2、person20、person9、person22、car16_1、uav1_1、person23、person4_1 |
纵横比变化(Aspect Ratio Change) | person8_1、person12_2、group3_1、group1_3、person11、person8_2、group3_3、car1_3、car1_2、car1_s、group3_2、car12、group1_4、car17、car15、person14_1、group3_4、person16、car14、car6_5、wakeboard1、group2_3、car2、wakeboard2、group2_1、wakeboard3、wakeboard7、car6_3、car6_2、wakeboard6、person17_2、car4、wakeboard4、boat9、car4_s、boat8、wakeboard5、person17_1、car7、person19_3、wakeboard8、boat5、truck1、boat4、person19_2、car9、truck2、car8_1、boat7、person3_s、person19_1、bird1_3、boat3、person7_2、bike1、bird1_2、person7_1、bike2、bird1_1、car18、person18、person21、car16_2、uav1_3、uav1_2、person20、person9、uav1_1 |
低分辨率(Low Resolution) | group3_1、car11、group1_3、car13、car1_2、group3_2、wakeboard10、car12、car17、car15、person14_1、uav8、group3_4、car14、car3、group2_3、car2、wakeboard3、wakeboard6、car4、truck4_2、boat9、boat8、wakeboard5、truck4_1、person19_3、wakeboard8、wakeboard9、car9、truck3、truck2、bird1_3、bird1_2、bike3、bike2、bird1_1、uav5、uav4、uav6、uav7、person21、uav3、uav1_3、uav1_2、uav2、person22、car16_1、uav1_1 |
快速运动(Fast Motion) | person8_1、car3_s、car1_s、car2_s、wakeboard2、wakeboard6、car4_s、wakeboard5、person19_3、person1_s、person19_2、car9、boat7、person3_s、person19_1、bird1_3、person7_2、bike1、bird1_2、person7_1、bird1_1、car18、uav6、uav3、car16_2、uav1_3、car16_1、person23 |
全部遮挡(Full Occlusion) | person8_1、person12_2、car11、car1_3、car1_2、group3_2、car12、person10、person14_1、group3_4、person16、car14、group2_3、group2_2、car2、group2_1、person17_1、car7、person19_3、person19_2、person19_1、bird1_3、bird1_2、person7_1、bike2、bird1_1、uav6、uav7、uav1_3、uav1_2、uav2、person9、uav1_1 |
局部遮挡(Partial Occlusion) | group1_2、car10、person8_1、person12_2、car3_s、group3_1、car11、person13、group1_3、group1_1、person11、person8_2、group3_3、car1_3、car1_2、car1_s、group3_2、car12、person10、group1_4、person14_3、person15、car15、person14_1、group3_4、person16、car14、car3、car6_5、group2_3、group2_2、car2、car2_s、group2_1、car6_2、person17_2、car4、truck4_2、boat9、wakeboard5、person17_1、truck4_1、car7、person19_3、person1_s、truck1、person19_2、car9、truck3、truck2、car8_1、person3_s、person19_1、bird1_3、person7_2、bird1_2、person7_1、bike3、bike2、bird1_1、person2_2、person18、uav6、uav7、person21、uav1_3、uav1_2、uav2、person20、person9、car16_1、uav1_1、person4_1 |
移出视野(Out-of-View) | person8_1、person8_2、car1_3、car1_s、person10、person14_3、car14、car3、car6_5、car2、car6_2、person19_3、person19_2、car8_1、person3_s、person19_1、bird1_3、person7_2、bird1_2、person7_1、bird1_1、person2_2、person18、uav1_3、uav1_2、person20、person9、car16_1、uav1_1、person4_1 |
背景杂波(Background Clutter) | person13、group3_3、person12_1、group3_2、person14_2、person14_3、person14_1、uav8、group3_4、person16、group2_3、group2_1、person17_2、truck3、bike2、uav5、uav7、person21、uav1_3、uav1_2、uav1_1 |
光照变化(Illumination Variation) | person12_2、car3_s、person13、person12_1、car1_s、group3_2、group1_4、uav8、group3_4、person16、wakeboard1、group2_3、car6_4、car2_s、car6_3、wakeboard6、person17_2、car4_s、wakeboard5、person17_1、person1_s、wakeboard8、car8_2、boat4、person3_s、bike1、bike2、person21、uav1_3、uav1_2、uav1_1 |
视角变化(Viewpoint Change) | car3_s、car11、person13、group1_3、person6、person11、person12_1、car1_3、car1_2、car1_s、car12、person10、group1_4、person14_3、car17、car14、car6_5、group2_3、group2_2、car6_4、car2_s、wakeboard2、group2_1、wakeboard3、wakeboard7、car6_3、car6_2、wakeboard6、truck4_2、wakeboard4、boat9、car4_s、boat8、wakeboard5、car7、person19_3、person1_s、wakeboard8、boat5、truck1、boat4、car8_1、boat7、boat3、person7_2、person5_1、bike1、person7_1、person5_2、car18、person18、person21、car16_2、uav1_3、uav1_2、person20、person9、person22、car16_1、uav1_1 |
相机运动(Camera Motion) | person8_1、person12_2、car3_s、car1_1、car11、group1_3、person6、car13、group3_3、person12_1、car1_2、car1_s、group3_2、person10、group1_4、person1、person14_2、person14_3、car17、person14_1、group3_4、person16、car14、person3、car3、car6_5、group2_3、group2_2、car6_4、car2、car2_s、wakeboard2、group2_1、wakeboard3、building5、car6_2、wakeboard6、person17_2、car4、car4_s、wakeboard5、person19_3、person1_s、wakeboard8、wakeboard9、person19_2、car9、car8_1、boat7、person3_s、person19_1、bird1_3、person7_2、bike1、person7_1、person2_2、car18、person18、uav6、person2_1、uav3、car16_2、uav1_3、person4_2、person20、person9、car16_1、uav1_1、person23、person4_1 |
相似目标(Similar Object) | group1_2、car10、car1_1、group3_1、car11、group1_3、group1_1、person11、group3_3、car1_3、car1_2、group3_2、car12、person10、group1_4、person15、car15、group3_4、car3、group2_3、group2_2、car6_4、car2、group2_1、car6_3、car4、car7、building3、person19_3、car8_2、car9、car8_1、bike1、uav4、uav6、person21、person20、person9、person4_1 |
然后是设定绘图风格、加载图像序列和跟踪器等等,其中,加载的图像序列包括 …/util/configSeqs.m 中设置的所有属性:
跟踪则包含我们在 …/util/configTrackers.m 中设置的两种属性:
然后,这里设置了一个元胞数组 nameTrkAll,用来存储所有跟踪器在图片中显示的名称:
nameTrkAll=cell(numTrk,1);
for idxTrk=1:numTrkt = trackers{idxTrk};nameTrkAll{idxTrk}=t.namePaper;
end
接下来,定义了一个元胞数组 nameSeqAll,用来存储所有图像序列的名称,以及一个 double 数组,用来存储每个图像序列的长度,以及一个空数组 att,用来存储每个序列的属性。attNum 则用来记录该数据集共有集中属性。这里是 12 种。
nameSeqAll=cell(numSeq,1);
numAllSeq=zeros(numSeq,1);att=[];
for idxSeq=1:numSeqs = seqs{idxSeq};nameSeqAll{idxSeq}=s.name;s.len = s.endFrame - s.startFrame + 1;numAllSeq(idxSeq) = s.len;att(idxSeq,:)=load([attPath s.name '.txt']);
endattNum = size(att,2);
然后设置 figPath 和 perfMatPath,分别为存储结果图的路径和存储 距离精度及重叠精度 mat 文件的路径。
接下来,设置度量类型、评估类型、排名类型,这里分别设置为距离误差、重叠率,一次性评估,精度:
metricTypeSet = {'error', 'overlap'};
evalTypeSet = {'OPE'}; %'SRE', 'OPE'rankingType = 'threshold'; %AUC, threshold
然后设置跟踪器的数量同时选定绘图风格。
接下来设置记录重叠率的阈值集 thresholdSetOverlap,以及记录误差的阈值集 thresholdSetError。
thresholdSetOverlap = 0:0.05:1;
thresholdSetError = 0:50;
2. 绘制精度曲线
在接下来的循环中,首先计算的是跟踪精度,以精度图的形式呈现。
在绘制精度图的过程中,首先将阈值集设置为误差阈值集,然后设置排名 rankIdx ,以及 x、y 坐标轴名称
case 'error'thresholdSet = thresholdSetError;rankIdx = 21;xLabelName = 'Location error threshold';yLabelName = 'Precision';
接下来,利用一次性评估标准计算跟踪误差,首先确定保存误差结果的 mat 文件的名称及存放地址:
evalType = evalTypeSet{j};%SRE, TRE, OPE
plotType = [metricType '_' evalType];
switch metricTypecase 'overlap'titleName = ['Success plots on UAV123 '];case 'error'titleName = ['Precision plots on UAV123 '];
end
dataName = [perfMatPath 'aveSuccessRatePlot_' num2str(numTrk) 'alg_' plotType '.mat'];
若不存在则创建:
if ~exist(dataName)genPerfMat(seqs, trackers, evalType, nameTrkAll, perfMatPath);
end
我们已经知道后面的跟踪精度图都是根据这个 mat 文件中的数据绘制的,那我们先来看一下这个文件是如何生成的:
pathAnno = '.../UAV123/tracker_benchmark_v1.1/anno_uav123/'; % UAV123
numTrk = length(trackers);
thresholdSetOverlap = 0:0.05:1;
thresholdSetError = 0:50;
首先需要明确每个序列中记录目标真值框文件的位置,然后是跟踪器的数目,以及重叠率阈值集和误差阈值集。
然后根据评估标准明确选取哪个位置的跟踪结果:
switch evalTypecase 'SRE'rpAll=['.\results\results_SRE\'];case {'TRE'}rpAll=['.\results\results_TRE\'];case {'OPE'}rpAll=['.\results\results_OPE\'];
end
然后则按照 configSeqs.m 中的序列顺序依次进行计算。首先初始化一些基本信息,包括序列的帧数、名称等等:
s = seqs{idxSeq};
s.len = s.endFrame - s.startFrame + 1;
s.s_frames = cell(s.len,1);
nz = strcat('%0',num2str(s.nz),'d'); %number of zeros in the name of image
其中 s 包含下列信息:
记录序列中每张图片的位置:
for i=1:s.lenimage_no = s.startFrame + (i-1);id = sprintf(nz,image_no);s.s_frames{i} = strcat(s.path,id,'.',s.ext);
end
读取真值框,设置采样片段数,然后
rect_anno = dlmread([pathAnno s.name '.txt']);
numSeg = 20;
[subSeqs, subAnno]=splitSeqTRE(s,numSeg,rect_anno);
来看一下这个 splitSeqTRE 函数。
splitSeqTRE 函数将每个序列20个片段,首先,排除所有occ/不可见帧,然后进行采样:
Idx = 1:seq.len;
for j = 1:size(IdxExclude,1)Idx(IdxExclude(j,1):IdxExclude(j,2))=0;
end
Idx = Idx(find(Idx>0));for i=1:length(Idx)r = rect_anno(Idx(i),:);if r(1)<=0 | r(2)<=0 | r(3)<=0 | r(4)<=0 | isnan(sum(r))Idx(i) = 0;end
endIdx = Idx(find(Idx>0));
上面这段代码即将所有不可见帧排除了。
设置数组 startFrIdxOne 记录每组图片的其实帧号:
for i = length(Idx):-1:1if seq.len - Idx(i) + 1 >= minNumendSeg = Idx(i);endSegIdx = i;break;end
endstartFrIdxOne = [floor(1:endSegIdx/(segNum-1):endSegIdx) endSegIdx] ;
然后将序列分为 20 组图片,变量 subAnno 记录每组图片的的真值框,变量 subSeqs 记录每组图片的信息:
for i = 1:length(startFrIdxOne)index = Idx(startFrIdxOne(i));subS.path = seq.path;subS.nz = seq.nz;subS.ext = seq.ext;subS.startFrame = index+seq.startFrame-1;subS.endFrame = seq.endFrame;subS.len = subS.endFrame - subS.startFrame + 1;subS.annoBegin = seq.startFrame;subS.init_rect = rect_anno(index,:);anno = rect_anno(index:end,:);subS.s_frames = seq.s_frames(index:end);subS.name = seq.name;
% subS.nameIdx = [seq.name '_' num2str(i)];subAnno{i} = anno;subSeqs{i}=subS;
end
这里每组图片是由先前计算的 startFrIdxOne 到最后一帧的信息。
回到 genPerfMat 函数,按照跟踪器的顺序依次计算误差和重叠率:
t = trackers{idxTrk};load([rpAll s.name '_' t.name '.mat'])
disp([s.name ' ' t.name]);aveCoverageAll=[];
aveErrCenterAll=[];
errCvgAccAvgAll = 0;
errCntAccAvgAll = 0;
errCoverageAll = 0;
errCenterAll = 0;lenALL = 0;
switch evalTypecase 'SRE'idxNum = length(results);anno=subAnno{1};case 'TRE'idxNum = length(results);case 'OPE'idxNum = 1;anno=subAnno{1};
end
运行到这里发现虽然 splitSeqTRE 函数将图像序列分为了 20 个片段,但使用 OPE 的评估方式只 用到了 subAnno{1},也就是剩余的都没用到,而 subAnno{1} 就是所有图片的真值框。
设置数组 successNumOverlap 记录不同重叠率阈值下的成功率数量,设置数组 successNumErr 记录不同误差阈值下的成功率数量:
successNumOverlap = zeros(idxNum,length(thresholdSetOverlap));
successNumErr = zeros(idxNum,length(thresholdSetError));
加载跟踪结果:
res = results{idx};
计算误差:
[aveCoverage, aveErrCenter, errCoverage, errCenter] = calcSeqErrRobust(res, anno);
直接来看这个 calcSeqErrRobust 函数。首先对跟踪结果进行了一个处理,对跟踪结果为 NaN 或者跟踪框尺度为负值且真值框不为 NaN 的情况,将跟踪结果改为前一帧的跟踪结果:
if strcmp(results.type,'rect')for i = 2:seq_lengthr = results.res(i,:);r_anno = rect_anno(i,:);if (isnan(r) | r(3)<=0 | r(4)<=0)&(~isnan(r_anno))results.res(i,:)=results.res(i-1,:);endend
end
计算真值框的中心坐标:
centerGT = [rect_anno(:,1)+(rect_anno(:,3)-1)/2 rect_anno(:,2)+(rect_anno(:,4)-1)/2];
将第一帧的真值框坐标赋给第一帧的跟踪结果并计算跟踪器跟踪的目标框中心坐标:
rectMat(1,:) = rect_anno(1,:);
center = [rectMat(:,1)+(rectMat(:,3)-1)/2 rectMat(:,2)+(rectMat(:,4)-1)/2];
计算每一帧的中心距离误差:
errCenter = sqrt(sum(((center(1:seq_length,:) - centerGT(1:seq_length,:)).^2),2));
将真值框大于 0 的帧的跟踪结果和真值框值送入 calcRectInt 函数计算重叠率 tmp:
index = rect_anno>0;
idx=(sum(index,2)==4);
tmp = calcRectInt(rectMat(idx,:),rect_anno(idx,:));
计算平均重叠率和平均中心距离误差:
aveErrCoverage = sum(errCoverage(idx))/length(idx);
aveErrCenter = sum(errCenter(idx))/length(idx);
按照之前设置的重叠率阈值分别计算该序列成功的帧数:
for tIdx=1:length(thresholdSetOverlap)successNumOverlap(idx,tIdx) = sum(errCoverage >thresholdSetOverlap(tIdx));
end
按照之前设置的中心距离误差阈值分别计算该序列成功的帧数:
for tIdx=1:length(thresholdSetError)successNumErr(idx,tIdx) = sum(errCenter <= thresholdSetError(tIdx));
end
计算成功率和跟踪精度每个阈值处的值:
if strcmp(evalType, 'OPE')aveSuccessRatePlot(idxTrk, idxSeq,:) = successNumOverlap/(lenALL+eps);aveSuccessRatePlotErr(idxTrk, idxSeq,:) = successNumErr/(lenALL+eps);
这里 eps 的目的是什么呢?
到这里第一个序列第一个跟踪器的成功率和跟踪精度就计算结束了。依次循环直至在所有序列上计算完所有跟踪器的结果。
将成功率和跟踪精度存至 perMat 文件夹下:
dataName1=[perfMatPath 'aveSuccessRatePlot_' num2str(numTrk) 'alg_overlap_' evalType '.mat'];
save(dataName1,'aveSuccessRatePlot','nameTrkAll');dataName2=[perfMatPath 'aveSuccessRatePlot_' num2str(numTrk) 'alg_error_' evalType '.mat'];
aveSuccessRatePlot = aveSuccessRatePlotErr;
save(dataName2,'aveSuccessRatePlot','nameTrkAll');
genPerfMat 函数执行完毕,回到 perfPlot 函数。
加载中心距离误差值,设置结果图名称:
load(dataName);
figName= [figPath 'quality_plot_' plotType '_' rankingType];
由 plotDrawSave 函数绘制曲线图。
来看一下 plotDrawSave 函数。
首先需要按照跟踪器的顺序依次统计中心距离误差小于 20 个像素的帧数所占百分比,即距离精度:
for idxTrk=1:numTrk%each row is the sr plot of one sequencetmp=aveSuccessRatePlot(idxTrk, idxSeqSet,:);aa=reshape(tmp,[length(idxSeqSet),size(aveSuccessRatePlot,3)]);aa=aa(sum(aa,2)>eps,:);bb=mean(aa);switch rankingTypecase 'AUC'perf(idxTrk) = mean(bb);case 'threshold'perf(idxTrk) = bb(rankIdx);end
end
这里 bb 即为每个跟踪器在 123 个序列上每个阈值下的平均中心距离误差,rankIdx 值为 21,bb 中第 21 个阈值刚好对应 20 个像素,即通用阈值。
对跟踪器根据 20 个像素的公共阈值进行排名:
[tmp,indexSort]=sort(perf,'descend');
其中 tmp 为排名之后的分数,indexSort 为排名之后各跟踪器对应的顺序。
然后按照排序后的顺序从高到低依次绘制精度曲线:
for idxTrk=indexSort(1:rankNum)tmp=aveSuccessRatePlot(idxTrk,idxSeqSet,:);aa=reshape(tmp,[length(idxSeqSet),size(aveSuccessRatePlot,3)]);aa=aa(sum(aa,2)>eps,:);bb=mean(aa);switch rankingTypecase 'AUC'score = mean(bb);tmp=sprintf('%.3f', score);case 'threshold'score = bb(rankIdx);tmp=sprintf('%.3f', score);endh(i) = plot(thresholdSet,bb,'color',plotDrawStyle{i}.color, 'lineStyle', plotDrawStyle{i}.lineStyle,'lineWidth', 4,'Parent',axes1);hold oni=i+1;
end
精度曲线绘制完成。
3. 绘制每种属性下的精度曲线
回到 perfPlot 函数,依次绘制每种属性的精度曲线图。
首先需要找出每种属性对应的序列:
idxSeqSet=find(att(:,attIdx)>attTrld);
然后同样进入 plotDrawSave 函数,分别绘制精度曲线图。
成功率曲线的绘制过程与精度曲线类似。
三、测试自己的数据集
1. 数据集标注
首先需要对数据集进行标注,标注过程就不再赘述了。数据集中的每个序列应该对应一个 .txt 格式的标注文档,文档中包含了每张图片中目标框的左上角和目标框的大小。
2. 配置数据集
仿照 UAV123 数据集将图像序列和标注数据进行存储。例如,我的数据集命名为 UAV_seq ,那么首先建立一个名为 UAV_seq 的文件夹,文件夹内容如下:
data_seq 文件夹中为每个图像序列的名称,每个文件夹下为对应的图像序列;anno 文件夹下则放置每个图像对应的 txt 文件。
3. 在 configSeqs 中添加数据集信息
仿照 seqUAV123 在 …/util/configSeqs.m 文件中添加 UAV_seq 的相关信息,包括数据集中图像序列的名称、路径、开始、结束帧数等等。
4.
相关文章:
在matlab中使用UAV123官方toolkits测试自己的数据集
一、前言 最近需要将自己的跟踪代码在自己拍摄的数据集上进行测试,这里我选择使用 UAV123 官方 toolkits 进行配置。首先需要搞清楚这部分代码是如何运行的,精度图和成功率图是如何绘制出来的,然后再将自己的数据集加进去进行测试。 二、UA…...
《淘宝 API 数据湖构建:实时商品详情入湖 + Apache Kafka 流式处理指南》
随着电商行业的蓬勃发展,淘宝作为头部电商平台,积累了海量的商品数据。构建淘宝 API 数据湖,将实时商品详情数据纳入其中,并借助 Apache Kafka 进行流式处理,能够为企业提供强大的数据支撑,助力精准营销、市…...
HTML5 WebSocket:实现高效实时通讯
一、引言 在当今的 Web 开发领域,实时通讯功能变得越来越重要。例如在线聊天、实时数据更新等场景都需要客户端与服务器之间能够进行高效的双向数据传输。HTML5 引入的 WebSocket 协议为我们提供了一种强大的解决方案,它在单个 TCP 连接上实现了全双工通讯,极大地改善了传统…...
数字人Live_Talking的搭建和使用
Live_Talking是一个实时交互流式数字人,可以实现音视频同步对话。今天咱们来试着部署一下项目。 先来看下本地环境 系统:Ubuntu 22.04 显卡:rtx 3060 cuda: Cuda 12.1 git上推荐cuda11.3,但是我用cuda12.2也搭建成功了。 1、…...
Coupang火箭计划深度攻略:eBay卖家突破韩国市场的三维数据作战模型
一、市场机遇与竞争格局解码 1.1 Coupang生态位分析 用户基数:2600万活跃买家(占韩国成年人口68%) 客单价表现:$82(较eBay韩国站高37%) 流量分布:移动端占比91%(需重点优化移动端详…...
Flask + ajax上传文件(四)--数据入库教程
本教程将详细介绍如何使用Flask后端和AJAX前端实现Excel/csv文件上传,并将数据导入数据库的功能。 一、系统架构概述 前端(HTML+JS) → AJAX请求 → Flask后端 → 数据库 二、环境准备 1. 安装必要库 pip install flask pandas sqlalchemy openpyxl2. 项目结构 data_imp…...
C++ 部署的性能优化方法
一、使用结构体提前存放常用变量 在编写前后处理函数时,通常会多次用到一些变量,比如模型输入 tensor 的 shape,count 等等,若在每个处理函数中都重复计算一次,会增加部署时的计算量。对于这种情况,可以考…...
并发设计模式实战系列(8):Active Object
🌟 大家好,我是摘星! 🌟 今天为大家带来的是并发设计模式实战系列,第8章Active Object,废话不多说直接开始~ 目录 一、核心原理深度拆解 1. 对象与执行解耦架构 2. 核心组件 二、生活化类比ÿ…...
jenkins容器提示磁盘空间过低
进入jenkins容器查看: sudo docker exec -it jenkins sh df -h查看磁盘占用情况: # df -h Filesystem Size Used Avail Use% Mounted on overlay 59G 56G 193M 100% / tmpfs 64M 0 64M 0% /dev shm…...
记一次pdf转Word的技术经历
一、发现问题 前几天在打开一个pdf文件时,遇到了一些问题,在Win10下使用WPS PDF、万兴PDF、Adobe Acrobat、Chrome浏览器打开都是正常显示的;但是在macOS 10.13中使用系统自带的预览程序和Chrome浏览器(由于macOS版本比较老了&am…...
【3分钟准备前端面试】Hybrid开发 谷歌浏览器调试安卓app
查看数据请求,页面dom结构和样式,日志打印输出,页面缓存等浏览器控制台素有功能,方便调试 检查元素,方便bug的定位 注:该文档是谷歌浏览器调试安卓apk内嵌网页 前提 app包需要是debug包,并且app的webview开启debug模式需要翻墙安卓手机打开开发者模式,开启usb调试调试…...
【二分查找】寻找峰值(medium)
6. 寻找峰值(medium) 题⽬描述:解法⼆(⼆分查找算法):算法思路:C 算法代码:Java 算法代码: 题⽬链接:162. 寻找峰值 题⽬描述: 峰值元素是指其值…...
这是一款好用的PDF工具!
用户习惯有时确实非常顽固,想要改变它可能需要漫长的时间。 比如PDF软件,我认为国产的福/昕、万/兴等软件都非常不错,它们贴合国人的使用习惯,操作起来非常顺手。但因为我习惯使用DC,所以在处理PDF文档时,…...
征程 6 逆向自证 hbm 与 bc 一致性
1.引言 在征程 6 算法工具链使用过程中,会存在算法侧与软件侧的交接,偶尔会遇到,需要自证清白的情况,例如: 算法侧反馈:bc 精度没问题,也参考了【征程 6】bc 与 hbm 一致性比对 文章ÿ…...
推荐一个微软官方开源浏览器自动化工具,可以用于UI自动化测试、爬虫等,具备.Net、Java、Python等多个版本!
推荐一个微软官方开源,且功能非常强大的浏览器自动化工具, 让我们很容易控制Chromium、Firefox 和 WebKit 内核的浏览器,实现跨浏览器的网页自动化操作。 01 项目简介 Playwright 一个开源浏览器自动化工具。 支持 Chromium、WebKit 和 Fir…...
深入理解链表:从基础操作到高频面试题解析
目录 一、链表基础概念 1.1 什么是链表? 1.2 链表核心特性 1.3 链表与数组对比 二、链表类型详解 2.1 单向链表 2.2 双向链表 2.3 循环链表 三、链表核心操作实现 3.1 插入操作 3.2 删除操作 四、链表高频面试题精讲 4.1 反转链表(LeetCode…...
【MCP Node.js SDK 全栈进阶指南】高级篇(1):MCP多服务器协作架构
随着业务规模的不断扩大和系统复杂度的提升,单一服务器架构往往无法满足高并发、高可用性和弹性扩展的需求。在MCP生态系统中,多服务器协作架构成为构建大规模应用的必然选择。本文将深入探讨MCP TypeScript-SDK在多服务器环境下的部署、协作和管理,以及如何构建高可用、高性…...
铭记之日(3)——4.28
铭记之日(3)——4.28 25.4.28,绝对是继20.12.19与24.6.26之后,又一个被钉在耻辱柱上的日子。 4.28本质上为12.19的严重恶劣版。 道德败坏、恶劣的大骗子终于在今日穿帮落马。 斯文面孔下,竟藏匿了如此罪恶幽暗混沌的内心。 24.10.20&…...
4月28日信息差全景:国际局势、科技突破与市场震荡一、国际政治与安全:俄乌冲突关键转折
一、国际政治与安全:俄乌冲突关键转折 1. 乌克兰反攻进展与情报差异 前线动态: 俄国防部称在顿涅茨克击退乌军三次进攻,摧毁12辆坦克;乌方则宣布在巴赫穆特南部推进2公里,双方战报存在显著差异。 信息差根源:战场信息管控导致西方媒体与俄媒报道截然不同。 国际援助: 美…...
Docker 容器虚拟化技术和自动化部署
Docker 容器虚拟化技术和自动化部署 一、Docker 核心组件1.1 Docker 引擎1.2 Docker 镜像1.3 Docker 容器1.4 Docker 仓库 二、Docker 环境安装清华镜像安装 三、Docker 基本操作3.1 镜像管理3.1.1 查看本地镜像 docker images3.1.2 添加镜像标签 docker tag3.1.3 查看镜像信息…...
人物5_My roommate
こんにちは Today, I will continue to share my life in JaPan. Everyone both know I couldn’t say JanPanese fluently【But I still learn this Language, I think it’s interesting for me{maybe it’s one exciting challenge, I want become a challenger that it li…...
OpenResty技术深度解析:原理、应用与生态对比-优雅草卓伊凡
OpenResty技术深度解析:原理、应用与生态对比-优雅草卓伊凡 一、OpenResty技术概述 1.1 OpenResty是什么? OpenResty是一个基于Nginx的高性能Web平台,它将标准的Nginx核心与一系列强大的第三方模块(主要是LuaJIT)捆绑在一起,形成了一个全功能的Web应用服务器。不同于传…...
深度学习任务评估指标
一、概念篇 混淆矩阵有何作用? 混淆矩阵(Confusion Matrix)是用于评估分类模型性能的工具,它展示了模型预测结果与实际标签之间的对比。混淆矩阵通常包括四个关键元素: True Positive (TP):模型正确预测为正类的数量。True Negative (TN):模型正确预测为负类的数量。F…...
Python-librosa库提取音频数据的MFCC特征
文章目录 MFCC特征代码分享 MFCC特征 MFCC(Mel-Frequency Cepstral Coefficients)是通过人耳对声音频率的感知方式对音频信号进行处理得到的特征,广泛用于语音识别和音频处理。 代码分享 import os import librosa import pywt import matpl…...
因特网和万维网
本文来源 :腾讯元宝 因特网(Internet)和万维网(World Wide Web,简称WWW)是紧密相关但完全不同的两个概念,它们的核心区别如下: 本质不同 因特网(Internet&#…...
道可云人工智能每日资讯|“人工智能科技体验展”在中国科学技术馆举行
道可云元宇宙每日简报(2025年4月28日)讯,今日元宇宙新鲜事有: 《2025年提升全民数字素养与技能工作要点》发布 近日,中央网信办、教育部、工业和信息化部、人力资源社会保障部联合印发《2025年提升全民数字素养与技能…...
Day8 鼠标控制与32位模式切换
文章目录 1. 例程harib05a(鼠标解读1)2. 例程harib05b(代码整理)3. 例程harib05c(鼠标解读2)4. 例程harib05d(移动鼠标指针)5. 通往32位模式之路 1. 例程harib05a(鼠标解…...
塔能科技:点亮节能之光,赋能工厂与城市
在能源形势日益严峻的当下,节能成为了各行各业的关键任务。工厂作为能耗大户,降低能耗迫在眉睫;市政照明作为城市运行的基本保障,也急需向绿色节能转型。塔能科技凭借其能源精准节能和定制开发的核心能力,为工厂节能和…...
UDP 报文结构与注意事项总结
目录 一、UDP报文结构简介 1. 源端口号(Source Port,16位): 2. 目的端口号(Destination Port,16位): 3. 长度(Length,16位): 4. 校…...
DBeaver CE 24.1.3 (Windows 64位) 详细安装教程
1. 下载安装包 dbeaver-ce-24.1.3-x86_64-setup.exe下载链接:https://pan.quark.cn/s/5a8dc9ad747f。 下载完成后,双击运行安装程序。 2. 运行安装向导 选择语言:安装程序启动后,选择安装语言(如英文或中文ÿ…...
Java多线程之线程控制
1、线程睡眠——sleep 如果我们需要让当前正在执行的线程暂停一段时间,并进入阻塞状态,则可以通过调用Thread的sleep方法 注意如下几点问题 ①、sleep是静态方法,最好不要用Thread的实例对象调用它,因为它睡眠的始终是当前正在运…...
任意波形发生器——2路同步DA模拟量输出卡
定义 任意波形发生器(Arbitrary Waveform Generator, AWG)是一种电子测试仪器,能够通过数字信号处理(DSP)和数模转换(DAC)技术生成非周期性、可编程的任意形状电信号。与传统函数发生器仅支持…...
【Java】 使用 HTTP 响应状态码定义web系统返回码
系统状态码定义 public interface GlobalErrorCodeConstants {ErrorCode SUCCESS new ErrorCode(0, "成功");// 客户端错误段 ErrorCode BAD_REQUEST new ErrorCode(400, "请求参数不正确");ErrorCode UNAUTHORIZED new ErrorCode(401, "账号未登…...
测试反馈陷入死循环?5大策略拆解新旧Bug难题
新旧Bug堆叠,测试反馈陷入死循环,如果不及时解决此问题,往往容易导致项目延期、成本增加、团队效率降低,直接影响产品的市场竞争力 。因此需及时应对此问题,进而保障项目进度如期进行,提升软件质量…...
结合大语言模型的机械臂抓取操作学习
结合大语言模型的机械臂抓取操作学习(完整ppt和代码)无视频 代码能正常运行时不负责答疑! 电子产品,一经出售,概不退换 算法设计、毕业设计、期刊专利!感兴趣可以联系我。 🏆代码获取方式1: 私信…...
待验证---Oracle 19c 在 CentOS 7 上的快速安装部署指南
Oracle 19c 在 CentOS 7 上的快速安装部署指南 Oracle Database 19c 是一个功能强大的企业级数据库系统,下面我将为您提供在 CentOS 7 上快速安装部署 Oracle 19c 的详细步骤。 一、准备工作 1. 系统要求 CentOS 7 (64位)最小内存: 2GB (推荐 8GB 以上)最小磁盘…...
风力发电领域canopen转Profinet网关的应用
在风力发电领域,开疆canopen转Profinet网关KJ-PNG-205的应用案例通常涉及将风力涡轮机内部的CANopen网络与外部的Profinet工业以太网连接起来。这种转换网关允许风力发电场的控制系统通过Profinet协议收集和监控涡轮机的状态信息,同时发送控制命令。 风力…...
vr全景相机如何选择?
VR全景相机,作为虚拟现实技术的核心设备之一,能够拍摄360度全景照片和视频,使用户通过虚拟现实设备身临其境地体验拍摄场景。 这种技术的快速发展,得益于传感器、图像处理和计算机视觉技术的不断进步。 选择一台合适的VR全景相机…...
在 Conda 中,包的安装路径在电脑的哪里
在 Conda 中,包的安装路径取决于你的 Conda 安装方式 和 环境类型(base 或其他虚拟环境)。以下是不同情况下的详细说明: 📌 1. Conda 包的默认安装路径 Conda 将所有包存储在 pkgs 目录 下,并在各个环境中…...
phpstorm用php连接数据库报错
项目场景: phpstorm用php连接数据库 问题描述 用php使用mysql_connect 的时候报错了,没有这个函数 原因分析: php解释器问题,后来查资料得知mysql_connct只适用于php5.5以下解释器。一开始用的7,改成5.3以后还是报…...
今日行情明日机会——20250428
指数依然在震荡区间,等待方向选择~ 2025年4月28日涨停主要行业方向分析 一、核心主线方向 一季报增长(业绩驱动资金避险) • 涨停家数:10家(最强方向)。 • 代表标的: ◦ 珀莱雅(2…...
Spring Boot 3与JDK 8环境下的单元测试实践指南
一、引言 在Java后端开发中,单元测试是保障代码质量的核心手段。Spring Boot作为主流框架,其单元测试体系随着版本迭代不断优化。本文聚焦于JDK 8与Spring Boot 3的组合场景,深入解析单元测试的多种实现方式,对比不同测试策略的异…...
微分与积分(前言)
导数 导数是一个非常重要的概念,先来看一个引例:速度问题。历史上速度问题与倒数概念的形成有着密切的关系。 平均速度 v s t v\frac{s}{t} vts那么如何表示瞬时速度呢? 瞬时经过路程: Δ s s ( t 0 Δ t ) − s ( t 0 ) Δ…...
61. Java 类和对象 - 使用 this 关键字
文章目录 61. Java 类和对象 - 使用 this 关键字1. 在方法或构造函数中引用对象成员1.1 区分同名变量1.2 在普通方法中引用字段或调用方法 2. 在构造函数中调用另一个构造函数示例:构造函数重载 3. 其他用法:返回当前对象4. 注意事项5. 总结 61. Java 类…...
安达发|高效智能塑料切割数控系统 - 全自动化软件解决方案
在当今的制造业中,塑料作为一种轻便、耐用且成本效益高的材料,被广泛应用于各个领域。随着科技的进步和市场需求的变化,塑料加工行业正面临着前所未有的挑战和机遇。为了提高生产效率,降低成本,并满足日益严格的质量标…...
20250428-AI Agent:智能体的演进与未来
目录 一、AI Agent的定义与演进 1.1 传统AI Agent的发展历程 1.2 现代AI Agent的技术突破 二、AI Agent的核心组件 2.1 大模型动态推理规划 2.2 工具系统的演进 2.3 记忆模块的设计 三、AI Agent的工作流程 3.1 感知阶段 3.2 推理阶段 3.3 决策阶段 3.4 执行阶段 …...
微信小程序分页和下拉刷新
在page.json中配置下拉刷新和底部距顶部的距离: {"path": "school-detail","style": {"navigationStyle": "custom","navigationBarTextStyle": "black","enablePullDownRefresh&quo…...
文献阅读(一)植物应对干旱的生理学反应 | The physiology of plant responses to drought
分享一篇Science上的综述文章,主要探讨了植物应对干旱的生理机制,强调通过调控激素信号提升植物耐旱性、保障粮食安全的重要性。 摘要 干旱每年致使农作物产量的损失,比所有病原体造成损失的总和还要多。为适应土壤中的湿度梯度变化&#x…...
开源CMS系统的SEO优化功能主要依赖哪些插件?
在当今互联网时代,搜索引擎优化(SEO)是网站获取流量的核心手段之一。开源内容管理系统(CMS)因其灵活性和丰富的插件生态,成为许多开发者和企业的首选。本文将以主流开源CMS为例,深入解析其SEO优…...
YUM/DNF管理工具
YUM (Yellow dog Updater, Modified) , RHEL8 中默认使用的软件批量管理工具由原版本的 yum 换成了速度更快的 dnf ( DNF Dandified YUM ),原有的 yum 命令仅为 dnf 的软链接,当然依旧可以使用。 [root…...