机器学习在APP启动耗时统计的应用

机器学习与图像识别

Posted by Ted on November 26, 2020

0、统计方案

应用启动耗时统计除了有通过代码来计算,还有一种方案就是通过录屏,然后查看视频,一帧一帧的人工识别启动帧和加载完成的帧,并且用时间戳相减,从而得到启动耗时时间。

这种方案如果多次人工识别就很繁琐,所以我们引入机器学习

1、机器学习自动识别过程

img

这是一个典型的图像识别,因此选择了SVM模型训练数据,通过有监督学习,建立图像和labal之间的对应关系。

框架选择方面,这是传统的机器学习,所以用的是Scikit-learn框架

img

2、准备训练数据

iOS的启动过程:

  1. 启动前
  2. 点击启动iCon
  3. 默认LaunchScreen
  4. 广告页
  5. 首页出现
  6. 首页加载完毕
def cut_video(i_video,o_video):
    print 'cuting...'
    videoCap= cv2.VideoCapture(i_video)
    if not videoCap.isOpened():
        log = i_video + " 该输入路径视频不存在,请检查"
        print(log)
    success, frame = videoCap.read()
    count = 0
    while success:
        if cv2.waitKey(1) == 27:
            break
        count += 1
        success, frame = videoCap.read()
        cv2.imwrite(os.path.join(o_video, 'o_' + str(count) + '.jpg'), frame)
    videoCap.release()

将训练视频按帧分割,这里用的是cv2的库

def make_dir(folder):
    feature_dir = os.path.join(os.getcwd(), folder)
    if not os.path.exists(feature_dir):
        os.makedirs(feature_dir) 

def make_all_folder():
    make_dir('mark_data/0_pre') # 桌面前
    make_dir('mark_data/1_home') # 桌面状态
    make_dir('mark_data/2_icon_click') # 点击icon
    make_dir('mark_data/3_default_show') # 默认启动图
    make_dir('mark_data/4_ad_show') # 广告页
    make_dir('mark_data/5_first_screen') # 首页
    make_dir('mark_data/6_finish') # 完成

生成几个阶段的文件夹,然后将分割好的图片放入对应的阶段

3、模型训练

减少数据大小,将图片缩小10倍,导入标签

def pre_train_datas():
    global img_w
    global img_h
    label_list = []
    image_list = []
    image_classes = os.listdir("mark_data")
    for classes in image_classes:
        image_dir = os.getcwd() + '/mark_data/' + classes
        if not os.path.isdir(image_dir):
            continue
        for image_path in os.listdir(image_dir)[:-1]:
            if image_path.endswith(".jpg"):
                img = Image.open(image_dir+"/"+image_path)
                img_w, img_h = img.size
                img.thumbnail((img_w//10, img_h//10))
                image_list.append(np.asarray(img).flatten())
                label_list.append(classes)
    return image_list, label_list

用SVM训练,得到model

def training_model():
    train_img, train_label = pre_train_datas()

    linear_svc = svm.LinearSVC()
    linear_svc.fit(train_img, train_label)
    model_name = 'model/' + str(img_w) + '_' + str (img_h) + '_model'
    joblib.dump(linear_svc, model_name)

4、测试

将测试视频输入后按帧分割,进行识别,记录启动时和加载完成的时间戳,将时间戳一减便能得到启动时间

def check_video(i_video):
    videoCap= cv2.VideoCapture(i_video)
    if not videoCap.isOpened():
        log = i_video + " 该输入路径视频不存在,请检查"
        print(log)
    
    width = int(videoCap.get(cv2.CAP_PROP_FRAME_WIDTH))
    height = int(videoCap.get(cv2.CAP_PROP_FRAME_HEIGHT))
    model_name = 'model/' + str(width) + '_' + str(height) + '_model'
    clf = joblib.load(model_name)
    success = True
    start = 0.0
    end = 0.0
    count = 0
    while success:
        success, frame = videoCap.read()
        count += 1
        if success:
            milliseconds = videoCap.get(cv2.CAP_PROP_POS_MSEC)
            img = Image.fromarray(cv2.cvtColor(frame,cv2.COLOR_BGR2RGB))  
            img.thumbnail((width//10, height//10))
            a = np.array(img).reshape(1, -1)
            predicts = clf.predict(a)
            print predicts
            if predicts[0] == '2_icon_click' and start == 0:
                start = milliseconds
            if predicts[0] == '6_finish' and end == 0:
                end = milliseconds
    duration = end - start
    print '本次启动时间:' + str(int(duration)) + 'ms'

img