记录第一个目标追踪程序
目前csdn查询到的基于opencv的目标追踪
在框选ROI的时候都是非常反人类的
此代码可以实时框选RIOI区域
我的运行环境python3.7+win10
复制一下代码可以直接运行
运行此代码需要卸载opencv
pip uninstall opencv-python
以及安装 opencv-contrib-python
pip install opencv-contrib-python -i https://pypi.tuna.tsinghua.edu.cn/simple
稍后发布基于此代码的树莓派两轴云台追踪指定物体
2020 09 02修订
增加目标丢失警告,不会自动找回目标,需要手动重新追踪
2020 09 03修订
对每一帧进行高斯处理,修复追踪窗口超出窗口范围报错,代码简洁化
#zoulee24
import cv2
import time
import sys
from click import globals
from skimage.metrics import structural_similarity
def mouse_event(event, x, y, flags, parms):
global points #全局调用
if event == cv2.EVENT_LBUTTONDOWN:
points = [(x, y)]
#elif event == cv2.EVENT_MOUSEMOVE and flags == cv2.EVENT_FLAG_LBUTTON:
elif len(points) == 1 and event != cv2.EVENT_LBUTTONUP:
cv2.rectangle(frame, points[0], (x, y), (0, 255, 0), thickness=2)
elif event == cv2.EVENT_LBUTTONUP and 0 < len(points) < 2:
if points[0] != (x, y):
points.append((x, y))
#判断是否非正常画框
if points[0][0] > points[1][0]:
if points[0][1] > points[1][1]:
points = [(points[1][0], points[1][1]), (points[0][0], points[0][1])]
else:
points = [(points[1][0], points[0][1]), (points[0][0], points[1][1])]
else:
if points[0][1] > points[1][1]:
points = [(points[0][0], points[1][1]), (points[1][0], points[0][1])]
else:
points = []
def main(cap):
global frame, points
ok = False
points = []
cv2.namedWindow('get ROI')
cv2.setMouseCallback('get ROI', mouse_event)
while not ok:
ret, frame = cap.read()
cv2.putText(frame, 'press Space to choice ROI', (5, 15), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255), 1)
cv2.putText(frame, 'press R to rechoie ROI', (5, 30), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255), 1)
key = cv2.waitKey(5) & 0xFF
if len(points) == 2:
cv2.rectangle(frame, points[0], points[1], (0, 255, 0), thickness=2)
if key == 27:
cap.release()
cv2.destroyAllWindows()
sys.exit()
elif key == ord('r'):
points = []
elif key == 32 and len(points) == 2:
locations = (points[0][0], points[0][1], points[1][0] - points[0][0], points[1][1] - points[0][1])
points = []
ok = True
#break
cv2.imshow('get ROI', frame)
object_to_track = frame[locations[1]:locations[1] + locations[3], locations[0]:locations[0] + locations[2], :]
return locations, object_to_track
def judge_tracker(tracker, box):
global frame
ok = tracker.init(frame, box)
if not ok:
raise Exception("追踪器工作初始化失败")
else:
pass
def tracker_start():
tracker = cv2.TrackerCSRT_create()
#tracker = cv2.TrackerKCF_create()
return tracker
def tracker_working(tracker, cap, object):
object = cv2.cvtColor(object, cv2.COLOR_BGR2GRAY)
t1 = round(time.time(), 2)
while cap.isOpened():
t2 = round(time.time(), 2)
ret, frame = cap.read()
frame_blur = frame.copy()
frame_blur = cv2.GaussianBlur(frame_blur, (5, 5), 0)
ok, new_location = tracker.update(frame_blur)
if ok:
p1 = [int(new_location[0]), int(new_location[1])]
p2 = [int(new_location[0] + new_location[2]), int(new_location[1] + new_location[3])]
p1 = tuple(0 if i < 0 else i for i in p1)
if p2[0] > 640:
p2[0] = 640
if p2[1] > 360:
p2[1] = 360
p2 = tuple(p2)
if (t2 - t1) % 1 > 0.9 or (t2 - t1) % 1 < 0.1:
frame_object = frame[p1[1]:p2[1], p1[0]:p2[0]]
frame_object = cv2.cvtColor(frame_object, cv2.COLOR_BGR2GRAY)
frame_object = cv2.resize(frame_object, (object.shape[1], object.shape[0]))
#print("object:{} object_frame:{}".format(object.shape, frame_object.shape))
(score, _) = structural_similarity(object, frame_object, full=True)
if score < 0.3:
cv2.putText(frame, "WARNING LOSING TARGET", (50, 45), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255),
2)
cv2.putText(frame, "press Q to rechoice ROI", (5, 15), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255), 1)
cv2.putText(frame, "press Esc to choice ROI", (5, 30), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255), 1)
# Tracking success
cv2.rectangle(frame, p1, p2, (255, 0, 0), thickness=2, lineType=1)
'''
if (p1[0] + p2[0]) < frame.shape[1]:
cv2.putText(frame, "need to be left", (100, 200), cv2.FONT_HERSHEY_SIMPLEX, 2, (0, 0, 255), 3)
else:
cv2.putText(frame, "need to be right", (100, 200), cv2.FONT_HERSHEY_SIMPLEX, 2, (0, 0, 255), 3)
'''
else:
# Tracking failure
#frame = np.zeros(frame.shape, np.uint8)
cv2.putText(frame, "Tracking failure detected", (50, 50), cv2.FONT_HERSHEY_SIMPLEX, 3, (0, 0, 255), 1)
cv2.imshow("get ROI", frame)
time.sleep(2)
break
cv2.imshow("get ROI", frame)
key = cv2.waitKey(1) & 0xFF
if key == 27:
return False
elif key == ord('q'):
break
return True
if __name__ == '__main__':
cap = cv2.VideoCapture(0, cv2.CAP_DSHOW)
ret = True
while ret:
location, object_to_track = main(cap)
tracker = tracker_start()
judge_tracker(tracker, location)
ret = tracker_working(tracker, cap, object_to_track)
cap.release()
cv2.destroyAllWindows()
有任何问题可以评论区指出