掘金 人工智能 前天 17:28
高通手机跑AI系列之——实时头发识别
index_new5.html
../../../zaker_core/zaker_tpl_static/wap/tpl_guoji1.html

 

本文介绍了一个基于AidLux 2.0和TNN模型的实时人物分割应用,该应用能够在手机上实现高效的人物与背景分离。通过准备手机环境(如Redmi K60 Pro)和安装AidLux APP,用户可以运行代码来调用轻量级的AI模型。代码的核心功能包括摄像头初始化、AI模型加载与配置、实时图像处理流程(预处理、推理、后处理生成掩码)以及性能监控。该应用能够将分割结果与原始图像叠加,实现背景虚化、虚拟试衣等多种视觉效果,为手机端的AI应用提供了实际的解决方案。

📱 **环境与软件准备**:文章详细列出了运行实时人物分割应用的硬件和软件需求。硬件方面,推荐使用性能较好的手机,如搭载骁龙8 Gen 2处理器的Redmi K60 Pro,并提及了内存、摄像头和AI算力等关键配置。软件方面,核心是AidLux 2.0 APP,并强调了在Ubuntu 20.04.3 LTS环境下运行代码的流畅性,以及为保证进程不被回收需要保持AidLux在前台运行和屏幕常亮。

💡 **核心AI模型与框架**:该应用的核心是一个轻量级的图像分割模型(segmentation.tnnmodel),采用TNN框架优化,专门用于实时分离人物与背景。模型输入为256x256的RGB图像,输出为两个256x256的概率图,分别代表背景和前景。Aidlite框架负责模型的加载、配置和加速执行(支持GPU),而OpenCV库则用于图像的预处理(如尺寸调整、颜色空间转换)和后处理(如掩码与原图的叠加合成)。

🚀 **应用功能与场景**:该应用的核心功能是实现实时的人物背景分割,并能生成二值掩码。通过将掩码与原始视频帧叠加,可以实现多种视觉效果,如背景虚化、虚拟背景替换、绿幕抠像替代方案、AR试衣/美妆等。文章还分析了模型的优势(实时性强、资源占用低、效果自然)和局限性(依赖光照、边界细节不足、仅支持单人物)。

⏱️ **性能监控与代码细节**:代码中包含了详细的性能监控机制,记录并打印了图像预处理、模型输入设置、推理、输出获取以及后处理等各个阶段的耗时,并计算总处理时间,以便评估系统性能。此外,代码还提供了摄像头管理功能,支持自动检测USB摄像头或使用设备内置摄像头,并对摄像头打开失败的情况进行了处理和重试,确保了应用的鲁棒性。

(原创作者@CSDN_伊利丹~怒风)

环境准备

手机

测试手机型号:Redmi K60 Pro

处理器:第二代骁龙8移动--8gen2

运行内存:8.0GB ,LPDDR5X-8400,67.0 GB/s

摄像头:前置16MP+后置50MP+8MP+2MP

AI算力:NPU 48Tops INT8 && GPU 1536ALU x 2 x 680MHz = 2.089 TFLOPS

提示:任意手机均可以,性能越好的手机速度越快

软件

APP:AidLux2.0

系统环境:Ubuntu 20.04.3 LTS

提示:AidLux登录后代码运行更流畅,在代码运行时保持AidLux APP在前台运行,避免代码运行过程中被系统回收进程,另外屏幕保持常亮,一般息屏后一段时间,手机系统会进入休眠状态,如需长驻后台需要给APP权限。

算法Demo

Demo代码介绍

主要功能

这段代码实现了一个实时人物分割应用,主要功能包括:

    摄像头初始化与管理:

      支持自动检测和选择 USB 摄像头提供备用方案,在无 USB 摄像头时使用设备内置摄像头处理摄像头打开失败的情况并进行重试

    AI 模型加载与配置:

      使用 aidlite 框架加载轻量级神经网络模型配置模型输入输出格式和加速选项(GPU)初始化模型解释器并准备进行推理

    实时图像处理流程:

      捕获摄像头视频帧图像预处理(调整大小、颜色空间转换)模型推理,获取前景和背景分割结果后处理生成二值掩码将掩码与原始图像叠加显示

    性能监控:

      记录并打印各个处理阶段的耗时计算总处理时间,评估系统性能

这个应用可以用于简单的实时背景替换、虚拟试衣、视频会议中的背景虚化等场景。通过调整掩码生成算法和叠加方式,可以获得更丰富的视觉效果。

Aidlite 框架

Aidlite 框架 是一个用于模型推理的框架,而非具体模型。它提供了模型加载、加速和执行的功能。

框架功能:

• 模型管理:创建实例、设置输入输出格式

• 硬件加速:支持 CPU/GPU/NPU 等多种后端

• 张量操作:输入数据传递、输出结果获取

OpenCV 计算机视觉功能

代码中使用了 OpenCV 的图像处理功能(如cv2.resize、cv2.addWeighted),但这些属于传统计算机视觉算法,并非 AI 模型。

关键功能:

总结

代码中实际使用的 AI 模型只有1 个(segmentation.tnnmodel),用于人物分割。另外两个组件是:

这种架构体现了典型的 AI 应用模式:AI 模型负责核心任务(分割),传统算法负责前后处理(图像调整、结果可视化)

AI模型介绍

这段代码中的模型是一个轻量级的图像分割模型,专门用于实时人物与背景的分离。下面从模型架构、功能和应用场景三个方面进行详细分析:

1. 模型架构

根据代码中的参数配置,可以推测该模型的特点:

2. 应用场景

基于人物分割功能,该模型可用于:

3. 性能与限制

Demo代码

import cv2import timefrom time import sleepimport subprocessimport remiimport sysimport numpy as npimport aidliteimport os # 获取USB摄像头ID函数def get_cap_id():    try:        # 执行shell命令获取所有USB视频设备的ID        cmd = "ls -l /sys/class/video4linux | awk -F ' -> ' '/usb/{sub(/.*video/, \"\", $2); print $2}'"        result = subprocess.run(cmd, shell=True, capture_output=True, text=True)        output = result.stdout.strip().split()         # 将设备ID转换为整数并返回最小值(优先使用第一个检测到的USB摄像头)        video_numbers = list(map(int, output))        if video_numbers:            return min(video_numbers)        else:            return None    except Exception as e:        print(f"获取摄像头ID时出错: {e}")        return None # 图像合成函数:将分割掩码与原始图像叠加def transfer(image, mask):    # 调整掩码大小与原始图像一致    mask = cv2.resize(mask, (image.shape[1], image.shape[0]))    # 创建与原始图像相同尺寸的三通道掩码    mask_n = np.zeros_like(image)    mask_n[:, :, 0] = mask  # 将掩码值赋给蓝色通道     # 设置透明度参数    alpha = 0.7  # 原始图像透明度    beta = (1.0 - alpha)  # 掩码图像透明度    # 加权叠加原始图像和掩码图像    dst = cv2.addWeighted(image, alpha, mask_n, beta, 0.0)    return dst # 模型输入输出参数配置w = 256  # 模型输入宽度h = 256  # 模型输入高度 # 定义模型输入输出形状inShape = [[1, w, h, 3]]  # 输入: 1张RGB图像,尺寸256x256outShape = [[1, w, h], [1, w, h]]  # 输出: 两个256x256的分割图model_path = "models/segmentation.tnnmodel"  # 模型文件路径 # 加载模型model = aidlite.Model.create_instance(model_path)if model is None:    print("模型创建失败!") # 设置模型属性:输入为uint8类型,输出为float32类型model.set_model_properties(inShape, aidlite.DataType.TYPE_UINT8, outShape, aidlite.DataType.TYPE_FLOAT32) # 配置模型加速类型为GPUconfig = aidlite.Config.create_instance()config.accelerate_type = aidlite.AccelerateType.TYPE_GPU # 构建并初始化模型解释器fast_interpreter = aidlite.InterpreterBuilder.build_interpretper_from_model_and_config(model, config)if fast_interpreter is None:    print("解释器创建失败!")result = fast_interpreter.init()if result != 0:    print("解释器初始化失败!")result = fast_interpreter.load_model()if result != 0:    print("模型加载失败!")print("模型加载成功!") # 设备类型和摄像头ID配置aidlux_type = "basic"# 0-后置摄像头,1-前置摄像头camId = 1opened = False # 尝试打开摄像头,失败则重试while not opened:    if aidlux_type == "basic":        # 基本设备使用MIPI接口打开前置摄像头        cap = cv2.VideoCapture(camId, device='mipi')    else:        # 其他设备优先使用USB摄像头        capId = get_cap_id()        print("USB摄像头ID: ", capId)        if capId is None:            print("未找到USB摄像头")            # 默认使用前置摄像头            cap = cv2.VideoCapture(1, device='mipi')        else:            camId = capId            cap = cv2.VideoCapture(camId)            # 设置视频编码格式为MJPG            cap.set(6, cv2.VideoWriter.fourcc('M', 'J', 'P', 'G'))        # 检查摄像头是否成功打开    if cap.isOpened():        opened = True    else:        print("摄像头打开失败")        cap.release()  # 释放摄像头资源        time.sleep(0.5)  # 等待0.5秒后重试 # 主循环:实时捕获、处理和显示视频while True:    # 读取一帧图像    ret, frame = cap.read()    if not ret:        continue  # 读取失败则跳过当前帧    if frame is None:        continue  # 空帧则跳过        # 如果使用前置摄像头,水平翻转图像以获得镜像效果    if camId == 1:        frame = cv2.flip(frame, 1)        # 记录处理时间点    t0 = time.time()        # 图像预处理    img = cv2.resize(frame, (w, w))  # 调整图像大小为模型输入尺寸    img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)  # 转换颜色空间从BGR到RGB        t1 = time.time()    print('tnn: 开始设置输入')        # 将预处理后的图像数据传入模型    result = fast_interpreter.set_input_tensor(0, img.data)    print(result)    if result != 0:        print("设置输入张量失败")        t2 = time.time()    print('tnn: 开始推理')        # 执行模型推理    result = fast_interpreter.invoke()    if result != 0:        print("模型推理失败")        t3 = time.time()        # 获取模型输出结果    pred_1 = fast_interpreter.get_output_tensor(1)    if pred_1 is None:        print("获取输出张量1失败!")        pred_0 = fast_interpreter.get_output_tensor(0)    if pred_0 is None:        print("获取输出张量0失败!")        print('预测结果形状:', pred_0.shape, pred_1.shape)    t4 = time.time()        # 重塑输出张量为二维数组    pred0 = (pred_0).reshape(w, h)    pred1 = (pred_1).reshape(w, h)        # 提取背景和前景预测结果    back = ((pred0)).copy()    front = ((pred1)).copy()    t5 = time.time()        # 计算前景掩码:前景分数减去背景分数    mask = front - back    print('掩码值范围:', mask)        # 二值化掩码:大于0的区域为前景(255),小于等于0的区域为背景(0)    mask[mask > 0] = 255    mask[mask <= 0] = 0        # 将掩码与原始图像叠加    dst = transfer(frame, mask)        # 打印各处理阶段耗时    print('预处理耗时:%f===设置输入耗时:%f===推理耗时:%f===获取输出耗时:%f===后处理耗时:%f' % (        t1 - t0, t2 - t1, t3 - t2, t4 - t3, t5 - t4))    print('总耗时', t5 - t0)        # 显示处理结果    cv2.imshow("", dst)        # 按ESC键退出程序    key = cv2.waitKey(1)    if key == 27:  # ESC键        break # 释放资源cap.release()cv2.destroyAllWindows()

模型位置

/opt/aidlux/app/aid-examples/hair_seg

模型效果

Fish AI Reader

Fish AI Reader

AI辅助创作,多种专业模板,深度分析,高质量内容生成。从观点提取到深度思考,FishAI为您提供全方位的创作支持。新版本引入自定义参数,让您的创作更加个性化和精准。

FishAI

FishAI

鱼阅,AI 时代的下一个智能信息助手,助你摆脱信息焦虑

联系邮箱 441953276@qq.com

相关标签

AidLux 实时人物分割 AI模型 TNN 计算机视觉
相关文章