在我之前的博客,”C++实现 多目标跟踪+画出轨迹 - OpenCV函数调用测试“ 中用C++实现了多目标跟踪并画出轨迹,贴上标签的功能,现在将他移植到python上面去。文章末贴上我的代码。
环境:pycharm professional 2019.1 + opencv-python 4.2.0.32 + opencv-contrib-python 4.2.0.32 + python 3.7.0 + anaconda
之前只是学过一小段时间python,但是没怎么搞过python,这次差不多是重新来了,因此遇到了很多小儿科问题,比如:
别的没啥可解释的了,要看详细解释,去看我C++实现的博客吧。
附代码:
from __future__ import print_function
import sys
import cv2
from random import randint
trackerTypes = ['BOOSTING', 'MIL', 'KCF', 'TLD', 'MEDIANFLOW', 'MOSSE', 'CSRT']
def createTrackerByName(trackerType):
# Create a tracker based on tracker name
if trackerType == trackerTypes[0]:
tracker = cv2.TrackerBoosting_create()
elif trackerType == trackerTypes[1]:
tracker = cv2.TrackerMIL_create()
elif trackerType == trackerTypes[2]:
tracker = cv2.TrackerKCF_create()
elif trackerType == trackerTypes[3]:
tracker = cv2.TrackerTLD_create()
elif trackerType == trackerTypes[4]:
tracker = cv2.TrackerMedianFlow_create()
elif trackerType == trackerTypes[5]:
tracker = cv2.TrackerMOSSE_create()
elif trackerType == trackerTypes[6]:
tracker = cv2.TrackerCSRT_create()
else:
tracker = None
print('Incorrect tracker name')
print('Available trackers are:')
for t in trackerTypes:
print(t)
return tracker
if __name__ == '__main__':
vecPoints = []
while True:
vecPoints.clear()
while True:
print('\n------------------------------------------------------------------\n'
'\n>> 可测试算法有 BOOSTING MIL KCF TLD MEDIANFLOW MOSSE CSRT'
'\n>> 请输入要测试的算法并按回车,如需退出请输入exit。')
tType = input('>> ')
if tType == 'exit':
sys.exit(0)
if tType == 'BOOSTING':
print('>> 选择BOOSTING成功!')
break
elif tType == 'MIL':
print('>> 选择MIL成功!')
break
elif tType == 'KCF':
print('>> 选择KCF成功!')
break
elif tType == 'TLD':
print('>> 选择TLD成功!')
break
elif tType == 'MEDIANFLOW':
print('>> 选择MEDIANFLOW成功!')
break
elif tType == 'MOSSE':
print('>> 选择MOSSE成功!')
break
elif tType == 'CSRT':
print('>> 选择CSRT成功!')
break
else:
print('>> 选择失败!')
continue
print('>> 输入1选择本地视频进行播放'
'\n>> 输入2选择实时摄像头播放')
judgement = input('>> ')
if judgement == '1':
while True:
print('\n+----------------+'
'\n| 1.步行的人_1 |'
'\n| 2.步行的人_2 |'
'\n| 3.步行的人_3 |'
'\n| 4.车 |'
'\n| 5.超车 |'
'\n| 6.大卫 |'
'\n| 7.跳绳 |'
'\n| 8.摩托越野 |'
'\n| 9.熊猫 |'
'\n| 10.大众汽车 |'
'\n+----------------+'
'\n\n>> 请输入要播放视频的序列号(例如4)')
videoNo = input('>> ')
if videoNo == '1':
videoName = 'pedestrian1.mpg'
print('>> 选择《步行的人_1》成功!')
break
elif videoNo == '2':
videoName = 'pedestrian2.mpg'
print('>> 选择《步行的人_2》成功!')
break
elif videoNo == '3':
videoName = 'pedestrian3.mpg'
print('>> 选择《步行的人_3》成功!')
break
elif videoNo == '4':
videoName = 'car.mpg'
print('>> 选择《车》成功!')
break
elif videoNo == '5':
videoName = 'carchase.mpg'
print('>> 选择《超车》成功!')
break
elif videoNo == '6':
videoName = 'david.mpg'
print('>> 选择《大卫》成功!')
break
elif videoNo == '7':
videoName = 'jumping.mpg'
print('>> 选择《跳绳》成功!')
break
elif videoNo == '8':
videoName = 'motocross.mpg'
print('>> 选择《摩托越野》成功!')
break
elif videoNo == '9':
videoName = 'panda.mpg'
print('>> 选择《熊猫》成功!')
break
elif videoNo == '10':
videoName = 'volkswagen.mpg'
print('>> 选择《大众汽车》成功!')
break
else:
print('>> 序列号有误,请重新输入!')
continue
video = cv2.VideoCapture('D:\\targetTracking\\datasets\\' + videoName)
if not video.isOpened():
print('>> 读取视频失败')
continue
print('\n+--------------------------+'
'\n| 点击 c 逐帧播放视频 |'
'\n| 点击 q 开始选择目标 |'
'\n| 点击空格开始播放并跟踪 |'
'\n| 播放期间按 q 退出播放 |'
'\n+--------------------------+\n')
success, frame = video.read()
if not success:
print('>> 读取视频失败')
continue
cv2.imshow('Tracker', frame)
while True:
key = cv2.waitKey(1)
if key == ord('c'):
success, frame = video.read()
cv2.imshow('Tracker', frame)
if key == ord('q'):
break
cv2.destroyWindow('Tracker')
bboxes = []
colors = []
while True:
# draw bounding boxes over objects
# selectROI's default behaviour is to draw box starting from the center
# when fromCenter is set to false, you can draw box starting from top left corner
bbox = cv2.selectROI('Tracker', frame)
bboxes.append(bbox)
colors.append((randint(64, 255), randint(64, 255), randint(64, 255)))
print("Press q to quit selecting boxes and start tracking")
print("Press any other key to select next object")
k = cv2.waitKey(0) & 0xFF
if (k == 113): # q is pressed
break
# print('Selected bounding boxes {}'.format(bboxes))
# Create MultiTracker object
multiTracker = cv2.MultiTracker_create()
# Initialize MultiTracker
for bbox in bboxes:
multiTracker.add(createTrackerByName(tType), frame, bbox)
temp = []
vecPoints.append(temp)
print('>> 开始播放')
# Process video and track objects
while video.isOpened():
success, frame = video.read()
if not success:
break
# get updated location of objects in subsequent frames
success, boxes = multiTracker.update(frame)
# draw tracked objects
for i, newbox in enumerate(boxes):
p1 = (int(newbox[0]), int(newbox[1]))
p2 = (int(newbox[0] + newbox[2]), int(newbox[1] + newbox[3]))
cv2.rectangle(frame, p1, p2, colors[i], 2, 1)
for i, newbox in enumerate(boxes):
vecPoints[i].append((int(newbox[0] + (newbox[2] * 0.5))*2, int(newbox[1] + (newbox[3] * 0.5))*2))
if len(vecPoints) > 0:
for i in range(len(vecPoints)):
for j in range(len(vecPoints[i])-1):
cv2.line(frame, vecPoints[i][j], vecPoints[i][j+1], colors[i], 1, 8, 1)
for i, newbox in enumerate(boxes):
cv2.putText(frame, 'id_'+str(i+1), (int(newbox[0]), int(newbox[1])-3), cv2.FONT_HERSHEY_PLAIN, 1, colors[i], 1)
# show frame
cv2.imshow('Tracker', frame)
# quit on ESC button
if cv2.waitKey(30) == ord('q'):
break
cv2.destroyWindow('Tracker')
print('>> 播放完毕')
elif judgement == '2':
video = cv2.VideoCapture(0)
if not video.isOpened():
print('>> 发生错误,请检查摄像头是否已断开!')
continue
print('>> 请按空格开始截取图片')
while True:
success, frame = video.read()
if not success:
print('>> 发生错误,请检查摄像头是否已断开!')
break
cv2.imshow('Tracker', frame)
if cv2.waitKey(30) == ord(' '):
break
bboxes = []
colors = []
while True:
# draw bounding boxes over objects
# selectROI's default behaviour is to draw box starting from the center
# when fromCenter is set to false, you can draw box starting from top left corner
bbox = cv2.selectROI('Tracker', frame)
bboxes.append(bbox)
colors.append((randint(64, 255), randint(64, 255), randint(64, 255)))
print("Press q to quit selecting boxes and start tracking")
print("Press any other key to select next object")
k = cv2.waitKey(0) & 0xFF
if (k == 113): # q is pressed
break
# print('Selected bounding boxes {}'.format(bboxes))
# Create MultiTracker object
multiTracker = cv2.MultiTracker_create()
# Initialize MultiTracker
for bbox in bboxes:
multiTracker.add(createTrackerByName(tType), frame, bbox)
temp = []
vecPoints.append(temp)
print('>> 开始播放')
# Process video and track objects
while video.isOpened():
success, frame = video.read()
if not success:
break
# get updated location of objects in subsequent frames
success, boxes = multiTracker.update(frame)
# draw tracked objects
for i, newbox in enumerate(boxes):
p1 = (int(newbox[0]), int(newbox[1]))
p2 = (int(newbox[0] + newbox[2]), int(newbox[1] + newbox[3]))
cv2.rectangle(frame, p1, p2, colors[i], 2, 1)
for i, newbox in enumerate(boxes):
vecPoints[i].append(
(int(newbox[0] + (newbox[2] * 0.5)) * 2, int(newbox[1] + (newbox[3] * 0.5)) * 2))
if len(vecPoints) > 0:
for i in range(len(vecPoints)):
for j in range(len(vecPoints[i]) - 1):
cv2.line(frame, vecPoints[i][j], vecPoints[i][j + 1], colors[i], 1, 8, 1)
for i, newbox in enumerate(boxes):
cv2.putText(frame, 'id_' + str(i + 1), (int(newbox[0]), int(newbox[1]) - 3), cv2.FONT_HERSHEY_PLAIN,
1, colors[i], 1)
# show frame
cv2.imshow('Tracker', frame)
# quit on ESC button
if cv2.waitKey(30) == ord('q'):
break
cv2.destroyWindow('Tracker')
print('\n>> 播放完毕\n')
else:
print('>> 输入有误')
sys.exit(1)
2020.04.08号更新
今天上午更新了C++版本的,现在在这更新python版本,在这里不做过多介绍了,要看详细介绍和遇到的问题请看C++版本的博客。
代码如下:
elif judgement == '2':
video = cv2.VideoCapture(0)
if not video.isOpened():
print('>> 发生错误,请检查摄像头是否已断开!')
continue
time_t = time.strftime('%Y.%m.%d %H-%M-%S', time.localtime(time.time()))
outDir = 'D:\\targetTracking\\pyMultiTracker\\' + time_t
os.mkdir(outDir)
outFile_1 = outDir + '\\videoNoTrack.avi'
outFile_2 = outDir + '\\videoWithTrack.avi'
s = (int(video.get(cv2.CAP_PROP_FRAME_WIDTH)), int(video.get(cv2.CAP_PROP_FRAME_HEIGHT)))
r = video.get(cv2.CAP_PROP_FPS)
write_1 = cv2.VideoWriter(outFile_1, 0, r, s, True)
write_2 = cv2.VideoWriter(outFile_2, 0, r, s, True)
# print(outDir)
print('>> 请按空格开始截取图片')
while True:
success, frame = video.read()
if not success:
print('>> 发生错误,请检查摄像头是否已断开!')
break
write_1.write(frame)
write_2.write(frame)
cv2.imshow('Tracker', frame)
if cv2.waitKey(30) == ord(' '):
break
bboxes = []
colors = []
while True:
# draw bounding boxes over objects
# selectROI's default behaviour is to draw box starting from the center
# when fromCenter is set to false, you can draw box starting from top left corner
bbox = cv2.selectROI('Tracker', frame)
bboxes.append(bbox)
colors.append((randint(64, 255), randint(64, 255), randint(64, 255)))
print("Press q to quit selecting boxes and start tracking")
print("Press any other key to select next object")
k = cv2.waitKey(0) & 0xFF
if (k == 113): # q is pressed
break
# print('Selected bounding boxes {}'.format(bboxes))
# Create MultiTracker object
multiTracker = cv2.MultiTracker_create()
# Initialize MultiTracker
for bbox in bboxes:
multiTracker.add(createTrackerByName(tType), frame, bbox)
temp = []
vecPoints.append(temp)
print('>> 开始播放')
# Process video and track objects
while video.isOpened():
success, frame = video.read()
if not success:
break
write_1.write(frame)
# write_2.write(frame)
# get updated location of objects in subsequent frames
success, boxes = multiTracker.update(frame)
# draw tracked objects
for i, newbox in enumerate(boxes):
p1 = (int(newbox[0]), int(newbox[1]))
p2 = (int(newbox[0] + newbox[2]), int(newbox[1] + newbox[3]))
cv2.rectangle(frame, p1, p2, colors[i], 2, 1)
for i, newbox in enumerate(boxes):
vecPoints[i].append((int(newbox[0] + (newbox[2] * 0.5)) * 2, int(newbox[1] + (newbox[3] * 0.5)) * 2))
if len(vecPoints) > 0:
for i in range(len(vecPoints)):
for j in range(len(vecPoints[i]) - 1):
cv2.line(frame, vecPoints[i][j], vecPoints[i][j + 1], colors[i], 1, 8, 1)
for i, newbox in enumerate(boxes):
cv2.putText(frame, 'id_' + str(i + 1), (int(newbox[0]), int(newbox[1]) - 3), cv2.FONT_HERSHEY_PLAIN,1, colors[i], 1)
# show frame
cv2.imshow('Tracker', frame)
# write_1.write(frame)
write_2.write(frame)
# quit on ESC button
if cv2.waitKey(30) == ord('q'):
break
write_1.release()
write_2.release()
print('\n>> 视频保存完毕。')
cv2.destroyWindow('Tracker')
print('\n>> 播放完毕\n')