[opencv]基于dlib和ssd的目标追踪和多线程加速

1.opencv的追踪算法

1.1opencv的八个追踪算法

"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(卡尔曼滤波),效率和准确率都不错

1.2基于kcf的OpenCV追踪检测流程

# 实例化OpenCV's multi-object tracker                         
trackers = cv2.legacy.MultiTracker_create()   #实例化一个追踪器    

# 视频流                         
while True:                   
	# 取当前帧                    
	ret , frame = vs.cv2.VideoCapture(args["video"])   #选择参数列表传入的追踪器  
	# 到头了就结束                  
	if ret is False:          
		print("没有视频")         
		break                             
                              
	# resize每一帧               
	(h, w) = frame.shape[:2]  
	width=600                 
	r = width / float(w)      
	dim = (width, int(h * r)) 
	frame = cv2.resize(frame, 
                              
	# 追踪结果                    
	(success, boxes) = tracker
                              
	# 绘制区域                    
	for box in boxes:         
		(x, y, w, h) = [int(v)
		cv2.rectangle(frame, (
                              
	# 显示                      
	cv2.imshow("Frame", frame)
	key = cv2.waitKey(100) & 0
                              
	if key == ord("s"):       
		# 选择一个区域,按s           
		box = cv2.selectROI("F
			showCrosshair=True
                              
		# 创建一个新的追踪器           
		tracker = OPENCV_OBJEC
		trackers.add(tracker, 
                              
	# 退出                      
	elif key == 27:           
		break                 
vs.release()                  
cv2.destroyAllWindows()       

2.深度学习的追踪算法:ssd(检测器)+dlib(追踪器)

2.1dlib介绍:

它是一个高性能的计算框架。它是一个C++编写的工具包,所以在应用层面的推理速度是非常快的。而且配备了python客户端,很方便开发者在各大平台使用,大大提高了框架的灵活性。

广泛应用于工业界和学术界。包含了大多数常用的机器学习算法,许多图像处理算法和深度学习算法,被工业界和学术界广泛应用于机器人,嵌入式设备,移动电话和大型高性能计算环境领域。常见的深度学习,基于SVM的分类和递归算法,针对大规模分类和递归的降维方法,相关向量机,聚类,多层感知机等都有相关API,且配置详细文档。最重要的一点是开源,开源,开源!这就意味着,我们可以在任何APP上免费试用。

2.2算法流程

'''训练的时候怎么进行数据预处理,测试的时也需要进行相同的预处理'''
if len(tracker) == 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(1,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

    	#得到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来进行目标追踪
    	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)


    
    

2.3多进程的追踪流程


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) #用dlib追踪器的属性去画图

	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)))

多进程处理:主要用到  `import multiprocessing` 工具包

 

from utils import FPS
import multiprocessing
import numpy as np
import argparse
import dlib
import cv2
#perfmon


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) #将处理后的图片放入net,再次将网络前向传播
			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))  #Process()函数需要的参数
					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()

你可能感兴趣的:(opencv之数字图像处理,opencv,计算机视觉,python,人工智能)