赞
踩
综合算法速度和准确率考虑,个人觉得CSRT、KCF、MOSSE这三个目标跟踪算法较好。
CF
正负样本选择,变换矩阵,得到更多样本训练分类器
KCF算法原理
KCF将待跟踪的目标表示为一个矩形框,然后在每一帧图像中通过计算目标区域与全局图像中所有可能的位置之间的相似度,找到最接近目标的位置。该相似度值通过傅里叶变换和核函数计算得出,然后通过最大化相似度值来更新目标区域的位置和大小
KCF算法的关键在于采用了核技巧,这意味着可以使用非线性函数对输入数据进行映射,从而使得滤波器更加灵活。因此,KCF算法比其他相关滤波器算法更加适合处理复杂场景下的目标追踪任务,例如光照变化和旋转等。
较于CF提速
追踪算法涉及到一些遮蔽现象之后效果会变差
一些深度学习算法或许可以解决
看2015年论文Faster-RCNN比较有价值的论文,这是后面的很多框架的基础
简介
Faster-RCNN是一个目标检测算法,它采用了两阶段的检测框架。首先,将输入图像通过卷积神经网络提取特征,然后在这些特征上使用区域建议网络(RPN)生成一些候选框。接下来,对这些候选框进行进一步的分类和回归,得到最终的目标检测结果。相比于其他单阶段的目标检测算法,如YOLO和SSD,Faster-RCNN有着更高的准确率和更低的误检率。但是,由于需要两个网络模型,因此其速度较慢。
SSD
简介
Opencv SSD是一种目标检测算法,它基于深度神经网络,可以在图像或视频中检测出特定物体的位置和类别。SSD代表“Single Shot MultiBox Detector”,它可以快速地检测出多个不同大小和形状的物体。在使用Opencv SSD时,需要首先训练一个模型来识别所需的物体类别,然后将该模型应用于输入的图像或视频中。当检测到物体时,SSD会返回一个包含物体位置和类别的边界框,这些信息可以用于进一步处理和分析图像或视频数据
YOLO
简介
YOLO是一种单阶段的目标检测算法,它可以实现实时目标检测。它将输入图像分成网格,并在每个网格中预测目标的位置和类别。与Faster-RCNN等两阶段方法不同,YOLO直接从原始图像中回归目标框,因此速度更快。但是由于网络结构相对简单,所以其检测精度可能会受到一些限制,而且对于小物体的检测效果可能不如其他算法。同时,YOLO也有不同版本,如YOLOv3、YOLOv4等,它们在网络结构和训练策略上都有所改进,提高了检测性能。
MASK-RCNN
简介
MASK-RCNN是一个多任务学习算法,它在Faster-RCNN的基础上增加了一个分割头来实现物体实例分割。与单纯的目标检测不同,物体实例分割需要同时得到每个目标的位置和像素级的语义分割结果。MASK-RCNN通过在ROI池化操作后增加一个子网络,来预测每个RoI中物体的掩模信息,从而实现物体实例分割。MASK-RCNN可以同时进行目标检测和物体实例分割,在一些应用场景下具有很高的实用价值。但是由于增加了掩模预测子网络,所以其计算复杂度相较于Faster-RCNN也会有所提升。
dlib库
dlib是一个用于机器学习和图像处理的C++库,它提供了一系列计算机视觉和机器学习算法的实现,并且能够在Python中进行使用。其主要功能包括:
人脸检测:使用HOG特征和级联分类器(cascade classifier)对图像中的人脸进行检测。
关键点检测:对人脸图像进行关键点检测,例如眼睛、鼻子、嘴巴等部位。
人脸识别:使用深度学习技术实现人脸识别,可以用于验证身份或者对人脸进行分类。
姿态估计:对人脸图像进行姿态估计,可以判断人脸的朝向和角度。
目标跟踪:对视频中的目标进行跟踪,可以用于自动驾驶、人员监控等领域。
图像变形:对图像进行变形,例如拉伸、扭曲等操作。
其他机器学习算法:dlib还包含了一些其他的机器学习算法,例如支持向量机(SVM)、线性回归等。
总步骤
检测阶段:使用SSD网络对图像中的物体进行检测,得到其位置和类别信息。
特征提取阶段:利用dlib库中的人脸检测器或者目标检测器来获取检测到的物体的特征向量,并将其保存。
匹配阶段:通过比较当前帧和上一帧中物体的特征向量,来匹配相同物体。可以使用各种方法如卡尔曼滤波、最近邻搜索等来实现匹配。
更新阶段:根据匹配结果,更新每个物体的位置和其他状态信息,例如速度、加速度等。
输出阶段:输出更新后的物体位置以及其它状态信息。
import cv2 as cv import numpy as np import dlib print(dlib.DLIB_USE_CUDA) video_file = 'videos/v2.mp4' output = "output2.mp4" CONFIDENCE_LIMIT = 0.4 # SSD标签 CLASSES = ["backgroud","aeroplane","bicycle","bird","boat", "bottle","bus","car","cat","chair","cow","diningtalble", "dog","horse","motorbike","person","pottedplant","sheep", "sofa","train","tvmoitor"] # 读取网络模型 print('loading model...') net = cv.dnn.readNetFromCaffe('dnn/MobileNetSSD_deploy.prototxt', 'dnn/MobileNetSSD_deploy.caffemodel') # 初始化 print("[INFO] starting video stream...") vs = cv.VideoCapture(video_file) writer = None trackers = [] labels = [] while True: ret, frame = vs.read() if not ret: break h, w = frame.shape[:2] width = 600 r = width / float(w) dim = (width,int(h*r)) frame = cv.resize(frame, dim, interpolation=cv.INTER_AREA) rgb = cv.cvtColor(frame, cv.COLOR_BGR2RGB) if output is not None and writer is None: fourcc = cv.VideoWriter_fourcc(*"MP4V") writer = cv.VideoWriter(output, fourcc,25,(frame.shape[1],frame.shape[0]),True) # 先检测,在追踪 if len(trackers) == 0: (h, w) = frame.shape[:2] # 归一化,输出 = (原始-127.5) * factor blob = cv.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 > CONFIDENCE_LIMIT: # 提取 idx = int(detections[0, 0, i, 1]) label = CLASSES[idx] # 只保留人的 if CLASSES[idx] != "person": continue # 得到BBOX print(detections[0, 0, i, 3:7]) # 检测出来的是一个相对的值,比如0.2w,0.2h这样 box = detections[0, 0, i, 3:7] * np.array([w, h, w, h]) (startX, startY, endX, endY) = box.astype(int) # 用dlib进行目标追踪 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) # 绘测 cv.rectangle(frame, (startX, startY), (endX, endY), (0,0,255), 2) cv.putText(frame, label, (startX, startY-15), cv.FONT_HERSHEY_SIMPLEX, 0.45, (255, 0, 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()) cv.rectangle(frame, (startX, startY), (endX, endY), (0, 0, 255), 2) cv.putText(frame, l, (startX, startY - 15), cv.FONT_HERSHEY_SIMPLEX, 0.45, (255, 0, 0), 2) # 可以保存下结果 # if writer is not None: # writer.write(frame) # 显示 cv.imshow("frame", frame) key = cv.waitKey(10) & 0xff if key == 27: break # 就是说第一帧先检测出哪些是人,然后后面那些帧直接用dlb追踪的框架来去追踪 cv.destroyAllWindows() vs.release()
处理函数,输入输出队列
import cv2 as cv import numpy as np import dlib import multiprocessing 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))) inputQueues = [] outputQueues = [] video_file = 'videos/v2.mp4' output = r"C:\Users\86189\Desktop\opencv\output2.avi" CONFIDENCE_LIMIT = 0.4 # SSD标签 CLASSES = ["backgroud", "aeroplane", "bicycle", "bird", "boat", "bottle", "bus", "car", "cat", "chair", "cow", "diningtalble", "dog", "horse", "motorbike", "person", "pottedplant", "sheep", "sofa", "train", "tvmoitor"] # 读取网络模型 print('[INFO] loading model...') net = cv.dnn.readNetFromCaffe('dnn/MobileNetSSD_deploy.prototxt', 'dnn/MobileNetSSD_deploy.caffemodel') # 初始化 print("[INFO] starting video stream...") vs = cv.VideoCapture(video_file) writer = None trackers = [] labels = [] if __name__ == '__main__': while True: ret, frame = vs.read() if not ret: break h, w = frame.shape[:2] width = 600 r = width / float(w) dim = (width, int(h * r)) frame = cv.resize(frame, dim, interpolation=cv.INTER_AREA) rgb = cv.cvtColor(frame, cv.COLOR_BGR2RGB) if output is not None and writer is None: fourcc = cv.VideoWriter_fourcc(*"MJPG") writer = cv.VideoWriter(output, fourcc, 25, (frame.shape[1], frame.shape[0]), True) # 先检测,在追踪 if len(inputQueues) == 0: (h, w) = frame.shape[:2] # 归一化,输出 = (原始-127.5) * factor blob = cv.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 > CONFIDENCE_LIMIT: # 提取 idx = int(detections[0, 0, i, 1]) label = CLASSES[idx] # 只保留人的 if CLASSES[idx] != "person": continue # 得到BBOX # print(detections[0, 0, i, 3:7]) # 检测出来的是一个相对的值,比如0.2w,0.2h这样 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 # 每个进程都有inputQ跟outputQ 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() # 绘测 cv.rectangle(frame, (startX, startY), (endX, endY), (0, 0, 255), 2) cv.putText(frame, label, (startX, startY - 15), cv.FONT_HERSHEY_SIMPLEX, 0.45, (255, 0, 0), 2) else: # 多个追踪器处理的都是相同输入 for iq in inputQueues: iq.put(rgb) for oq in outputQueues: # 得到更新结果 label, (startX, startY, endX, endY) = oq.get() cv.rectangle(frame, (startX, startY), (endX, endY), (0, 0, 255), 2) cv.putText(frame, label, (startX, startY - 15), cv.FONT_HERSHEY_SIMPLEX, 0.45, (255, 0, 0), 2) if writer is not None: writer.write(frame) # 显示 cv.imshow("frame", frame) key = cv.waitKey(1) & 0xff if key == 27: break # 就是说第一帧先检测出哪些是人,然后后面那些帧直接用dlb追踪的框架来去追踪 if writer is not None: writer.release() cv.destroyAllWindows() vs.release()
速度巨快
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。