首页
课程
问答
CTF
社区
招聘
峰会
发现
排行榜
知识库
工具下载
看雪20年
看雪商城
证书查询
登录
注册
首页
社区
课程
招聘
发现
问答
CTF
排行榜
知识库
工具下载
峰会
看雪商城
证书查询
社区
编程技术
发新帖
1
0
[原创]腾讯验证码识别之“点击运动最慢的元素”分析
发表于: 2026-9-10 13:10
324
[原创]腾讯验证码识别之“点击运动最慢的元素”分析
你送的花开了
2026-9-10 13:10
324
验证码中有一类动态题型:画面包含多个运动元素,要求点击运动最慢的一个。此类问题属于典型的时序分析任务,可拆解为前景检测、多目标跟踪与速度比较三个环节。本文基于 Python + OpenCV 给出一种实现方案,重点说明前景提取、坐标计算与轨迹速度统计的方法构成。 一、问题定义 输入:一段 WebM 短视频,画面中存在若干近似圆形的运动元素,其中可能混入完全静止的干扰元素。输出:运动最慢元素的中心坐标 (x, y)。需要处理的难点: 完全静止元素的速度恒为 0,必须在速度比较之前剔除; 元素存在交错、短暂消失等情况,跨帧关联必须保证一对一匹配; 输出坐标必须对应提交时刻的元素位置,而非历史某一帧的位置。 二、总体流程 视频读取 → 背景建模 → 前景提取 → 轮廓筛选 → 中心坐标计算 → 跨帧轨迹关联 → 速度统计 → 静止元素剔除 → 最慢目标输出 三、视频读取 使用 cv2.VideoCapture 逐帧读取视频,获取总帧数 N 与帧率 fps。轨迹参与统计需要满足最少观测帧数下限 min_frames,该值由总帧数推导(经验公式形如 max(a, b·N),a、b 为常量)。观测帧数不足的目标不参与判定,避免小样本统计失真。视频处理完毕后,下载到本地的临时文件需要及时删除。 四、背景建模与前景提取 4.1 背景建模 直接在原图上搜索轮廓会引入大量背景干扰,因此先建立背景模型。采用自适应背景差分:为每个像素维护随时间缓慢更新的背景模型 B_t(x, y),当前帧与模型比较后,变化明显的区域即为运动目标。相比取固定帧的中值或均值作为背景,自适应模型对光照缓慢变化和画面轻微抖动更稳定。OpenCV 的 MOG2 类算法即属于此类实现。 4.2 前景提取链路 对当前帧 frame_t 的处理顺序: 灰度化 → 高斯模糊 → 背景差分 → 阈值二值化 → 形态学开运算与闭运算 差分结果 fg_t = |gray_t − B_t|,经阈值二值化得到前景掩码 mask_t;开运算清除孤立噪点,闭运算填补目标内部空洞。mask_t 中高亮区域即候选运动元素。 五、候选轮廓筛选 对前景掩码使用 cv2.findContours 提取外部轮廓,随后进行几何筛选。 5.1 面积筛选 轮廓面积记为 A,满足 min_area ≤ A ≤ max_area 面积过小的轮廓视为噪点,过大的视为背景误检。 5.2 圆度筛选 对轮廓求最小外接圆,得到圆心与半径 (cx, cy, r),圆度定义为 circularity = A / (π·r²) 即轮廓面积占外接圆面积的比例,越接近 1 越接近圆。低于圆度下限 min_circularity 的轮廓直接剔除。两类典型干扰在此阶段或后续阶段处理:细线条纹类干扰形状细长、圆度低,在几何筛选阶段排除;完全静止的大圆形状合格但速度为零,由速度统计阶段剔除。 六、中心坐标计算 通过筛选的轮廓直接采用最小外接圆的圆心 (cx, cy) 作为元素中心。选择该方案的原因: 对近似圆形目标,外接圆圆心与质心基本重合; 圆心与半径一次计算同时得到,半径可复用于圆度判定; 对轻微遮挡和边缘缺损,外接圆圆心比质心更稳定。 单帧坐标计算链路: 前景掩码 → 轮廓提取 → 面积筛选 → 圆度筛选 → 最小外接圆 → 中心坐标 (cx, cy, r) 七、跨帧轨迹关联 7.1 轨迹表示 轨迹定义为元素在多帧中的位置序列: track = [(f1, x1, y1), (f2, x2, y2), ...] 7.2 关联策略 相邻帧之间构造距离矩阵: cost(i, j) = ||p_i − q_j|| p_i 为已有轨迹的末位置,q_j 为当前帧检测点。关联规则: 距离超过关联阈值 link_distance 视为不可匹配; 循环取全局最小距离,完成一对一贪心配对; 未匹配的检测点创建新轨迹;未匹配的旧轨迹丢失计数加 1,超过 lost_limit 后删除。 采用全局配对而非逐目标最近邻搜索,是为了避免元素交错时两条轨迹争夺同一检测点导致串号。 关联阈值 link_distance 与丢失容忍 lost_limit 决定轨迹连续性:阈值过大容易串号,过小容易断线,需要根据实际素材调整。 八、速度统计与最慢目标判定 8.1 轨迹平均速度 对轨迹内相邻帧位置累计路程: total_distance = Σ ||p_k − p_{k−1}|| avg_speed = total_distance / len(track) 采用累计路程而非首尾直线距离,原因在于元素可能折返或绕圈运动,直线距离无法反映实际运动量。 8.2 静止目标剔除 满足 net_distance < ε1 且 total_distance < ε2 的轨迹判定为完全静止(ε1、ε2 为小量阈值,net_distance 为起点到当前点的直线距离),不参与最慢判定。 8.3 最慢目标输出 有效轨迹按 avg_speed 升序排序,取第一条,返回其末位置坐标 (last_x, last_y)。返回末位置的原因:提交答案时元素仍在运动,末位置对应当前时刻的位置,与题目要求一致。 九、核心代码 实例代码... 9.1 单帧候选提取 for frame in frames: mask = preprocess(frame) 灰度 → 模糊 → 差分 → 阈值 → 形态学 detections = [] for cnt in find_contours(mask): area = contour_area(cnt) if not (min_area <= area <= max_area): continue (cx, cy, r) = min_enclosing_circle(cnt) if circularity(area, r) < min_circularity: continue detections.append((cx, cy, r)) detections_by_frame.append(detections) 9.2 跨帧轨迹关联 tracks = {} for frame_index, detections in enumerate(detections_by_frame): if tracks and detections: cost = distance_matrix(track_tails, detections) for (i, j) in greedy_one_to_one_match(cost, link_distance): tracks[i].append(detections[j]) 未匹配的旧轨迹:lost += 1,超过 lost_limit 删除 # 未匹配的新检测点:创建新轨迹 9.3 最慢目标判定 valid = [t for t in tracks if len(t) >= min_frames and not is_completely_static(t)] if not valid: return None valid.sort(key=lambda t: avg_speed(t)) slowest = valid[0] return slowest.last_pos 9.4 对外接口 def get_slowest_point(url: str): webm_path = download_webm(url) try: slowest = detect_slowest_dot(webm_path) return slowest.last_pos if slowest else None finally: remove(webm_path) 十、工程要点 临时文件通过 try/finally 兜底清理,识别失败也不残留; 识别失败返回空值,由上层决定重试或放弃,不输出无效坐标; 识别模块只暴露单一接口(视频 URL → 坐标),与验证码整体流程解耦,便于与其它题型共用接入模式。 十一、方法特点与局限 方法特点: 无需训练样本,不依赖深度学习模型; 计算开销小,可毫秒级完成; 对元素颜色与背景形态不敏感; 处理环节独立,可逐环节调试与可视化验证。 局限性:目标遮挡严重、轨迹密集交叉、运动突变明显的场景下,基于距离的简单关联容易串号,需要引入运动估计与全局优化类跟踪方法。 结语 该方法将“谁在动”转化为“谁动了多少”,以前景差分负责目标发现、几何筛选负责干扰剔除、轨迹关联负责身份保持、速度统计负责排序判定,最终输出的坐标具有明确的计算来源与时序语义。 公众号:JavaScript逆向笔记 来源:<mark class="encrypted">63dK9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6E0M7q4)9J5k6i4N6W2K9i4S2A6L8W2)9J5k6i4q4I4i4K6u0W2j5$3!0E0i4K6u0r3M7#2)9J5c8U0q4V1y4%4b7@1L8e0y4W2K9o6u0v1c8h3&6Y4f1p5)9H3h3i4y4J5K9@1p5`.</mark>
传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!!
收藏
・
1
点赞
・
0
打赏
分享
分享到微信
分享到QQ
分享到微博
赞赏记录
参与人
雪币
留言
时间
查看更多
赞赏
×
1 雪花
5 雪花
10 雪花
20 雪花
50 雪花
80 雪花
100 雪花
150 雪花
200 雪花
支付方式:
微信支付
赞赏留言:
快捷留言
感谢分享~
精品文章~
原创内容~
精彩转帖~
助人为乐~
感谢分享~
最新回复
(
0
)
游客
登录
|
注册
方可回帖
回帖
表情
雪币赚取及消费
高级回复
返回
你送的花开了
3
发帖
1
回帖
0
RANK
关注
私信
他的文章
[原创]完美滑块还原笔记
371
[原创]腾讯验证码识别之“旋转最快的物体”
314
[原创]腾讯验证码识别之“点击运动最慢的元素”分析
323
关于我们
联系我们
企业服务
看雪公众号
专注于PC、移动、智能设备安全研究及逆向工程的开发者社区
看原图
赞赏
×
雪币:
+
留言:
快捷留言
为你点赞!
返回
顶部