MindSpore 21天实战营-Yolo实现篮球比赛检测
一、作业流程:
1. 申请华为云账号、申请 ModelArts 华为云昇腾集群服务公测
2. 从链接下载 YOLOv3 ckpt 文件和源代码
3. 创建 obs 桶
4. 本地修改 predict.py 源代码,完成篮球比赛视频的解码和合成工作
5. 上传 YOLOv3 ckpt 文件、篮球比赛视频和修改后的源代码到 obs 桶
6. 提交 ModelArts 训练作业
7. 等待、查看结果
8. 保存预测结果截图
二、最终实现的流程

三、opencv操作样例代码
"""从视频逐帧读取图片"""
import glob
import cv2
# 读取视频文件
cap = cv2.VideoCapture("videoplayback.mp4")
# 获取视频帧率(30p/60p)
frame_rate = round(cap.get(5))
# 获取视频帧数
frame_num = cap.get(7)
# 逐帧获取图片
for i in range(0, frame_num):
# frame就是输出的图片
ret, frame = cap.read()
cap.release()
####################################################### """将图片合成视频"""
# 根据自己的实际情况更改目录。
# 要转换的图片的保存地址,按顺序排好,后面会一张一张按顺序读取。
convert_image_path = 'images'
# 帧率(fps),尺寸(size),size为图片的大小,本文转换的图片大小为1920×1080,
# 即宽为1920,高为1080,要根据自己的情况修改图片大小。
size = (1920, 1080) videoWriter = cv2.VideoWriter('output.mp4', cv2.VideoWriter_fourcc('D', 'I', 'V', 'X'), frame_rate, size)
for img in glob.glob(convert_image_path + "/*.jpg"):
read_img = cv2.imread(img)
videoWriter.write(read_img)
videoWriter.release()
四、目录结构

对于体验作业来说,把截取到的篮球比赛照片放入basketball-dataset中的test目录下。然后执行模型训练就算完成了
我使用的原图:

模型训练参数配置如下:

模型训练结束后识别出来的图如下:

五、进阶作业的难点
进阶作业和体验作业的不同在于,进阶作业需要自己去下载或者拍摄一段视频,然后将视频使用CV库进行切分成图片,然后送入Modlear实现本文第三部分的流程。
这一部分做了好几天都没有好的结果,都是在本地都可以,上传到ModelArts上后就生成不了文件,至今没有下文。参考了huqi大神的文章后生成出来的视频效果稍微好了一点,原本自己生成的视频都特别大,后续继续研究一下发生了什么,这次也做了一次copy攻城狮。感谢一下huqi
import cv2
import os
import moxing as mox
#视频集存储位置
video_path = '/cache/data/videoinput/'
#生成的图像数据集位置
save_path = '/cache/data/images/'
save_fps30 = '/cache/data/image-fp30/'
#拷贝视频
mox.file.copy_parallel('obs://jeffdingtons/mindspore_21/yolo/basketball-dataset/train/',video_path)
#创建路径
if not os.path.exists(save_path):
os.mkdir(save_path)
if not os.path.exists(save_fps30):
os.mkdir(save_fps30)
video_list = os.listdir(video_path)
#遍历视频
for video in video_list:
print(video)
prefix = video.split('.')[0]
if not os.path.exists(os.path.join(save_path,prefix)):
os.mkdir(os.path.join(save_path,prefix))
if not os.path.exists(os.path.join(save_fps30,prefix)):
os.mkdir(os.path.join(save_fps30,prefix))
save_name = os.path.join(save_path,prefix)+'/'
#save_fps30_name = os.path.join(save_fps30,prefix)+'/'
save_fps30_name = save_fps30+'/'
video_name = video_path + video
#读取视频文件
print(video_name)
cap = cv2.VideoCapture(video_name)
fps = cap.get(5)
frame_count = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
print(fps,frame_count)
fps_count = 0
for i in range(frame_count):
ret,frame = cap.read()
if ret:
#帧画面读入图片文件夹
cv2.imwrite(save_name+str(10000+fps_count)+'.jpg',frame)
if fps_count%(int(fps/5))==0:
cv2.imwrite(save_fps30_name+str(10000+fps_count)+'.jpg',frame)
fps_count +=1
mox.file.copy_parallel(save_fps30,"obs://jeffdingtons/mindspore_21/yolo/basketball-dataset/train/fps30")
这一段执行完后,把生成的图片上传到OBS中进行训练predict训练。如果要实现批量图片训练,predict.py需要进行一些小的修改,如下所示:
def predict():
"""The function of predict."""
args = parse_args()
# logger
args.outputs_dir = os.path.join(args.log_path,
datetime.datetime.now().strftime('%Y-%m-%d_time_%H_%M_%S'))
rank_id = int(os.environ.get('RANK_ID'))
args.logger = get_logger(args.outputs_dir, rank_id)
args.logger.info('Creating Network....')
network = YOLOV3DarkNet53(is_training=False)
ckpt_file_slice = args.checkpoint_path.split('/')
ckpt_file = ckpt_file_slice[len(ckpt_file_slice)-1]
local_ckpt_path = '/cache/'+ckpt_file
# download checkpoint
mox.file.copy_parallel(src_url=args.checkpoint_path, dst_url=local_ckpt_path)
args.logger.info(local_ckpt_path)
if os.path.isfile(local_ckpt_path):
param_dict = load_checkpoint(local_ckpt_path)
param_dict_new = {}
for key, values in param_dict.items():
if key.startswith('moments.'):
continue
elif key.startswith('yolo_network.'):
param_dict_new[key[13:]] = values
else:
param_dict_new[key] = values
load_param_into_net(network, param_dict_new)
args.logger.info('load_model {} success'.format(local_ckpt_path))
else:
args.logger.info('{} not exists or not a pre-trained file'.format(local_ckpt_path))
assert FileNotFoundError('{} not exists or not a pre-trained file'.format(local_ckpt_path))
exit(1)
config = ConfigYOLOV3DarkNet53()
local_data_path = '/cache/data'
# data download
print('Download data.')
mox.file.copy_parallel(src_url=args.data_url, dst_url=local_data_path)
# init detection engine
#detection = DetectionEngine(args)
# preprocess the image
images = os.listdir(local_data_path)
for _image in images:
image_path = os.path.join(local_data_path, _image)
image, image_shape = data_preprocess(image_path, config)
args.logger.info('testing shape: {}'.format(config.test_img_shape))
input_shape = Tensor(tuple(config.test_img_shape), ms.float32)
args.logger.info('Start inference....')
network.set_train(False)
prediction = network(Tensor(image.reshape(1, 3, 416, 416), ms.float32), input_shape)
output_big, output_me, output_small = prediction
output_big = output_big.asnumpy()
output_me = output_me.asnumpy()
output_small = output_small.asnumpy()
# init detection engine
detection = DetectionEngine(args)
detection.detect([output_small, output_me, output_big], args.per_batch_size,
image_shape, config)
detection.do_nms_for_results()
img = detection.draw_boxes_in_image(image_path)
local_output_dir = '/cache/output'
if not os.path.exists(local_output_dir):
os.mkdir(local_output_dir)
cv2.imwrite(os.path.join(local_output_dir, _image), img)
# upload output image files
print('Upload output image.')
mox.file.copy_parallel(src_url=local_output_dir, dst_url=args.train_url)
训练会产生标注好的图片,就和体验作业生成的output差不多
全都生成完毕后,我们在使用代码,将这些标注完的图片串联成视频就完成了进阶作业。将图片串联成视频的代码如下:
import os
import cv2
import moxing as mox
#视频位置
video_path = '/cache/data/video/'
#图片保存位置
save_path = '/cache/data/images/'
#图片路径
im_dir = save_path + '/test1/'
if not os.path.exists(video_path):
os.mkdir(video_path)
mox.file.copy_parallel('obs://jeffdingtons/mindspore_21/yolo/outputfile',im_dir)
img_list = os.listdir(im_dir)
img = cv2.imread(im_dir+'/10000.jpg')
width = img.shape[0]
heigh = img.shape[1]
size = (heigh,width)
print(size)
#输出视频路径
video_dir = video_path + '/output1.mp4'
fps=25
num=len(img_list) - 1
img_size = size
fourcc = cv2.VideoWriter_fourcc('D','I','V','X')
video_writer = cv2.VideoWriter(video_dir,fourcc,fps,img_size)
for i in range(1,num):
im_name = os.path.join(im_dir,str(10000+i)+'.jpg')
frame = cv2.imread(im_name)
video_writer.write(frame)
video_writer.release()
mox.file.copy_parallel(video_path,'obs://jeffdingtons/mindspore_21/yolo/output/')
六、现存问题
将在Notebook中运行的代码和predict.py串联后的代码,不知道为什么,读取路径能看见视频传送到ModelArts中,路径也使用的正确的,但是就是出现无法进行转换,不知道是那一块存在问题,课程结束后有时间继续研究探索这一块。
- 点赞
- 收藏
- 关注作者
评论(0)