ProjectA 项目辅助脚本档案

本文主要记录在做 ProjectA 时用到的 Python 脚本,因为用得频繁,所以做成了脚本,避免重复输命令。

项目树状结构图如下:

.
├── CommonTips.py
├── DumpPhotos.py
├── FallWithMask.py
├── OfflineSoRunner.py
└── main.py

它主要的功能是:

  • 从 Android 手机拉取照片(需要手机连接到电脑并且安装好 adb 命令)
  • 在 Android 手机上以 shell 的形式跑 so 库算法,一般是在 apk 上运行
  • 这个带 mask 分析已经看不懂是什么意思了

入口:main.py

import CommonTips
import DumpPhotos
import OfflineSoRunner
import FallWithMask
sub_model_name = 'Main Menu'
op_info = '''\n--------------Main Menu--------------
| 【0】:Dump照片
| 【1】:离线跑算法库
| 【2】:带mask分析跌倒视频''' + CommonTips.tip_ops+'-------------------------------------\n'
print(op_info)

while True:
    cmd = input('('+sub_model_name+')'+CommonTips.tip_input_cmd)

    if cmd.isdigit():
        cmd = int(cmd)
        if cmd == 0:
            DumpPhotos.main()
        elif cmd == 1:
            OfflineSoRunner.main()
        elif cmd == 2:
            FallWithMask.main()
        else:
            print(CommonTips.tip_arg_error)
    else:
        if 'h' == cmd.lower():
            print(op_info)
        elif 'q' == cmd.lower():
            print(CommonTips.tip_quit)
            break
        else:
            print(CommonTips.tip_arg_error)

提示输出:CommonTips.py

tip_arg_error = '''--------------------------
| X 参数错误,请重新输入! |
--------------------------\n'''
tip_quit = "已退出子模块"
tip_input_cmd = "请输入命令:"
tip_ops = '''\n|************************************
| 【h】:打印本帮助
| 【q】:退出本模块
'''

拉取照片:DumpPhotos.py

import os

import CommonTips

sub_model_name = 'Dump照片'

save_path = "C:\\Users\\D22433\\Desktop\\DumpPhotos\\"
remote_path = "/sdcard/AlgoTest/"

pull_photo_2_local = "adb pull "+remote_path+" "+save_path
del_local_photos = "del /Q "+save_path+"\\*"
del_remote_photos = 'adb shell "rm -rf '+remote_path+'/*"'

op_info = '''--------------Dump照片--------------
| 【0】:从安卓端拉取dump照片至本地
| 【1】:删除本地dump照片
| 【2】:删除安卓dump照片
| 【3】:删除本地&安卓dump照片''' + CommonTips.tip_ops+'-----------------------------------'


def main():
    print(op_info)
    while True:
        cmd = input('('+sub_model_name+')'+CommonTips.tip_input_cmd)

        if cmd.isdigit():
            cmd = int(cmd)
            if cmd == 0:
                os.system(pull_photo_2_local)
            elif cmd == 1:
                os.system(del_local_photos)
            elif cmd == 2:
                os.system(del_remote_photos)
            elif cmd == 3:
                os.system(del_local_photos)
                os.system(del_remote_photos)
            else:
                print(CommonTips.tip_arg_error)
        else:
            if 'h' == cmd.lower():
                print(op_info)
            elif 'q' == cmd.lower():
                print(CommonTips.tip_quit)
                break
            else:
                print(CommonTips.tip_arg_error)


if __name__ == '__main__':
    main()

离线跑 so 库:OfflineSoRunner.py

# -*- coding:utf-8 -*-
import os
import CommonTips

sub_model_name = '跑离线算法库'

model_path_local = 'E:\\ProjectA\\latestModel'
model_path_remote = '/sdcard/apache/model/'

exe_path_local = 'E:\\projects\\Android\\projectA_app\\app\\build\\intermediates\\cmake\\debug\\obj\\arm64-v8a\\executor'
exe_path_remote = '/system/app/'

so_path_local = 'E:\\ProjectA\\latestLib'
so_path_remote = '/system/lib64/'

cmd_push_model = 'adb push ' + model_path_local + ' ' + model_path_remote
cmd_push_exe = 'adb push ' + exe_path_local + ' ' + exe_path_remote
cmd_grant_permission = 'adb shell chmod 777 /system/app/executor'
cmd_push_so = 'adb push ' + so_path_local + ' ' + so_path_remote

op_info = '''--------------跑离线算法库--------------
| 【0】:推送算法库所需要的数据文件
| 【1】:推送算法库so文件
| 【2】:推送可执行文件并授予运行权限
| 【3】:执行可执行文件
|    1 for testing checkFall
|    2 for testing detectFaceNumber
|    3 for testing extractFaceFeature
|    others for quit.''' + CommonTips.tip_ops + '----------------------------------------'


def main():
    print(op_info)
    while True:
        cmd = input('('+sub_model_name+')'+CommonTips.tip_input_cmd)
        if cmd.isdigit():
            cmd = int(cmd)
            if cmd == 0:
                os.system(cmd_push_model)
            elif cmd == 1:
                os.system(cmd_push_so)
            elif cmd == 2:
                os.system(cmd_push_exe)
                os.system(cmd_grant_permission)
            elif cmd == 3:
                while True:
                    choice = input("测试选项:")
                    if choice == '1' or choice == '2' or choice == '3':
                        # do something about checkFall
                        command = 'adb shell "/system/app/executor ' + choice + ' `ls /sdcard/TestData' + choice + '`"'
                        print(command)
                        os.system(command)
                    else:
                        break
            else:
                print(CommonTips.tip_arg_error)
        else:
            if 'h' == cmd.lower():
                print(op_info)
            elif 'q' == cmd.lower():
                print(CommonTips.tip_quit)
                break
            else:
                print(CommonTips.tip_arg_error)


if __name__ == '__main__':
    main()

带 mask 分析:FallWithMask.py

import os

import CommonTips

sub_model_name = '带mask跌倒检测'

exe_path = 'E:\\ProjectA\\TestVideoWithMask\\TestVideoWithMask.exe'
video_path = 'E:\\ProjectA\\videos'
remote_path = '/sdcard/LuPingDaShi/Rec/'

op_info = '--------------带mask跌倒检测--------------'


def main():
    # pull videos
    pull = input("是否要从Android拉取视频(y/N):")
    if pull == 'y':
        os.system('adb pull '+remote_path+' '+video_path+' ')
        os.system('adb shell rm '+remote_path+'* ')

    files = os.listdir(video_path)
    print("可用来测试的视频 :")
    for f in range(0, len(files)):
        print('【'+str(f)+'】 : '+files[f])

    while True:
        idx = input('(' + sub_model_name + ')' + "请选择序号:")

        if idx.isdigit():
            idx = int(idx)
            if idx >= len(files) or idx < 0:
                print(CommonTips.tip_arg_error+"---数组越界")
            else:
                os.system(exe_path + ' ' + video_path + '\\' + files[idx]+' >> log.txt')
        else:
            if 'h' == idx.lower():
                print(op_info)
            elif 'q' == idx.lower():
                print(CommonTips.tip_quit)
                break
            elif 'r' == idx.lower():
                files = os.listdir(video_path)
                print("可用来测试的视频 :")
                for f in range(0, len(files)):
                    print('【' + str(f) + '】 : ' + files[f])
            else:
                print(CommonTips.tip_arg_error)


if __name__ == '__main__':
    main()

Read more

Volcano 与 Kubernetes GPU 调度学习笔记

本笔记系统整理 Volcano 调度器、Kubernetes 调度框架、GPU Device Plugin、HAMi 等云原生 AI 调度领域的核心知识,适合用于学习、复习和工程实践参考。 目录 * 第一部分:Volcano 入门 * 1. Volcano 是什么 * 2. 安装与快速使用 * 3. 核心特性一览 * 第二部分:Volcano 整体架构 * 4. Volcano 解决的核心问题 * 5. 整体架构与数据流 * 6. 三层抽象模型 * 第三部分:Volcano 核心实现原理 * 7. Session 机制 * 8. Gang Scheduling 实现 * 9. Queue 与 DRF 公平调度

容器镜像(4):镜像的常用工具箱

容器镜像(4):镜像的常用工具箱

前几篇在讲多架构镜像时已经用过 skopeo 和 crane 做镜像复制,这篇系统整理这两个工具的完整能力,同时介绍几个日常操作镜像时同样好用的工具。 一、skopeo:不依赖 Daemon 的镜像瑞士军刀 skopeo 的核心价值是绕过 Docker daemon,直接与 Registry API 交互。上一篇用它做镜像复制和离线传输,但它的能力远不止于此。 1.1 安装 # Ubuntu / Debian sudo apt install -y skopeo skopeo --version # skopeo version 1.15.1 1.2 inspect:免拉取检查镜像元数据 docker inspect 需要先把镜像拉到本地,skopeo inspect 直接向 Registry

容器镜像(3):多架构镜像构建

容器镜像(3):多架构镜像构建

一、什么是多架构镜像 1.1 OCI Image Index 上一篇介绍了单平台镜像的结构:一个 Manifest 指向 Config 和若干 Layer blob。多架构镜像在此之上多了一层——OCI Image Index(也叫 Manifest List),是一个轻量的索引文件,把多个单平台 Manifest 组织在一起: $ docker manifest inspect golang:1.22-alpine { "schemaVersion": 2, "mediaType": "application/vnd.oci.image.index.v1+json", "manifests&

容器镜像(2):containerd 视角下的镜像

容器镜像(2):containerd 视角下的镜像

一、为什么需要了解 containerd 如果你只用 docker run 跑容器,从来不关心底层,那可以不了解 containerd。但如果你在用 Kubernetes,或者想真正理解"容器运行时"是什么,containerd 是绕不开的。 事实上,当你执行 docker run 的时候,containerd 早就在后台悄悄工作了——Docker 从 1.11 版本开始,就把核心运行时剥离出来交给 containerd 负责。 1.1 Docker 的架构演变 早期的 Docker(1.10 及之前)是一个"大一统"的单体程序:一个 dockerd