屏蔽Tracked事件

本文介绍了一个使用C#实现的SuperMap GIS应用案例,主要内容包括地图组件的加载过程以及事件委托的绑定与解除绑定操作。通过具体代码展示了如何在应用程序中初始化地图并设置事件响应。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

外面使用的代码为:

 

1、将下面代码所提取的视频的的第一帧图片,也就是(% 2. 获取第一帧用于设置警戒线)这一步骤进行“灰度化 → 高斯滤波 → 梯度计算 → 自适应阈值 → 交互测量”这一操作。最终效果是:用户点击两个点之间的直线长度为1cm,然后再点击两个点,根据刚才的1CM计算出这两点之间的距离。 2、报警部分。报警部分在警报后停止视频继续播放,并只要记录第一次超过警戒线的时间。 function video_surveillance_system() % 清除工作区 close all; clear; clc; % 1. 读取视频文件 [filename, pathname] = uigetfile({'*.mp4;*.avi;*.mov','视频文件'}, '选择监控视频'); if isequal(filename, 0) disp('用户取消选择'); return; end video_path = fullfile(pathname, filename); video_reader = VideoReader(video_path); % 2. 获取第一帧用于设置警戒线 first_frame = readFrame(video_reader); fig = figure('Name', '视频监控系统 - 警戒线设置', 'NumberTitle', 'off', 'Position', [100, 100, 1200, 600]); subplot(1,2,1); h_img = imshow(first_frame); title('原始视频帧', 'FontSize', 12); hold on; % 3. 手动设置警戒线 subplot(1,2,2); imshow(first_frame); title('请设置警戒线:点击起点和终点', 'FontSize', 12); hold on; % 获取用户设置的两个点 [x, y] = ginput(2); line_start = [x(1), y(1)]; line_end = [x(2), y(2)]; % 绘制警戒线 plot([line_start(1), line_end(1)], [line_start(2), line_end(2)], 'r-', 'LineWidth', 3); plot(line_start(1), line_start(2), 'go', 'MarkerSize', 10, 'MarkerFaceColor', 'g'); plot(line_end(1), line_end(2), 'ro', 'MarkerSize', 10, 'MarkerFaceColor', 'r'); title('警戒线设置完成', 'FontSize', 12); % 4. 初始化报警记录 alarm_log = table('Size', [0, 3], ... 'VariableTypes', {'double', 'double', 'double'}, ... 'VariableNames', {'FrameNumber', 'Timestamp', 'ObjectID'}); % 5. 创建报警日志文件 log_filename = 'alarm_log.csv'; fid = fopen(log_filename, 'w'); fprintf(fid, 'FrameNumber,Timestamp(s),ObjectID\n'); fclose(fid); % 6. 初始化背景减法器 detector = vision.ForegroundDetector('NumGaussians', 3, 'NumTrainingFrames', 50, ... 'MinimumBackgroundRatio', 0.7, 'LearningRate', 0.005); % 7. 创建斑点分析器 blob_analyzer = vision.BlobAnalysis('BoundingBoxOutputPort', true, ... 'AreaOutputPort', true, ... 'CentroidOutputPort', true, ... 'MinimumBlobArea', 500); % 8. 主处理循环 frame_count = 0; prev_centroids = []; tracked_objects = {}; next_id = 1; % 创建处理结果展示窗口 result_fig = figure('Name', '视频监控系统 - 实时分析', 'NumberTitle', 'off', 'Position', [100, 100, 1200, 600]); while hasFrame(video_reader) frame = readFrame(video_reader); frame_count = frame_count + 1; timestamp = frame_count / video_reader.FrameRate; % 9. 运动目标检测 gray_frame = rgb2gray(frame); foreground_mask = detector.step(gray_frame); % 形态学操作去除噪声 se = strel('square', 3); cleaned_mask = imopen(foreground_mask, se); cleaned_mask = imclose(cleaned_mask, se); cleaned_mask = imfill(cleaned_mask, 'holes'); % 10. 目标检测与跟踪 [areas, centroids, bboxes] = blob_analyzer.step(cleaned_mask); % 目标跟踪 [tracked_objects, next_id] = track_objects(centroids, tracked_objects, next_id); % 11. 越线检测 current_centroids = centroids; alarm_triggered = false; alarm_positions = []; object_ids = []; for i = 1:size(current_centroids, 1) centroid = current_centroids(i, :); object_id = tracked_objects{i}.id; % 检查是否越过警戒线 if is_crossing_line(line_start, line_end, centroid) alarm_triggered = true; alarm_positions = [alarm_positions; centroid]; object_ids = [object_ids; object_id]; % 记录报警信息 new_entry = {frame_count, timestamp, object_id}; alarm_log = [alarm_log; new_entry]; % 写入日志文件 fid = fopen(log_filename, 'a'); fprintf(fid, '%d,%.2f,%d\n', frame_count, timestamp, object_id); fclose(fid); end end % 12. 显示处理结果 figure(result_fig); subplot(1,2,1); imshow(frame); hold on; % 绘制警戒线 plot([line_start(1), line_end(1)], [line_start(2), line_end(2)], 'r-', 'LineWidth', 3); plot(line_start(1), line_start(2), 'go', 'MarkerSize', 10, 'MarkerFaceColor', 'g'); plot(line_end(1), line_end(2), 'ro', 'MarkerSize', 10, 'MarkerFaceColor', 'r'); % 绘制检测到的目标 for i = 1:size(centroids, 1) centroid = centroids(i, :); object_id = tracked_objects{i}.id; % 绘制目标边界框和ID bbox = bboxes(i, :); rectangle('Position', bbox, 'EdgeColor', 'g', 'LineWidth', 2); text(bbox(1), bbox(2)-10, sprintf('ID: %d', object_id), ... 'Color', 'g', 'FontSize', 10, 'FontWeight', 'bold'); end % 显示报警信息 if alarm_triggered for i = 1:size(alarm_positions, 1) pos = alarm_positions(i, :); plot(pos(1), pos(2), 'rx', 'MarkerSize', 20, 'LineWidth', 3); text(pos(1)+20, pos(2)+20, 'ALARM!', 'Color', 'r', ... 'FontSize', 16, 'FontWeight', 'bold'); end title(sprintf('帧号: %d, 时间: %.2f秒 - 检测到越线!', frame_count, timestamp), ... 'Color', 'r', 'FontSize', 14); else title(sprintf('帧号: %d, 时间: %.2f秒', frame_count, timestamp), 'FontSize', 14); end % 显示运动目标检测结果 subplot(1,2,2); imshow(cleaned_mask); title('运动目标检测结果', 'FontSize', 12); % 刷新显示 drawnow; % 控制处理速度 pause(0.5 / video_reader.FrameRate); end % 13. 显示报警日志 disp('===== 报警事件记录 ====='); disp(alarm_log); % 14. 绘制报警事件时间分布 figure('Name', '报警事件时间分布', 'NumberTitle', 'off'); if ~isempty(alarm_log) plot(alarm_log.Timestamp, alarm_log.ObjectID, 'ro', 'MarkerSize', 8, 'MarkerFaceColor', 'r'); xlabel('时间 (秒)', 'FontSize', 12); ylabel('目标ID', 'FontSize', 12); title('报警事件时间分布', 'FontSize', 14); grid on; else text(0.5, 0.5, '未检测到报警事件', 'HorizontalAlignment', 'center', 'FontSize', 16); end % 15. 保存报警日志 writetable(alarm_log, 'alarm_log_full.csv'); disp('处理完成!报警日志已保存为 alarm_log.csv 和 alarm_log_full.csv'); end % 目标跟踪函数 function [tracked_objects, next_id] = track_objects(centroids, tracked_objects, next_id) % 初始化新的跟踪对象列表 new_tracked_objects = cell(size(centroids, 1), 1); % 如果没有检测到目标,重置跟踪 if isempty(centroids) tracked_objects = {}; return; end % 如果没有现有跟踪对象,创建新对象 if isempty(tracked_objects) for i = 1:size(centroids, 1) new_tracked_objects{i} = struct('id', next_id, 'centroid', centroids(i, :)); next_id = next_id + 1; end tracked_objects = new_tracked_objects; return; end % 计算现有对象和新检测点之间的距离 num_existing = length(tracked_objects); num_new = size(centroids, 1); distances = zeros(num_existing, num_new); for i = 1:num_existing for j = 1:num_new distances(i, j) = norm(tracked_objects{i}.centroid - centroids(j, :)); end end % 分配ID给检测到的目标 assigned = false(num_new, 1); for i = 1:num_existing [min_dist, idx] = min(distances(i, :)); if min_dist < 50 % 距离阈值 tracked_objects{i}.centroid = centroids(idx, :); new_tracked_objects{idx} = tracked_objects{i}; assigned(idx) = true; distances(:, idx) = inf; % 标记为已分配 end end % 为未分配的目标创建新ID for i = 1:num_new if ~assigned(i) new_tracked_objects{i} = struct('id', next_id, 'centroid', centroids(i, :)); next_id = next_id + 1; end end tracked_objects = new_tracked_objects; end % 越线检测函数 function crossing = is_crossing_line(line_start, line_end, point) % 计算点到直线的距离 numerator = abs((line_end(2)-line_start(2))*point(1) - ... (line_end(1)-line_start(1))*point(2) + ... line_end(1)*line_start(2) - line_end(2)*line_start(1)); denominator = norm(line_end - line_start); distance = numerator / denominator; % 计算点到线段起止点的距离 dist_to_start = norm(point - line_start); dist_to_end = norm(point - line_end); % 计算线段长度 line_length = norm(line_end - line_start); % 检查点是否在警戒线附近 proximity_threshold = line_length * 0.05; % 警戒线长度的5% crossing = (distance < 15) && (dist_to_start < line_length + proximity_threshold) && ... (dist_to_end < line_length + proximity_threshold); end
最新发布
07-20
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值