MindSpore 21天实战营-Yolo实现篮球比赛检测

举报
JeffDing 发表于 2020/11/10 15:56:41 2020/11/10
【摘要】 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中,路径也使用的正确的,但是就是出现无法进行转换,不知道是那一块存在问题,课程结束后有时间继续研究探索这一块。


【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。