news 2026/10/20 9:12:28

目标检测算法综述1

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
目标检测算法综述1
# opencv已经实现了的追踪算法 OPENCV_OBJECT_TRACKERS = { "csrt": cv2.TrackerCSRT_create, "kcf": cv2.TrackerKCF_create, "boosting": cv2.TrackerBoosting_create, "mil": cv2.TrackerMIL_create, "tld": cv2.TrackerTLD_create, "medianflow": cv2.TrackerMedianFlow_create, "mosse": cv2.TrackerMOSSE_create }

kcf就是画一个框,然后去追踪,缺点就是人消失了就没有办法追踪了 。一开始起源是相关滤波(CF)也就是目标追踪的核心思路,

CF 原理就是:

必须手动框选第一帧里要追踪的目标位置,这是追踪的起点。

然后对框选的目标区域做padding 填充,加入周边背景信息,方便模型学习。

构建正样本和负样本:正样本是手动框选的目标,负样本是目标周边偏移的区域。

训练滤波矩阵:这个矩阵的作用是计算图像各区域的响应值,目标区域的响应值会最高。

那么,为什么叫滤波?

在 CF/KCF 算法里,“滤波” 的核心是训练一个 “匹配模板”(也就是滤波矩阵)。这个矩阵的作用不是去噪,而是在每一帧图像里,筛选出和初始目标最相似的区域。

KCF做的改进(2014年论文)

KCF 的全称是核相关滤波,在 CF 的基础上做了两个关键优化,解决了速度慢的问题:

第一个是样本扩增,用变换矩阵对现有样本做变换,生成更多样本。这样不需要额外采集样本,就能提升模型的泛化能力。第二个是:运算提速,把原本耗时的卷积运算,通过傅里叶变换转换成简单的乘法运算。大幅降低计算复杂度,实现实时追踪。第三个是:引入核函数核函数能把低维空间里线性不可分的数据,映射到高维空间变成线性可分。提升目标识别的准确率,同时不会显著增加计算量。

视频流追踪代码

# 实例化OpenCV's multi-object tracker trackers = cv2.MultiTracker_create() vs = cv2.VideoCapture(args["video"]) # 视频流 while True: # 取当前帧 frame = vs.read() # (true, data) frame = frame[1] # 到头了就结束 if frame is None: break # resize每一帧,原始的图是很大的 (h, w) = frame.shape[:2] width=600 r = width / float(w) dim = (width, int(h * r)) frame = cv2.resize(frame, dim, interpolation=cv2.INTER_AREA) # 追踪结果 (success, boxes) = trackers.update(frame) # 绘制区域 for box in boxes: (x, y, w, h) = [int(v) for v in box] cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2) # 显示 cv2.imshow("Frame", frame) key = cv2.waitKey(100) & 0xFF if key == ord("s"): # 选择一个区域,按s box = cv2.selectROI("Frame", frame, fromCenter=False, showCrosshair=True) # 创建一个新的追踪器 tracker = OPENCV_OBJECT_TRACKERS[args["tracker"]]() trackers.add(tracker, frame, box) # 退出 elif key == 27: break vs.release() cv2.destroyAllWindows()

上面的代码是在视频中框出一个人,然后通过这一帧检测学习下一帧,但是如果存在遮挡现象,那么久会出现目标丢失。

接下来思考,如果没有手动框出一个人,那么模型是否先识别到人,然后再进行追踪?

基于dlib与ssd的追踪

dlib 机器学习的实现方法,直接调用就可以使用了。

运行下面代码需要指定参数;

检测框架学习路线:

Faster-RCNN (2015)基础 5fps

SSD,Single shot detection 30+fps

YOLO 速度快

Mask-RCNN 更通用的,检测的知识,过一遍

#导入工具包 from utils import FPS import numpy as np import argparse import dlib import cv2 """ --prototxt mobilenet_ssd/MobileNetSSD_deploy.prototxt --model mobilenet_ssd/MobileNetSSD_deploy.caffemodel --video race.mp4 """ # 参数 ap = argparse.ArgumentParser() ap.add_argument("-p", "--prototxt", required=True, help="path to Caffe 'deploy' prototxt file") ap.add_argument("-m", "--model", required=True, help="path to Caffe pre-trained model") ap.add_argument("-v", "--video", required=True, help="path to input video file") ap.add_argument("-o", "--output", type=str, help="path to optional output video file") ap.add_argument("-c", "--confidence", type=float, default=0.2, help="minimum probability to filter weak detections") args = vars(ap.parse_args()) # SSD标签 CLASSES = ["background", "aeroplane", "bicycle", "bird", "boat", "bottle", "bus", "car", "cat", "chair", "cow", "diningtable", "dog", "horse", "motorbike", "person", "pottedplant", "sheep", "sofa", "train", "tvmonitor"] # 读取网络模型 print("[INFO] loading model...") net = cv2.dnn.readNetFromCaffe(args["prototxt"], args["model"]) # 初始化 print("[INFO] starting video stream...") vs = cv2.VideoCapture(args["video"]) writer = None # 一会要追踪多个目标 trackers = [] labels = [] # 计算FPS fps = FPS().start() while True: # 读取一帧 (grabbed, frame) = vs.read() # 是否是最后了 if frame is None: break # 预处理操作 (h, w) = frame.shape[:2] width=600 r = width / float(w) dim = (width, int(h * r)) frame = cv2.resize(frame, dim, interpolation=cv2.INTER_AREA) rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) # 如果要将结果保存的话 if args["output"] is not None and writer is None: fourcc = cv2.VideoWriter_fourcc(*"MJPG") writer = cv2.VideoWriter(args["output"], fourcc, 30, (frame.shape[1], frame.shape[0]), True) # 先检测 再追踪 if len(trackers) == 0: # 获取blob数据 (h, w) = frame.shape[:2] blob = cv2.dnn.blobFromImage(frame, 0.007843, (w, h), 127.5) # 得到检测结果 net.setInput(blob) detections = net.forward() # 遍历得到的检测结果 for i in np.arange(0, detections.shape[2]): # 能检测到多个结果,只保留概率高的 confidence = detections[0, 0, i, 2] # 过滤 if confidence > args["confidence"]: # extract the index of the class label from the # detections list idx = int(detections[0, 0, i, 1]) label = CLASSES[idx] # 只保留人的,其他的标签跳过 if CLASSES[idx] != "person": continue # 得到BBOX #print (detections[0, 0, i, 3:7]) 还原成图像中的相对的数值 box = detections[0, 0, i, 3:7] * np.array([w, h, w, h]) (startX, startY, endX, endY) = box.astype("int") # 使用dlib来进行目标追踪 #http://dlib.net/python/index.html#dlib.correlation_tracker t = dlib.correlation_tracker() rect = dlib.rectangle(int(startX), int(startY), int(endX), int(endY)) t.start_track(rgb, rect) # 保存结果 labels.append(label) trackers.append(t) # 绘图 cv2.rectangle(frame, (startX, startY), (endX, endY), (0, 255, 0), 2) cv2.putText(frame, label, (startX, startY - 15), cv2.FONT_HERSHEY_SIMPLEX, 0.45, (0, 255, 0), 2) # 如果已经有了框,就可以直接追踪了 else: # 每一个追踪器都要进行更新 for (t, l) in zip(trackers, labels): t.update(rgb) pos = t.get_position() # 得到位置 startX = int(pos.left()) startY = int(pos.top()) endX = int(pos.right()) endY = int(pos.bottom()) # 画出来 cv2.rectangle(frame, (startX, startY), (endX, endY), (0, 255, 0), 2) cv2.putText(frame, l, (startX, startY - 15), cv2.FONT_HERSHEY_SIMPLEX, 0.45, (0, 255, 0), 2) # 也可以把结果保存下来 if writer is not None: writer.write(frame) # 显示 cv2.imshow("Frame", frame) key = cv2.waitKey(1) & 0xFF # 退出 if key == 27: break # 计算FPS fps.update() fps.stop() print("[INFO] elapsed time: {:.2f}".format(fps.elapsed())) print("[INFO] approx. FPS: {:.2f}".format(fps.fps())) if writer is not None: writer.release() cv2.destroyAllWindows() vs.release()

多进程目标追踪

思路:每一个追踪器追踪代码封装成一个函数。然后用multiprocessing 处理每一追踪器。

from utils import FPS import multiprocessing import numpy as np import argparse import dlib import cv2 #perfmon def start_tracker(box, label, rgb, inputQueue, outputQueue): t = dlib.correlation_tracker() rect = dlib.rectangle(int(box[0]), int(box[1]), int(box[2]), int(box[3])) t.start_track(rgb, rect) while True: # 获取下一帧 rgb = inputQueue.get() # 非空就开始处理 if rgb is not None: # 更新追踪器 t.update(rgb) pos = t.get_position() startX = int(pos.left()) startY = int(pos.top()) endX = int(pos.right()) endY = int(pos.bottom()) # 把结果放到输出q outputQueue.put((label, (startX, startY, endX, endY))) ap = argparse.ArgumentParser() ap.add_argument("-p", "--prototxt", required=True, help="path to Caffe 'deploy' prototxt file") ap.add_argument("-m", "--model", required=True, help="path to Caffe pre-trained model") ap.add_argument("-v", "--video", required=True, help="path to input video file") ap.add_argument("-o", "--output", type=str, help="path to optional output video file") ap.add_argument("-c", "--confidence", type=float, default=0.2, help="minimum probability to filter weak detections") args = vars(ap.parse_args()) # 一会要放多个追踪器 inputQueues = [] outputQueues = [] CLASSES = ["background", "aeroplane", "bicycle", "bird", "boat", "bottle", "bus", "car", "cat", "chair", "cow", "diningtable", "dog", "horse", "motorbike", "person", "pottedplant", "sheep", "sofa", "train", "tvmonitor"] print("[INFO] loading model...") net = cv2.dnn.readNetFromCaffe(args["prototxt"], args["model"]) print("[INFO] starting video stream...") vs = cv2.VideoCapture(args["video"]) writer = None fps = FPS().start() if __name__ == '__main__': while True: (grabbed, frame) = vs.read() if frame is None: break (h, w) = frame.shape[:2] width=600 r = width / float(w) dim = (width, int(h * r)) frame = cv2.resize(frame, dim, interpolation=cv2.INTER_AREA) rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) if args["output"] is not None and writer is None: fourcc = cv2.VideoWriter_fourcc(*"MJPG") writer = cv2.VideoWriter(args["output"], fourcc, 30, (frame.shape[1], frame.shape[0]), True) #首先检测位置 if len(inputQueues) == 0: (h, w) = frame.shape[:2] blob = cv2.dnn.blobFromImage(frame, 0.007843, (w, h), 127.5) net.setInput(blob) detections = net.forward() for i in np.arange(0, detections.shape[2]): confidence = detections[0, 0, i, 2] if confidence > args["confidence"]: idx = int(detections[0, 0, i, 1]) label = CLASSES[idx] if CLASSES[idx] != "person": continue box = detections[0, 0, i, 3:7] * np.array([w, h, w, h]) (startX, startY, endX, endY) = box.astype("int") bb = (startX, startY, endX, endY) # 创建输入q和输出q iq = multiprocessing.Queue() oq = multiprocessing.Queue() inputQueues.append(iq) outputQueues.append(oq) # 多核 p = multiprocessing.Process( target=start_tracker, args=(bb, label, rgb, iq, oq)) p.daemon = True p.start() cv2.rectangle(frame, (startX, startY), (endX, endY), (0, 255, 0), 2) cv2.putText(frame, label, (startX, startY - 15), cv2.FONT_HERSHEY_SIMPLEX, 0.45, (0, 255, 0), 2) else: # 多个追踪器处理的都是相同输入 for iq in inputQueues: iq.put(rgb) for oq in outputQueues: # 得到更新结果 (label, (startX, startY, endX, endY)) = oq.get() # 绘图 cv2.rectangle(frame, (startX, startY), (endX, endY), (0, 255, 0), 2) cv2.putText(frame, label, (startX, startY - 15), cv2.FONT_HERSHEY_SIMPLEX, 0.45, (0, 255, 0), 2) if writer is not None: writer.write(frame) cv2.imshow("Frame", frame) key = cv2.waitKey(1) & 0xFF if key == 27: break fps.update() fps.stop() print("[INFO] elapsed time: {:.2f}".format(fps.elapsed())) print("[INFO] approx. FPS: {:.2f}".format(fps.fps())) if writer is not None: writer.release() cv2.destroyAllWindows() vs.release()
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/19 9:29:45

Comsol 中浆液扩散模型:注浆过程的数字化洞察

comsol注浆,浆液扩散模型在岩土工程、建筑施工等诸多领域,注浆是一项关键技术,它能有效改善土体性质、增强结构稳定性。而理解浆液在地下的扩散规律至关重要,借助 Comsol 建立浆液扩散模型,可让我们在虚拟环境中深入探…

作者头像 李华
网站建设 2026/10/19 9:29:45

2026中专生考大数据与财务管理专业学习指南

行业需求与就业前景数据分析在财务领域的应用日益广泛,企业需要能够处理财务数据并从中提取价值的专业人才。掌握数据分析技能可提升就业竞争力,尤其在金融科技、企业财务分析等岗位需求旺盛。大数据与财务管理专业结合了传统财务知识与现代数据技术&…

作者头像 李华
网站建设 2026/10/19 12:25:28

手把手教你降AI不伤文:保姆级操作让论文既通过检测又保持专业

手把手教你降AI不伤文:保姆级操作让论文既通过检测又保持专业 TL;DR:降AI率最怕的就是把专业术语改没了、论文变得不伦不类。本文教你如何实现「降AI不伤文」:选对工具(推荐嘎嘎降AI)、分段处理、处理后校对。掌握这套…

作者头像 李华
网站建设 2026/10/19 12:25:26

小程序毕设选题推荐:基于django+微信小程序的健康生活系统个人健康生活平台小程序【附源码、mysql、文档、调试+代码讲解+全bao等】

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围:&am…

作者头像 李华
网站建设 2026/10/19 12:25:14

微分方程一维抛物热传导方程数值解法全解析

微分方程一维抛物热传导方程向前向后欧拉C-N格式二阶BDF格式MATLAB源码 显式欧拉,隐式欧拉,梯形公式,改进欧拉 五点差分,九点差分 差分格式,紧差分格式 直拍,只有pdf版方法说明 word版 公式纯手打 数值例子…

作者头像 李华
网站建设 2026/10/19 12:25:16

图像金字塔与直方图

在计算机视觉领域,图像金字塔与直方图是两大基础且实用的技术。图像金字塔用于处理不同分辨率的图像,广泛应用于图像融合、超分辨率重建等场景;直方图则用于描述图像像素分布,是图像增强、阈值分割的核心工具。本文将结合完整代码…

作者头像 李华