本期更新全是乾貨

首先説一下我們跑完訓練好的跟蹤器之後,可能想自己製作一個視頻,然後運用到跟蹤當中,這期博主帶大家一步一步的完成這個目標,看很多博客沒有系統的製作,並且過程比較繁瑣,沒有統一的説明。這次給大家帶些福利,節省大家科研工作的時間!歡迎大家積極討論!

注:博主也是花了很多時間,所以,如果説對大家有用,給博主點點關注,謝謝!

視頻採集

攝像頭單獨視頻採集的代碼博主放在這裏,供大家使用(常用的.avi和.mp4格式)

import cv2
cap = cv2.VideoCapture(0)
# Define the codec and create VideoWriter object
fourcc = cv2.VideoWriter_fourcc(*'XVID')
out = cv2.VideoWriter('C:\\Users\\26254\\Desktop\\save_webcam_video.avi', fourcc, 20.0, (640,  480))#注意路徑
while cap.isOpened():
    ret, frame = cap.read()
    if not ret:
        print("Can't receive frame (stream end?). Exiting ...")
        break
    # write frame
    out.write(frame)
    cv2.imshow('webcam', frame)
    # press key 'q' to quit
    if cv2.waitKey(1) == ord('q'):
        break
# Release everything if job is finished
cap.release()
out.release()
cv2.destroyAllWindows()

視頻轉化為圖像代碼

然後可以將視頻轉化為圖片的代碼,供大家使用

import cv2
from cv2 import VideoWriter, VideoWriter_fourcc, imread, resize
import os
from PIL import Image
 
def Video2Pic():#視頻轉換為圖片
    videoPath = "C:/Users/HK/Desktop/shipin/cup.avi"  # 讀取視頻路徑,還有格式'.mp4'
    imgPath = "C:/Users/HK/Desktop/shipin/cup/"  # 保存圖片路徑
 
    cap = cv2.VideoCapture(videoPath)
    # fps = cap.get(cv2.CAP_PROP_FPS)  # 獲取幀率
    # width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))  # 獲取寬度
    # height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))  # 獲取高度
    suc = cap.isOpened()  # 是否成功打開
    frame_count = 0
    while suc:
        frame_count += 1
        suc, frame = cap.read()
        cv2.imwrite(imgPath + str(frame_count).zfill(4)+'.jpg', frame)#注jpg格式可以換為png格式
        cv2.waitKey(1)
    cap.release()
    print("視頻轉圖片結束!")


def Pic2Video():
    imgPath = "youimgPath"  # 讀取圖片路徑
    videoPath = "youvideoPath"  # 保存視頻路徑
 
    images = os.listdir(imgPath)
    fps = 25  # 每秒25幀數
 
    # VideoWriter_fourcc為視頻編解碼器 ('I', '4', '2', '0') —>(.avi) 、('P', 'I', 'M', 'I')—>(.avi)、('X', 'V', 'I', 'D')—>(.avi)、('T', 'H', 'E', 'O')—>.ogv、('F', 'L', 'V', '1')—>.flv、('m', 'p', '4', 'v')—>.mp4
    fourcc = VideoWriter_fourcc(*"MJPG")
 
    image = Image.open(imgPath + images[0])
    videoWriter = cv2.VideoWriter(videoPath, fourcc, fps, image.size)
    for im_name in range(len(images)):
        frame = cv2.imread(imgPath + images[im_name])  # 這裏的路徑只能是英文路徑
        # frame = cv2.imdecode(np.fromfile((imgPath + images[im_name]), dtype=np.uint8), 1)  # 此句話的路徑可以為中文路徑
        print(im_name)
        videoWriter.write(frame)
    print("圖片轉視頻結束!")
    videoWriter.release()
    cv2.destroyAllWindows()


# 此處添加上述兩個函數
 
 
if __name__ == '__main__':
    Video2Pic()
    # Pic2Video()

圖片轉化為視頻代碼

由圖片轉化為視頻的代碼,大家幀率按照需求來定吧

import os
import cv2

# image path
im_dir = '/media/mrtrying/ysdtracker/test/tracker_benchmark_v1.0/tmp/imgs/bike1_1'
# im_dir = '/home/mrtrying/shiyan/shujuji/cup'
# output video path
video_dir = '/home/mrtrying/shiyan/shujuji'
if not os.path.exists(video_dir):
    os.makedirs(video_dir)
# set saved fps
fps = 20
# get frames list
frames = sorted(os.listdir(im_dir))
# w,h of image
img = cv2.imread(os.path.join(im_dir, frames[0]))
img_size = (img.shape[1], img.shape[0])
# get seq name
seq_name = os.path.dirname(im_dir).split('/')[-1]
# splice video_dir
# video_dir = os.path.join(video_dir, seq_name + '.avi')
# fourcc = cv2.VideoWriter_fourcc('M', 'J', 'P', 'G')
video_dir = os.path.join(video_dir, seq_name + '.mp4')
fourcc = cv2.VideoWriter_fourcc('M', 'p', '4', 'V')
# also can write like:fourcc = cv2.VideoWriter_fourcc(*'MJPG')
# if want to write .mp4 file, use 'MP4V'
videowriter = cv2.VideoWriter(video_dir, fourcc, fps, img_size)

for frame in frames:
    f_path = os.path.join(im_dir, frame)
    image = cv2.imread(f_path)
    videowriter.write(image)
    print(frame + " has been written!")

videowriter.release()

視覺跟蹤demo所需要的代碼

這裏就是訓練好的跟蹤器,需要加載訓練好的模型才可以,用於測試單獨序列的代碼,也比較簡單

from __future__ import absolute_import

import os
import sys
sys.path.append(os.getcwd())
import glob
import numpy as np
import argparse
import cv2
import torch

from xxx import Tracker#加載所構建的跟蹤器,這裏需要大家加入自己的跟蹤器

import multiprocessing
multiprocessing.set_start_method('spawn',True)


model_path = 'models/ysdtracker_20.pth'
gpu_id = 0

def get_axis_aligned_bbox(region):
    """ convert region to (cx, cy, w, h) that represent by axis aligned box
    """
    # nv = region.size
    nv = 4
    if nv == 8:
        cx = np.mean(region[0::2])
        cy = np.mean(region[1::2])
        x1 = min(region[0::2])
        x2 = max(region[0::2])
        y1 = min(region[1::2])
        y2 = max(region[1::2])
        A1 = np.linalg.norm(region[0:2] - region[2:4]) * \
            np.linalg.norm(region[2:4] - region[4:6])
        A2 = (x2 - x1) * (y2 - y1)
        s = np.sqrt(A1 / A2)
        w = s * (x2 - x1) + 1
        h = s * (y2 - y1) + 1
    else:
        x = region[0]
        y = region[1]
        w = region[2]
        h = region[3]
        cx = x+w/2
        cy = y+h/2
    return cx, cy, w, h

def cxy_wh_2_rect(pos, sz):
    return np.array([pos[0]-sz[0]/2, pos[1]-sz[1]/2, sz[0], sz[1]])  # 0-index
### 測試圖片視頻序列
# image and init box
image_files = sorted(glob.glob('/home/mrtrying/shiyan/shujuji/OTB2015/Basketball/img/*.jpg')) #測試序列的路徑
init_rbox = [198,214,34,81]
init_rbox =  list(map(int, init_rbox))
tracker=Tracker(model_path,0)#這裏就是構建和加載測試數據集構建的跟蹤器,需要自己加載

[cx, cy, w, h] = get_axis_aligned_bbox(init_rbox)

# tracker init
target_pos, target_sz = np.array([cx, cy]), np.array([w, h])
im = cv2.imread(image_files[0])  # HxWxC
state = tracker.init(im,init_rbox)

# tracking and visualization
toc = 0
for f, image_file in enumerate(image_files):
    im = cv2.imread(image_file)
    tic = cv2.getTickCount()
    state = tracker.update(im)  # track
    bbox = list(map(int, state))
    toc += cv2.getTickCount()-tic
    cv2.rectangle(im, (bbox[0], bbox[1]), (bbox[0]+bbox[2], bbox[1]+bbox[3]), (0, 255, 255), 3)
    cv2.imshow('demo', im)
    cv2.waitKey(1)

print('Tracking Speed {:.1f}fps'.format((len(image_files)-1)/(toc/cv2.getTickFrequency())))

下面的代碼主要是測試自己所採集的視頻,需要注意的是視頻要為avi格式,mp4格式要報錯,同時保存為圖像,為後面的gif動圖做準備,

from __future__ import absolute_import

import os
import sys
sys.path.append(os.getcwd())
import glob
import numpy as np
import argparse
import cv2
import torch

from xxx import Tracker#這裏需要改動的是:需要加載自己測試數據集是所用到的跟蹤器

import multiprocessing
multiprocessing.set_start_method('spawn',True)


model_path = 'models/ysdtracker_20.pth'
gpu_id = 0

###測試自己拍攝的視頻

def get_frames(video_name):
    if not video_name:
        cap = cv2.VideoCapture(0)
        # warmup
        for i in range(5):
            cap.read()
        while True:
            ret, frame = cap.read()
            if ret:
                yield frame
            else:
                break
    elif video_name.endswith('avi') or \
        video_name.endswith('mp4'):
        cap = cv2.VideoCapture(args.video_name)
        while True:
            ret, frame = cap.read()
            if ret:
                yield frame
            else:
                break
    else:
        images = glob(os.path.join(video_name, '*.jp*'))
        images = sorted(images,
                        key=lambda x: int(x.split('/')[-1].split('.')[0]))
        for img in images:
            frame = cv2.imread(img)
            yield frame

video='/home/mrtrying/shiyan/mytest/myEI/save.avi'#加載自己的視頻路徑

parser = argparse.ArgumentParser(description='tracking demo')
parser.add_argument('--video_name', default=video, type=str,
                    help='videos or image files')
args = parser.parse_args()
def main():
    # build tracker
    tracker=Tracker(model_path,0)

    first_frame = True
    if args.video_name:
        video_name = args.video_name.split('/')[-1].split('.')[0]
    else:
        video_name = 'webcam'
    cv2.namedWindow(video_name, cv2.WND_PROP_FULLSCREEN)
    pic = "/home/mrtrying/shiyan/mytest/myEI/pic/"#保存圖像到指定路徑下
    c = 0#用來建立幀數,為了能夠跟蹤過程中的每一幀都可以保存
    for frame in get_frames(args.video_name):
        if first_frame:
            try:
                init_rect = cv2.selectROI(video_name, frame, False, False)
            except:
                exit()
            tracker.init(frame, init_rect)
            first_frame = False
        else:
            outputs = tracker.update(frame) #這裏的只能送入幀數
            c = c + 1
            bbox = list(map(int, outputs))
            cv2.rectangle(frame, (bbox[0], bbox[1]),
                            (bbox[0]+bbox[2], bbox[1]+bbox[3]),
                            (0, 0, 255), 3)
            cv2.imshow(video_name, frame)
            
            # cv2.imwrite('video_name.jpg',frame)
            cv2.imwrite(pic + video_name + str(c) + '_' + '.jpg',frame)
            cv2.waitKey(40)
if __name__ == '__main__':
    main()

視覺跟蹤自己的demo產生gif

import imageio
import glob

def main():
    c = 0
    image_listall = sorted(glob.glob('/home/mrtrying/shiyan/mytest/myEI/pic/*.jpg'))#用於長度的計算
    image_list_ = []
    frames = []
    duration = 0.01
    for i in range(len(image_listall)):
        c = c + 1
        image_list_.append(sorted(glob.glob('/home/mrtrying/shiyan/mytest/myEI/pic/save{}_.jpg'.format(c))))
    for image_list in image_list_:
        for image_name in image_list:
            frames.append(imageio.imread(image_name))
    gif_name = '/home/mrtrying/shiyan/mytest/myEI/demo.gif'
    imageio.mimsave(gif_name, frames, 'GIF', duration=duration)

if __name__ == '__main__':
    main()

最後説一句,博主不易,請大家點點關注!