| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177 |
- clc;
- clear;
- close('all');
- addpath('../../ref');
- addpath('../../ref/check_sum');
- FRAME_HEADER = 'RadarEye';
- FRAME_END = 'REND';
- MAX_LENGTH = 1000000;
- isGui = 1;
- if isGui
- hGui = struct();
- hGui.Figure = figure('WindowState', 'maximized');
-
- hGui.Axes_image = subplot(3, 4, [1,2,5,6]);
- hGui.hDataImage = imagesc(nan(320, 680, 3));
- axis image
- set(gca, 'XTick', [], 'YTick', []);
- imageT=title('CAMERA', 'FontSize', 16, 'FontWeight', 'bold');
-
- hGui.Axes_vr = subplot(3,4,[9,10]);
- hGui.fftv = imagesc(128, 128, nan(128, 128));
- grid minor;
- axis xy;
- box on;
- set(gca, 'FontSize', 12);
- xlabel('VelIdx', 'FontSize', 14);
- ylabel('RngIdx', 'FontSize', 14);
- title('fftv', 'FontSize', 16, 'FontWeight', 'bold');
-
- hGui.Axes_xy = subplot(3, 4, [3,7,11]);
- hGui.hDataPointZY = scatter(nan, nan, 'oG');
- axis xy;
- grid minor;
- xlim(10*[ -1, +1, ]);
- ylim(60*[ 0, 1, ]);
- set(gca, 'FontSize', 12);
- xlabel('Z (m)', 'FontSize', 14);
- ylabel('Y (m)', 'FontSize', 14);
- title('Point', 'FontSize', 16);
- hGui.Axes_xy = subplot(3, 4, [4,8,12]);
- hGui.hDataPointXYPZ = scatter(nan, nan, 'blue','oG');
- hold on;
- hGui.hDataPointXYNZ = scatter(nan, nan, 'red','oG');
- axis xy;
- grid minor;
- xlim(10*[ -1, +1, ]);
- ylim(60*[ 0, 1, ]);
- set(gca, 'FontSize', 12);
- xlabel('X (m)', 'FontSize', 14);
- ylabel('Y (m)', 'FontSize', 14);
- title('Point', 'FontSize', 16);
- end
- if isGui
- hGui_ref = struct();
- hGui_ref.Figure = figure('WindowState', 'maximized');
-
- hGui_ref.Axes_xy = subplot(3, 4, [2,6,10]);
- hGui_ref.hDataPointZY = scatter(nan, nan, 'oG');
- axis xy;
- grid minor;
- xlim(10*[ -1, +1, ]);
- ylim(60*[ 0, 1, ]);
- set(gca, 'FontSize', 12);
- xlabel('Z (m)', 'FontSize', 14);
- ylabel('Y (m)', 'FontSize', 14);
- title('Rotation Point', 'FontSize', 16);
- hGui_ref.Axes_xy = subplot(3, 4, [1,5,9]);
- hGui_ref.hDataPointZY_before = scatter(nan, nan, 'oG');
- axis xy;
- grid minor;
- xlim(10*[ -1, +1, ]);
- ylim(60*[ 0, 1, ]);
- set(gca, 'FontSize', 12);
- xlabel('Z (m)', 'FontSize', 14);
- ylabel('Y (m)', 'FontSize', 14);
- title('Raw Point', 'FontSize', 16);
- hGui_ref.Axes_xy = subplot(3, 4, [4,8,12]);
- hGui_ref.hDataPointXYPZ = scatter(nan, nan, 'blue','oG');
- hold on;
- hGui_ref.hDataPointXYNZ = scatter(nan, nan, 'red','oG');
- axis xy;
- grid minor;
- xlim(10*[ -1, +1, ]);
- ylim(60*[ 0, 1, ]);
- set(gca, 'FontSize', 12);
- xlabel('X (m)', 'FontSize', 14);
- ylabel('Y (m)', 'FontSize', 14);
- title('Rotation Point', 'FontSize', 16);
- hGui_ref.Axes_xy = subplot(3, 4, [3,7,11]);
- hGui_ref.hDataPointXYPZ_before = scatter(nan, nan, 'blue','oG');
- hold on;
- hGui_ref.hDataPointXYNZ_before = scatter(nan, nan, 'red','oG');
- axis xy;
- grid minor;
- xlim(10*[ -1, +1, ]);
- ylim(60*[ 0, 1, ]);
- set(gca, 'FontSize', 12);
- xlabel('X (m)', 'FontSize', 14);
- ylabel('Y (m)', 'FontSize', 14);
- title('Raw Point', 'FontSize', 16);
- end
- if isGui
- hGui_filter = struct();
- hGui_filter.Figure = figure('WindowState', 'maximized');
-
- hGui_filter.Axes_raw = subplot(1, 2, 1);
- hGui_filter.raw_hDataPointXYPZ = scatter(nan, nan, 'blue','oG');
- hold on;
- hGui_filter.raw_hDataPointXYNZ = scatter(nan, nan, 'red','oG');
- axis xy;
- grid minor;
- xlim(10*[ -1, +1, ]);
- ylim(60*[ 0, 1, ]);
- set(gca, 'FontSize', 12);
- xlabel('X (m)', 'FontSize', 14);
- ylabel('Y (m)', 'FontSize', 14);
- title('Raw Point', 'FontSize', 16);
- hGui_filter.Axes_filter = subplot(1, 2, 2);
- hGui_filter.filter_hDataPointXYPZ = scatter(nan, nan, 'blue','oG');
- hold on;
- hGui_filter.filter_hDataPointXYNZ = scatter(nan, nan, 'red','oG');
- hold on;
- hGui_filter.cluster_hDataPointXYNZ = scatter(nan, nan, 'green','filled');
- axis xy;
- grid minor;
- xlim(10*[ -1, +1, ]);
- ylim(60*[ 0, 1, ]);
- set(gca, 'FontSize', 12);
- xlabel('X (m)', 'FontSize', 14);
- ylabel('Y (m)', 'FontSize', 14);
- title('Filter Point', 'FontSize', 16);
- end
- % ====== 初始化图像 ======
- global t0 time_hist dist_hist dist_hist2 hPlot hPlot2
- t0 = tic;
- time_hist = [];
- dist_hist = [];
- dist_hist2 = [];
- figure; hold on; grid on;
- hPlot = plot(nan, nan, 'r.-', 'LineWidth', 1.5);
- hPlot2 = plot(nan, nan, 'b.-', 'LineWidth', 1.5);
- xlabel('Time (s)');
- ylabel('Nearest Cluster Distance (m)');
- title('Obstacle Distance vs Time');
- targetFrame = struct();
- ori_point = struct();
- cfar_point = struct();
- tempdata=[];
- % axis image
- % set(gca, 'XTick', [], 'YTick', []);
- % title('CAMERA', 'FontSize', 16, 'FontWeight', 'bold');
- path = 'C:\Users\VK\Desktop\nationstech\采样分析专用\采样数据\250929\20250929_163854_340';
- listBin = dir(fullfile(path, '*.bin'));
- numBin = length(listBin);
- fprintf(" numBin %d \r\n",numBin);
- pc_hist = cell(10,1); % pc_hist{1}: 上一帧(t-1),pc_hist{2}: 上上帧(t-2)
- q_hist = cell(10,1);
- pos_hist = cell(10,1);
- dataBuffer = [];
- idxBin = 1;
- %%%第一版聚类参数
- cluster_params_1 = [ ...
- struct('y_min',0,'y_max',15,'dist_thresh',0.5,'min_points',4); ...
- struct('y_min',16,'y_max',25,'dist_thresh',0.8,'min_points',3); ...
- struct('y_min',25,'y_max',50,'dist_thresh',1.5,'min_points',3); ...
- ];
- %%%第二版聚类参数
- cluster_params = [ ...
- struct('y_min',0,'y_max',10,'dist_thresh',0.5,'min_points',4); ...
- struct('y_min',10.1,'y_max',20,'dist_thresh',1,'min_points',3); ...
- struct('y_min',20.1,'y_max',35,'dist_thresh',1.8,'min_points',3); ...
- ];
- % 原始定义追踪参数
- params_1.match_thresh = 2; % 匹配阈值 (米)
- params_1.inc_val = 1; % 命中 +1
- params_1.dec_val = 1; % 丢失 -1
- params_1.min_conf = 3; % 置信度 >=3 才显示
- % 第二版定义追踪参数
- params_2.match_thresh = 1.3; % 匹配阈值 (米)
- params_2.inc_val = 1; % 命中 +1
- params_2.dec_val = 1; % 丢失 -1
- params_2.min_conf = 2; % 置信度 >=2 才显示
- all_points = [];
- points_body_cur =[];
- while(idxBin <= numBin)
- % 读取被测雷达数据文件
- pathBin = fullfile(path, listBin(idxBin).name);
- [ ~, currentTimestr, ~, ] = fileparts(pathBin);
- currentTime = datetime(currentTimestr, ...
- 'InputFormat', 'uuuuMMdd_HHmmss_SSSSSS');
- % fileBin = fopen(pathBin, 'rb');
- % dataBin = uint8(fread(fileBin, inf, 'uint8')).';
- % fclose(fileBin);
- [pose, radarData] = read_bin_with_pose(pathBin);
- dataBuffer = cat(2, dataBuffer, radarData);
- quat = pose(1:4);
- pos = pose(5:7);
- euler = quat2euler_enu(quat); % 转换为欧拉角
- [ listFrame, dataBuffer] = extract_frame(dataBuffer);
- numFrame = length(listFrame);
- % disp(currentTime);
- idxFrame = 1;
- while (idxFrame <= numFrame)
- frame = listFrame(idxFrame);
- % fprintf("Type %d\r\n",frame.Type);
- paramAlg.ResRng = single(0.6958);
- paramAlg.ResVel = single(0.3519);
- switch frame.Type
- case 7 %点云数据
- framePayload = struct();
- framePayload.Idx = int32(typecast(frame.Raw(4 + (1:4)), 'uint32'));
- framePayload.Tick = int32(typecast(frame.Raw(8 + (1:4)), 'uint32'));
- framePayload.NumPoint = uint32(typecast(frame.Raw(12 + (1:4)), 'uint32'));
-
- % ori_point.num = framePayload.NumPoint;
- ori_point.r=[];
- ori_point.v=[];
- ori_point.Azi=[];
- ori_point.Ele=[];
- ori_point.pow=[];
- ori_point.x=[];
- ori_point.y=[];
- ori_point.z=[];
- numBytePerPoint = int32(100);
- idx = 0;
- % fprintf("Type %d, idx %d , tick %d , num %d\r\n" ...
- % ,frame.Type,framePayload.Idx,framePayload.Tick,framePayload.NumPoint);
-
- for idxPoint = 1:framePayload.NumPoint
- rIdx = typecast(frame.Raw(int32(16) + (int32(idxPoint) - 1)*numBytePerPoint + int32(1:4)), 'int32');
- vIdx = (typecast(frame.Raw(int32(16) + (int32(idxPoint) - 1)*numBytePerPoint + int32(5:8)), 'int32') - 65);
- pow = typecast(frame.Raw(int32(16) + (int32(idxPoint) - 1)*numBytePerPoint + int32(97:100)), 'int32');
- azi = typecast(frame.Raw(int32(16) + (int32(idxPoint) - 1)*numBytePerPoint + int32(89:92)), 'single');
- ele = typecast(frame.Raw(int32(16) + (int32(idxPoint) - 1)*numBytePerPoint + int32(93:96)), 'single');
- ele = -(ele + 0.18);
- if ele > -15/180*pi && ele < 15/180*pi && powerFilter(rIdx,pow) == 1 %1、去除俯仰角大于20度的点,2、能量过滤
- idx = idx + 1;
- ori_point.r(idx) = single(rIdx)*paramAlg.ResRng;
- ori_point.v(idx) = single(vIdx)*paramAlg.ResVel;
- ori_point.Azi(idx) = (-azi); %X值左右反了,水平角取反
- ori_point.Ele(idx) = ele+12/180*pi; %补偿雷达安装角度值
- % ori_point.Ele(idx) = ele;
- ori_point.pow(idx) = pow;
- ori_point.x(idx) = ori_point.r((idx))*cos(ori_point.Ele((idx)))*sin(ori_point.Azi((idx)));
- ori_point.y(idx) = ori_point.r((idx))*cos(ori_point.Ele((idx)))*cos(ori_point.Azi((idx)));
- ori_point.z(idx) = ori_point.r((idx))*sin(ori_point.Ele((idx)));
- tempdata = cat(1,tempdata,[single(idxBin),single(idxFrame),single(rIdx),ori_point.r(idx),ori_point.v(idx),single(ori_point.pow(idx)),ori_point.x(idx),ori_point.y(idx),ori_point.z(idx),ori_point.Azi(idx),ori_point.Ele(idx),single(1)]);
- % else %记录被过滤掉的点云数据
- % r = single(rIdx)*paramAlg.ResRng;
- % v = single(vIdx)*paramAlg.ResVel;
- % azi = -azi;
- % ele = ele+12/180*pi;
- % x = r*cos(ele)*sin(azi);
- % y = r*cos(ele)*cos(azi);
- % z = r*sin(ele);
- % tempdata = cat(1,tempdata,[single(idxBin),single(idxFrame),single(rIdx),r,v,single(pow),x,y,z,azi,ele,single(0)]);
- end
- end
- ori_point.num = idx;
- %%%%%%%%%%%%%%%%%%%%%%%%% 点云旋转 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
- if ori_point.num > 0
- % 构造点云矩阵
- points_body_cur = [ori_point.x(:), ori_point.y(:), ori_point.z(:)]; % N×3
-
- quat_cur = quat(:)'; % pose(1:4) = [w x y z]
- pos_cur = pos(:)';
- %%%%%% 最新帧点云进行姿态转换
-
- R_body2enu = quat2rotm(quat_cur); % 机体系 -> ENU系
- points_enu_raw = (R_body2enu * points_body_cur')';
- q_yaw = Quaternion_Enu_ByEuler(-euler(3), 0, 0); % 只保留 yaw
- R_yaw = quat2rotm(q_yaw); % Yaw 补偿旋转
- % 应用 yaw 补偿
- points_enu = (R_yaw * points_enu_raw')';
- cur_point_enu.x = points_enu(:,1);
- cur_point_enu.y = points_enu(:,2);
- cur_point_enu.z = points_enu(:,3);
- cur_point_enu.num = size(points_enu,1);
- % filter_condition_cur = (points_enu(:,3) > -1.8) & (points_enu(:,1) < 10.0) ...
- % & (points_enu(:,1) > -10.0) & (points_enu(:,2) < 30.0);
- % filtered_points = points_enu(filter_condition_cur, :);
-
- % all_points = points_enu;
- if euler(2) < -0.16
- ratio_posz = sum(points_enu(:,3) < 0) / cur_point_enu.num;
- if ratio_posz >= 0.6
- % 过滤掉当前点云
- % disp('当前帧点云被丢弃: z>0 占比过高');
- % cur_point_enu.num = 0;
- % cur_point_enu.x = [];
- % cur_point_enu.y = [];
- % cur_point_enu.z = [];
- points_body_cur = 0;
- all_points = [];
- else
- all_points = points_enu;
- end
- else
- all_points = points_enu;
- end
-
- %%%%%% 历史帧点云进行旋转映射
- %%% 第一帧历史点云
- if ~isempty(pc_hist{1})
- quat_hist1 = q_hist{1};
- R_body2enu_hist1 = quat2rotm(quat_hist1); % 机体系 -> ENU系
- points_hist1 = (R_body2enu_hist1 * pc_hist{1}')';
- points_enu_hist1 = points_hist1 + pos_hist{1} - pos_cur;
- points_rfu_hist1 = (R_yaw * points_enu_hist1')';
- all_points = [all_points; points_rfu_hist1];
-
- end
- %%% 第二帧历史点云
- if ~isempty(pc_hist{2})
- quat_hist2 = q_hist{2};
- R_body2enu_hist2 = quat2rotm(quat_hist2); % 机体系 -> ENU系
- points_hist2 = (R_body2enu_hist2 * pc_hist{2}')';
- points_enu_hist2 = points_hist2 + pos_hist{2} - pos_cur;
- points_rfu_hist2 = (R_yaw * points_enu_hist2')';
- all_points = [all_points; points_rfu_hist2];
-
- end
- %%% 第三帧历史点云
- if ~isempty(pc_hist{3})
- quat_hist3 = q_hist{3};
- R_body2enu_hist3 = quat2rotm(quat_hist3); % 机体系 -> ENU系
- points_hist3 = (R_body2enu_hist3 * pc_hist{3}')';
- points_enu_hist3 = points_hist3 + pos_hist{3} - pos_cur;
- points_rfu_hist3 = (R_yaw * points_enu_hist3')';
- hist3_point.num = size(points_rfu_hist3,1);
- if(hist3_point.num > 0)
- all_points = [all_points; points_rfu_hist3];
- end
- end
- %%% 第四帧历史点云
- if ~isempty(pc_hist{4})
- quat_hist4 = q_hist{4};
- R_body2enu_hist4 = quat2rotm(quat_hist4); % 机体系 -> ENU系
- points_hist4 = (R_body2enu_hist4 * pc_hist{4}')';
- points_enu_hist4 = points_hist4 + pos_hist{4} - pos_cur;
- points_rfu_hist4 = (R_yaw * points_enu_hist4')';
- hist4_point.num = size(points_rfu_hist4,1);
- if(hist4_point.num > 0)
- all_points = [all_points; points_rfu_hist4];
- end
- end
- %%% 第五帧历史点云
- if ~isempty(pc_hist{5})
- quat_hist5 = q_hist{5};
- R_body2enu_hist5 = quat2rotm(quat_hist5); % 机体系 -> ENU系
- points_hist5 = (R_body2enu_hist5 * pc_hist{5}')';
- points_enu_hist5 = points_hist5 + pos_hist{5} - pos_cur;
- points_rfu_hist5 = (R_yaw * points_enu_hist5')';
- hist5_point.num = size(points_rfu_hist5,1);
- if(hist5_point.num > 0)
- all_points = [all_points; points_rfu_hist5];
- end
- end
- %%% 第六帧历史点云
- if ~isempty(pc_hist{6})
- quat_hist6 = q_hist{6};
- R_body2enu_hist6 = quat2rotm(quat_hist6); % 机体系 -> ENU系
- points_hist6 = (R_body2enu_hist6 * pc_hist{6}')';
- points_enu_hist6 = points_hist6 + pos_hist{6} - pos_cur;
- points_rfu_hist6 = (R_yaw * points_enu_hist6')';
- hist6_point.num = size(points_rfu_hist6,1);
- if(hist6_point.num > 0)
- all_points = [all_points; points_rfu_hist6];
- end
- end
- %%% 第七帧历史点云
- if ~isempty(pc_hist{7})
- quat_hist7 = q_hist{7};
- R_body2enu_hist7 = quat2rotm(quat_hist7); % 机体系 -> ENU系
- points_hist7 = (R_body2enu_hist7 * pc_hist{7}')';
- points_enu_hist7 = points_hist7 + pos_hist{7} - pos_cur;
- points_rfu_hist7 = (R_yaw * points_enu_hist7')';
- hist7_point.num = size(points_rfu_hist7,1);
- if(hist7_point.num > 0)
- all_points = [all_points; points_rfu_hist7];
- end
- end
- %%% 第八帧历史点云
- if ~isempty(pc_hist{8})
- quat_hist8 = q_hist{8};
- R_body2enu_hist8 = quat2rotm(quat_hist8); % 机体系 -> ENU系
- points_hist8 = (R_body2enu_hist8 * pc_hist{8}')';
- points_enu_hist8 = points_hist8 + pos_hist{8} - pos_cur;
- points_rfu_hist8 = (R_yaw * points_enu_hist8')';
- hist8_point.num = size(points_rfu_hist8,1);
- if(hist8_point.num > 0)
- all_points = [all_points; points_rfu_hist8];
- end
- end
- %%% 第九帧历史点云
- if ~isempty(pc_hist{9})
- quat_hist9 = q_hist{9};
- R_body2enu_hist9 = quat2rotm(quat_hist9); % 机体系 -> ENU系
- points_hist9 = (R_body2enu_hist9 * pc_hist{9}')';
- points_enu_hist9 = points_hist9 + pos_hist{9} - pos_cur;
- points_rfu_hist9 = (R_yaw * points_enu_hist9')';
- hist9_point.num = size(points_rfu_hist9,1);
- if(hist9_point.num > 0)
- all_points = [all_points; points_rfu_hist9];
- end
- end
- % %%% 第十帧历史点云
- % if ~isempty(pc_hist{10})
- % quat_hist10 = q_hist{10};
- % R_body2enu_hist10 = quat2rotm(quat_hist10); % 机体系 -> ENU系
- % points_hist10 = (R_body2enu_hist10 * pc_hist{10}')';
- % points_enu_hist10 = points_hist10 + pos_hist{10} - pos_cur;
- % points_rfu_hist10 = (R_yaw * points_enu_hist10')';
- % hist10_point.num = size(points_rfu_hist10,1);
- % if(hist10_point.num > 0)
- % all_points = [all_points; points_rfu_hist10];
- % end
- % end
- if ~isempty(all_points)
- filter_condition_cur = true(size(all_points,1),1);
- for i = 1:size(all_points, 1)
- x_value = all_points(i, 1); % 获取当前点的 x 值
- y_value = all_points(i, 2); % 获取当前点的 y 值
- z_value = all_points(i, 3); % 获取当前点的 z 值
- if y_value >= 35 || y_value <= 0
- filter_condition_cur(i) = false;
- elseif x_value >=10 || x_value <= -10
- filter_condition_cur(i) = false;
- elseif y_value < 5
- % 如果 y < 5,则 z > -2
- if x_value >= 4 || x_value <= -4
- filter_condition_cur(i) = false;
- end
- if z_value <= -1.0
- filter_condition_cur(i) = false;
- end
- elseif y_value >= 5 && y_value < 10
- % 如果 5 <= y < 10,则 z > -1.5
- if x_value >= 7 || x_value <= -7
- filter_condition_cur(i) = false;
- end
- if z_value <= -1.2
- filter_condition_cur(i) = false;
- end
- elseif y_value >= 10
- % 如果 y >= 20,则 z > -1
- if z_value <= -1.0
- filter_condition_cur(i) = false;
- end
- end
- end
-
- filtered_points = all_points(filter_condition_cur, :);
- filtered_point_rfu.x = filtered_points(:, 1);
- filtered_point_rfu.y = filtered_points(:, 2);
- filtered_point_rfu.z = filtered_points(:, 3);
- filtered_point_rfu.num = size(filtered_points, 1);
-
- %%% 聚类
- clusters_all_1 = multiRangeClustering(filtered_point_rfu, cluster_params_1);
- clusters_all = multiRangeClustering(filtered_point_rfu, cluster_params);
- [cx, cy] = updateObstacleTracking(clusters_all, params_2);
- [cx_1, cy_1] = updateObstacleTracking(clusters_all_1, params_1);
-
- % 更新 scatter 数据
- set(hGui_filter.cluster_hDataPointXYNZ, 'XData', cx, 'YData', cy);
- % 找到 y 最小的聚类点
- if ~isempty(cy)
- nearestDist = min(cy);
- else
- nearestDist = 0;
- end
- if ~isempty(cy_1)
- nearestDist2 = min(cy_1);
- else
- nearestDist2 = 0;
- end
-
- % 当前时间
- t = toc(t0);
-
- % 追加数据
- global time_hist dist_hist dist_hist2 hPlot hPlot2
- time_hist(end+1) = t;
- dist_hist(end+1) = nearestDist;
- dist_hist2(end+1) = nearestDist2;
-
- % 更新曲线
- set(hPlot, 'XData', time_hist, 'YData', dist_hist);
- set(hPlot2, 'XData', time_hist, 'YData', dist_hist2);
- drawnow limitrate;
-
- if(filtered_point_rfu.num > 0)
- posIdx_filter = filtered_point_rfu.z>=0;
- negIdx_filter = filtered_point_rfu.z<0;
- if sum(posIdx_filter) > 0
- posZX_filter = filtered_point_rfu.x(posIdx_filter);
- posZY_filter = filtered_point_rfu.y(posIdx_filter);
- posSize = 10;
- else
- posZX_filter = nan;
- posZY_filter = nan;
- posSize = nan;
- end
- if sum(negIdx_filter)
- negZX_filter = filtered_point_rfu.x(negIdx_filter);
- negZY_filter = filtered_point_rfu.y(negIdx_filter);
- negSize = 10;
- else
- negZX_filter = nan;
- negZY_filter = nan;
- negSize = nan;
- end
- %显示Z值大于等于0的点
- hGui_filter.filter_hDataPointXYPZ.XData = posZX_filter;
- hGui_filter.filter_hDataPointXYPZ.YData = posZY_filter;
- hGui_filter.filter_hDataPointXYPZ.SizeData = posSize;
- %显示Z值小于0的点
- hGui_filter.filter_hDataPointXYNZ.XData = negZX_filter;
- hGui_filter.filter_hDataPointXYNZ.YData = negZY_filter;
- hGui_filter.filter_hDataPointXYNZ.SizeData = negSize;
- else
- hGui_filter.filter_hDataPointXYPZ.XData = nan;
- hGui_filter.filter_hDataPointXYPZ.YData = nan;
- hGui_filter.filter_hDataPointXYPZ.SizeData = nan;
- hGui_filter.filter_hDataPointXYNZ.XData = nan;
- hGui_filter.filter_hDataPointXYNZ.YData = nan;
- hGui_filter.filter_hDataPointXYNZ.SizeData = nan;
- end
- end
- %%%%%% 更新历史信息
- % pc_hist{10} = pc_hist{9};
- pc_hist{9} = pc_hist{8};
- pc_hist{8} = pc_hist{7};
- pc_hist{7} = pc_hist{6};
- pc_hist{6} = pc_hist{5};
- pc_hist{5} = pc_hist{4};
- pc_hist{4} = pc_hist{3};
- pc_hist{3} = pc_hist{2};
- pc_hist{2} = pc_hist{1}; % t-2 <- t-1
- pc_hist{1} = points_body_cur; % t-1 <- 当前帧body坐标系点云
-
- % q_hist{10} = q_hist{9};
- q_hist{9} = q_hist{8};
- q_hist{8} = q_hist{7};
- q_hist{7} = q_hist{6};
- q_hist{6} = q_hist{5};
- q_hist{5} = q_hist{4};
- q_hist{4} = q_hist{3};
- q_hist{3} = q_hist{2};
- q_hist{2} = q_hist{1}; % t-2 <- t-1
- q_hist{1} = quat_cur; % t-1 <- 当前帧 Q
-
- % pos_hist{10} = pos_hist{9};
- pos_hist{9} = pos_hist{8};
- pos_hist{8} = pos_hist{7};
- pos_hist{7} = pos_hist{6};
- pos_hist{6} = pos_hist{5};
- pos_hist{5} = pos_hist{4};
- pos_hist{4} = pos_hist{3};
- pos_hist{3} = pos_hist{2};
- pos_hist{2} = pos_hist{1}; % t-2 <- t-1
- pos_hist{1} = pos_cur; % t-1 <- 当前帧 pos
-
- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
- % 更新旋转后点云信息
- if isGui
- if(cur_point_enu.num > 0)
- posIdx = cur_point_enu.z>=0;
- negIdx = cur_point_enu.z<0;
- if sum(posIdx) > 0
- posZX = cur_point_enu.x(posIdx);
- posZY = cur_point_enu.y(posIdx);
- posSize = 10;
- else
- posZX = nan;
- posZY = nan;
- posSize = nan;
- end
- if sum(negIdx)
- negZX = cur_point_enu.x(negIdx);
- negZY = cur_point_enu.y(negIdx);
- negSize = 10;
- else
- negZX = nan;
- negZY = nan;
- negSize = nan;
- end
- %显示Z值大于等于0的点
- hGui_ref.hDataPointXYPZ.XData = posZX;
- hGui_ref.hDataPointXYPZ.YData = posZY;
- hGui_ref.hDataPointXYPZ.SizeData = posSize;
- %显示Z值小于0的点
- hGui_ref.hDataPointXYNZ.XData = negZX;
- hGui_ref.hDataPointXYNZ.YData = negZY;
- hGui_ref.hDataPointXYNZ.SizeData = negSize;
-
- hGui_ref.hDataPointZY.XData = cur_point_enu.z;
- hGui_ref.hDataPointZY.YData = cur_point_enu.y;
- hGui_ref.hDataPointZY.SizeData = 10;%1e-4*double([ ori_point.pow, ] + 1000);
- else
- hGui_ref.hDataPointXYPZ.XData = nan;
- hGui_ref.hDataPointXYPZ.YData = nan;
- hGui_ref.hDataPointXYPZ.SizeData = nan;
-
- hGui_ref.hDataPointXYNZ.XData = nan;
- hGui_ref.hDataPointXYNZ.YData = nan;
- hGui_ref.hDataPointXYNZ.SizeData = nan;
-
- hGui_ref.hDataPointZY.XData = nan;
- hGui_ref.hDataPointZY.YData = nan;
- hGui_ref.hDataPointZY.SizeData = nan;
- end
- end
-
- end
- if isGui
- if(ori_point.num > 0)
- posIdx = ori_point.z>=0;
- negIdx = ori_point.z<0;
- if sum(posIdx) > 0
- posZX = ori_point.x(posIdx);
- posZY = ori_point.y(posIdx);
- posSize = 10;
- else
- posZX = nan;
- posZY = nan;
- posSize = nan;
- end
- if sum(negIdx)
- negZX = ori_point.x(negIdx);
- negZY = ori_point.y(negIdx);
- negSize = 10;
- else
- negZX = nan;
- negZY = nan;
- negSize = nan;
- end
- %显示Z值大于等于0的点
- hGui.hDataPointXYPZ.XData = posZX;
- hGui.hDataPointXYPZ.YData = posZY;
- hGui.hDataPointXYPZ.SizeData = posSize;
- hGui_ref.hDataPointXYPZ_before.XData = posZX;
- hGui_ref.hDataPointXYPZ_before.YData = posZY;
- hGui_ref.hDataPointXYPZ_before.SizeData = posSize;
-
- %显示Z值小于0的点
- hGui.hDataPointXYNZ.XData = negZX;
- hGui.hDataPointXYNZ.YData = negZY;
- hGui.hDataPointXYNZ.SizeData = negSize;
- hGui_ref.hDataPointXYNZ_before.XData = negZX;
- hGui_ref.hDataPointXYNZ_before.YData = negZY;
- hGui_ref.hDataPointXYNZ_before.SizeData = negSize;
-
- hGui.hDataPointZY.XData = ori_point.z;
- hGui.hDataPointZY.YData = ori_point.y;
- hGui.hDataPointZY.SizeData = 10;%1e-4*double([ ori_point.pow, ] + 1000);
- hGui_ref.hDataPointZY_before.XData = ori_point.z;
- hGui_ref.hDataPointZY_before.YData = ori_point.y;
- hGui_ref.hDataPointZY_before.SizeData = 10;%1e-4*double([ ori_point.pow, ] + 1000);
- else
- hGui.hDataPointXYPZ.XData = nan;
- hGui.hDataPointXYPZ.YData = nan;
- hGui.hDataPointXYPZ.SizeData = nan;
- hGui_ref.hDataPointXYPZ_before.XData = nan;
- hGui_ref.hDataPointXYPZ_before.YData = nan;
- hGui_ref.hDataPointXYPZ_before.SizeData = nan;
- hGui.hDataPointXYNZ.XData = nan;
- hGui.hDataPointXYNZ.YData = nan;
- hGui.hDataPointXYNZ.SizeData = nan;
- hGui_ref.hDataPointXYNZ_before.XData = nan;
- hGui_ref.hDataPointXYNZ_before.YData = nan;
- hGui_ref.hDataPointXYNZ_before.SizeData = nan;
- hGui.hDataPointZY.XData = nan;
- hGui.hDataPointZY.YData = nan;
- hGui.hDataPointZY.SizeData = nan;
- hGui_ref.hDataPointZY_before.XData = nan;
- hGui_ref.hDataPointZY_before.YData = nan;
- hGui_ref.hDataPointZY_before.SizeData = nan;
- end
- end
- case 6
- framePayload = struct();
- framePayload.Idx = int32(typecast(frame.Raw(4 + (1:4)), 'uint32'));
- framePayload.Tick = int32(typecast(frame.Raw(8 + (1:4)), 'uint32'));
- framePayload.NumPoint = uint32(typecast(frame.Raw(12 + (1:4)), 'uint32'));
- cfar_point.num = framePayload.NumPoint;
- cfar_point.r = [];
- cfar_point.v = [];
- cfar_point.pow = [];
- numBytePerPoint = int32(100);
- for idxPoint = 1:framePayload.NumPoint
- cfar_point.r(idxPoint) = typecast(frame.Raw(int32(16) + (int32(idxPoint) - 1)*numBytePerPoint + int32(1:4)), 'int32');
- cfar_point.v(idxPoint) = typecast(frame.Raw(int32(16) + (int32(idxPoint) - 1)*numBytePerPoint + int32(5:8)), 'int32') - int32(64);
- cfar_point.pow(idxPoint) = single(typecast(frame.Raw(int32(16) + (int32(idxPoint) - 1)*numBytePerPoint + int32(97:100)), 'int32'));
- end
-
- case 5
- DataBuffer = frame.Raw(13:frame.Length - 8);
-
- total_len = 128 * 8 * 128;
- nt2 = uint8(reshape(DataBuffer,[4,total_len/4]));
-
- for i=1:total_len/4
- nt3(i) = typecast(fliplr(squeeze(nt2(:,i))),'single');
- end
- float_single = complex(nt3(1:2:end),nt3(2:2:end));
-
- ntt4 = reshape(float_single,[128, 128]);
- for k=1:128
- fft2d_abs(:,k)= abs(ntt4(:,k));
- end
- if isGui
- hGui.fftv.CData = fft2d_abs;
- end
-
- end
- idxFrame = idxFrame + 1;
- %显示图片
- oriImage = imread(fullfile(path, ...
- sprintf("%s.jpg", currentTimestr)));
-
- % rotatedImage = imrotate(oriImage, 180, 'bilinear', 'crop');
- % hGui.hDataImage.CData = rotatedImage;
- hGui.hDataImage.CData = oriImage;
- drawnow;
- end
- idxBin = idxBin + 1;
- pause(0.05);
- end
- function [pose, radarData] = read_bin_with_pose(filename)
- % 读取整个bin文件
- fid = fopen(filename, 'rb');
- rawData = uint8(fread(fid, inf,'*uint8')).';
- fclose(fid);
- % 文件至少要有 32 字节才能包含位姿
- if numel(rawData) < 32
- error('文件太短,没有位姿数据');
- end
- % 末尾 32 字节是 float32 位姿
- poseBytes = rawData(end-31:end);
- pose = typecast(poseBytes, 'single'); % [q0,q1,q2,q3,x,y,z,valid]
- % 剩余部分是雷达数据
- radarData = rawData(1:end-32);
- end
- function [listFrame, dataBuffer] = extract_frame(dataBuffer)
- FRAME_HEADER = 'RadarEye';
- FRAME_END = 'REND';
- listFrame = [];
- while true
- lenBuffer = length(dataBuffer);
- % 必须至少有 16 字节(8B帧头 + 4B长度 + 4B类型)
- if lenBuffer < 16
- return; % 等待更多数据
- end
- % 找帧头
- if ~strcmp(char(dataBuffer(1:8)), FRAME_HEADER)
- % 没找到帧头 → 丢掉一个字节继续找
- dataBuffer = dataBuffer(2:end);
- continue;
- end
- % 读取 Length
- frame = struct();
- frame.Header = FRAME_HEADER;
- frame.Length = double(typecast(dataBuffer(9:12), 'uint32'));
- % 合理性检查(防止 Length 乱值)
- if frame.Length <= 0 || frame.Length > 200000
- % 丢掉帧头继续
- dataBuffer = dataBuffer(9:end);
- continue;
- end
- % 数据不足整个帧,等下一轮再处理
- if lenBuffer < 12 + frame.Length
- return;
- end
- % 读取 Type
- frame.Type = typecast(dataBuffer(13:16), 'uint32');
- % 根据 Type 决定校验数据范围
- if frame.Type == 6 || frame.Type == 7
- frame.Check = uint32(0);
- dataToCheck = typecast(dataBuffer(13:(12 + frame.Length - 4)), 'uint32');
- elseif frame.Type == 5
- frame.Length = frame.Length + 12;
- % 再次检查长度
- if frame.Length > 200000 || lenBuffer < 12 + frame.Length
- dataBuffer = dataBuffer(9:end);
- continue;
- end
- frame.Check = uint32(0);
- dataToCheck = typecast(dataBuffer(13:(12 + frame.Length - 4)), 'uint32');
- else
- % 未知类型,丢掉帧头继续
- dataBuffer = dataBuffer(9:end);
- continue;
- end
- % 计算校验和
- for i = 1:length(dataToCheck)
- frame.Check = bitxor(frame.Check, dataToCheck(i));
- end
- % 检查帧尾
- frame.End = char(dataBuffer((12 + frame.Length - 3):(12 + frame.Length)));
- if frame.Check ~= 0 || ~strcmp(frame.End, FRAME_END)
- % 校验失败 → 丢掉一个字节继续
- dataBuffer = dataBuffer(2:end);
- continue;
- end
- % 保存原始数据
- frame.Raw = dataBuffer(13:(12 + frame.Length - 8));
- frame.bin = dataBuffer(1:(12 + frame.Length));
- % 存到结果
- listFrame = [listFrame; frame];
- % 移除已解析的帧
- dataBuffer = dataBuffer((12 + frame.Length + 1):end);
- end
- end
- %根据不同距离不同能量过滤数据
- function isFlag=powerFilter(range,pow)
- isFlag = 0;
- if range < 10 && pow > 1200000
- isFlag = 1;
- elseif range >= 10 && range < 20 && pow > 800000
- isFlag = 1;
- elseif range >= 20 && range < 30 && pow > 500000
- isFlag = 1;
- elseif range >= 30 && range < 40 && pow > 400000
- isFlag = 1;
- elseif range >= 40 && range < 50 && pow > 300000
- isFlag = 1;
- elseif range >= 50 && range < 60 && pow > 200000
- isFlag = 1;
- elseif range >= 60 && range < 70 && pow > 200000
- isFlag = 1;
- elseif range >= 70 && range < 80 && pow > 200000
- isFlag = 1;
- elseif range >= 80 && pow > 200000
- isFlag = 1;
- end
- end
- function euler = quat2euler_enu(Q)
- % Q = [Q0 Q1 Q2 Q3] (标量在前, 与C代码一致)
- q0 = Q(1); q1 = Q(2); q2 = Q(3); q3 = Q(4);
- % 方向余弦矩阵 DCM
- dcm = zeros(3,3);
- q0s = q0*q0; q1s = q1*q1; q2s = q2*q2; q3s = q3*q3;
- dcm(1,1) = q0s + q1s - q2s - q3s;
- dcm(1,2) = 2*(q1*q2 - q0*q3);
- dcm(1,3) = 2*(q0*q2 + q1*q3);
- dcm(2,1) = 2*(q1*q2 + q0*q3);
- dcm(2,2) = q0s - q1s + q2s - q3s;
- dcm(2,3) = 2*(q2*q3 - q0*q1);
- dcm(3,1) = 2*(q1*q3 - q0*q2);
- dcm(3,2) = 2*(q0*q1 + q2*q3);
- dcm(3,3) = q0s - q1s - q2s + q3s;
- % 欧拉角 (ENU 系统,弧度制)
- phi = atan2(-dcm(3,1), dcm(3,3)); % roll
- theta = asin(dcm(3,2)); % pitch
- psi = atan2(-dcm(1,2), dcm(2,2)); % yaw
- % 处理 pitch = ±90° 奇异点
- eps = 1e-4;
- if abs(theta - pi/2) < eps
- phi = 0;
- psi = atan2(-dcm(1,3), -dcm(2,3));
- elseif abs(theta + pi/2) < eps
- phi = 0;
- psi = atan2(dcm(1,3), dcm(2,3));
- end
-
- %弧度制
- euler = [phi, theta, psi]; % [roll pitch yaw]
- % 转换为角度制
- % euler = rad2deg([phi, theta, psi]); % [roll pitch yaw] in degree
- end
- function Q = Quaternion_Enu_ByEuler(yaw, pitch, roll)
- % Quaternion_Enu_ByEuler 将欧拉角(yaw, pitch, roll)转换为四元数
- % 输入角度单位为弧度 (rad)
- % Q = [q0 q1 q2 q3] (标量在前,向量在后)
- % 计算半角的正弦和余弦
- cy = cos(yaw/2);
- cp = cos(pitch/2);
- cr = cos(roll/2);
- sy = sin(yaw/2);
- sp = sin(pitch/2);
- sr = sin(roll/2);
- q0 = cy*cp*cr - sy*sp*sr;
- q1 = cy*sp*cr - sy*cp*sr;
- q2 = cy*cp*sr + sy*sp*cr;
- q3 = cy*sp*sr + sy*cp*cr;
- % 组合成向量
- Q = [q0 q1 q2 q3];
- end
- function clusters = euclideanClusterExtraction(filtered_point_rfu, dist_thresh, min_points)
- % filtered_point_rfu: 结构体,包含 x, y, z, num
- % dist_thresh: 聚类的阈值 (比如 0.5 m)
- % min_points: 最小点数阈值 (比如 3)
- % 转换为矩阵 Nx3
- points = [filtered_point_rfu.x, filtered_point_rfu.y, filtered_point_rfu.z];
- N = size(points, 1);
- visited = false(N, 1); % 标记访问
- cluster_list = {}; % 保存聚类结果
- for i = 1:N
- if ~visited(i)
- % 新的聚类
- cluster_points = points(i, :);
- visited(i) = true;
- % 广度优先搜索(BFS)
- queue = i;
- while ~isempty(queue)
- idx = queue(1);
- queue(1) = []; % 出队
- % 找邻居
- diffs = points - points(idx, :);
- dists = sum(diffs.^2, 2);
- neighbors = find(dists < dist_thresh^2 & ~visited);
- if ~isempty(neighbors)
- visited(neighbors) = true;
- cluster_points = [cluster_points; points(neighbors, :)];
- queue = [queue; neighbors]; %#ok<AGROW>
- end
- end
- % 只保留点数超过 min_points 的聚类
- if size(cluster_points, 1) >= min_points
- cluster_list{end+1} = cluster_points; %#ok<AGROW>
- end
- end
- end
- % 输出格式化结果
- clusters = struct('points', {}, 'center', {}, 'num', {});
- for k = 1:numel(cluster_list)
- pts = cluster_list{k};
- clusters(k).points = pts;
- clusters(k).center = mean(pts, 1);
- clusters(k).num = size(pts, 1);
- end
- end
- function clusters_all = multiRangeClustering(points, params)
- % points: struct,包含 x,y,z,num
- % params: 每个距离区间的聚类参数设置
-
- clusters_all = [];
-
- for i = 1:length(params)
- % 提取该区间的点
- rangeIdx = points.y >= params(i).y_min & points.y < params(i).y_max;
- pts_range = [points.x(rangeIdx), points.y(rangeIdx), points.z(rangeIdx)];
-
- if isempty(pts_range)
- continue;
- end
-
- % 在该区间用对应参数做聚类
- clusters = euclideanClusterExtraction(...
- struct('x',pts_range(:,1),'y',pts_range(:,2),'z',pts_range(:,3),'num',size(pts_range,1)), ...
- params(i).dist_thresh, ...
- params(i).min_points);
-
- % 合并结果
- clusters_all = [clusters_all, clusters];
- end
- end
- function [cx, cy] = updateObstacleTracking(clusters, params)
- persistent trackedTargets
- if isempty(trackedTargets)
- trackedTargets = struct('x', {}, 'y', {}, 'confidence', {}, 'updated', {});
- end
- % --- 提取每个簇的代表点 ---
- numClusters = numel(clusters);
- cx_new = nan(1,numClusters);
- cy_new = nan(1,numClusters);
- for k = 1:numClusters
- pts = clusters(k).points;
- if isempty(pts), continue; end
- [min_y, idx] = min(pts(:,2));
- cx_new(k) = pts(idx,1);
- cy_new(k) = min_y;
- end
- cur_points = [cx_new(:), cy_new(:)];
- % --- 标记所有目标未更新 ---
- for i = 1:numel(trackedTargets)
- trackedTargets(i).updated = false;
- end
- % --- 遍历检测点,更新或新建目标 ---
- for i = 1:size(cur_points,1)
- px = cur_points(i,1);
- py = cur_points(i,2);
- if isnan(px) || isnan(py), continue; end
- % 动态参数选择
- if py <= 10
- match_thresh = 1;
- min_conf = 4;
- max_conf = 6;
- elseif py <= 20
- match_thresh = 1.3;
- min_conf = 2;
- max_conf = 5;
- elseif py <= 35
- match_thresh = 1.8;
- min_conf = 2;
- max_conf = 5;
- else
- continue;
- end
- % --- 匹配已有目标 ---
- dists = arrayfun(@(t) hypot(t.x - px, t.y - py), trackedTargets);
- if isempty(dists)
- minDist = inf;
- else
- [minDist, minIdx] = min(dists);
- end
- if ~isempty(dists) && minDist < match_thresh
- % 命中已有目标
- trackedTargets(minIdx).x = px;
- trackedTargets(minIdx).y = py;
- trackedTargets(minIdx).confidence = ...
- min(trackedTargets(minIdx).confidence + params.inc_val, max_conf);
- trackedTargets(minIdx).updated = true;
- else
- % 新建目标
- newTarget.x = px;
- newTarget.y = py;
- newTarget.confidence = 1; % 初始值
- newTarget.updated = true;
- trackedTargets = [trackedTargets, newTarget];
- end
- end
- % --- 更新置信度 ---
- for i = 1:numel(trackedTargets)
- if ~trackedTargets(i).updated
- trackedTargets(i).confidence = trackedTargets(i).confidence - params.dec_val;
- end
- end
- % 仅保留置信度 > 0 的目标
- if ~isempty(trackedTargets)
- trackedTargets = trackedTargets([trackedTargets.confidence] > 0);
- end
- % --- 生成输出点 ---
- cx = []; cy = [];
- for i = 1:numel(trackedTargets)
- py = trackedTargets(i).y;
- if py <= 10
- min_conf = 4;
- elseif py <= 20
- min_conf = 2;
- elseif py <= 35
- min_conf = 2;
- else
- continue;
- end
- if trackedTargets(i).confidence >= min_conf
- cx(end+1) = trackedTargets(i).x; %#ok<AGROW>
- cy(end+1) = py; %#ok<AGROW>
- end
- end
- if isempty(cx)
- cx = 0; cy = 0;
- end
- end
|