尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

手把手教你Android调用AI手势识别:彩虹骨骼可视化完整教程

手把手教你Android调用AI手势识别:彩虹骨骼可视化完整教程 手把手教你Android调用AI手势识别彩虹骨骼可视化完整教程1. 引言1.1 从想法到指尖为什么需要移动端手势识别想象一下你正在开发一款健身应用用户可以通过手势在空中划动来切换训练课程或者你正在设计一款儿童教育游戏孩子用手势比划出字母就能触发动画。这些充满未来感的交互其核心就是手势识别技术。过去在手机上实现精准的手势识别是个不小的挑战。要么需要把摄像头拍到的画面传到遥远的服务器去分析等结果传回来手势早就做完了体验非常卡顿。要么就是本地运行的模型又大又慢手机发烫不说识别还经常出错。现在情况不一样了。基于Google MediaPipe Hands模型的技术方案让我们能在普通的Android手机上完全离线、实时地识别出手部的21个关键点速度快到毫秒级别。更酷的是通过“彩虹骨骼”可视化技术我们能清晰地看到每根手指的运动轨迹——拇指是黄色食指是紫色中指是青色无名指是绿色小指是红色科技感十足。这篇文章就是一份详细的“施工图纸”。我会带你一步步在Android应用里集成这个强大的手势识别能力从零开始直到在手机屏幕上画出那副炫酷的彩虹骨骼图。无论你是想开发体感游戏、AR应用还是智能家居控制这篇教程都能帮你把想法变成现实。2. 项目核心认识我们的工具2.1 MediaPipe Hands藏在手机里的“手语翻译官”简单来说MediaPipe Hands就像一个高度专注的“手语翻译官”。它不关心整张图片里有什么花花草草只盯着一样东西手。它的工作流程非常高效定位首先在图像中快速找到手的位置哪怕只露出一部分。标点然后在这只手上精准地标出21个三维坐标点包括每个指尖、指关节和手腕。理解最后根据这些点的位置关系“理解”手正在做什么姿势。这个方案最大的优点就是“轻快准”。模型经过专门优化在手机CPU上就能飞快运行完全不需要联网也保护了用户的隐私。我们使用的镜像已经把这个“翻译官”和它的所有工具模型、算法都打包好了开箱即用省去了自己搭建环境的麻烦。2.2 彩虹骨骼让数据“看得见”光有21个冷冰冰的坐标点对我们和用户来说都不够直观。这就是“彩虹骨骼”可视化出场的时候了。它的作用就像给X光片上了色白点代表21个手部关节点清晰标注位置。彩线按照手指分组用不同颜色的线条把关节点连接起来形成完整的手指骨骼。这样做的好处一目了然开发调试方便你能立刻看到算法识别得对不对手指连接是否合理。用户体验提升在最终应用里彩色的线条比一堆白点更有动感和科技感。手势判断更简单通过观察彩色线条的形态变化比如食指和中指竖起其他手指弯曲可以更容易地编程识别出“胜利”、“点赞”、“OK”等具体手势。3. 开发环境搭建与项目初始化3.1 准备工作清单在开始写代码之前请确保你的“工具箱”里备齐了以下物品Android Studio建议使用较新的版本如Giraffe 2022.3.1或更高它提供了更好的Gradle和Kotlin支持。一个Android项目可以新建一个也可以使用现有的。本教程以新建的Empty Views Activity项目为例。模拟器或真机用于运行和测试。建议使用API 24Android 7.0或更高版本的设备因为我们需要用到一些较新的相机API。3.2 关键依赖给项目添加“动力组件”我们需要在项目的app模块下的build.gradle文件里声明需要使用的库。打开这个文件在dependencies部分添加如下代码dependencies { // MediaPipe核心库与手势识别模块 implementation com.google.mediapipe:mediapipe-android:0.10.0 implementation com.google.mediapipe:mediapipe-hands:0.10.0 // CameraX库用于简化摄像头操作 def camerax_version 1.3.0 implementation androidx.camera:camera-core:${camerax_version} implementation androidx.camera:camera-camera2:${camerax_version} implementation androidx.camera:camera-lifecycle:${camerax_version} implementation androidx.camera:camera-view:${camerax_version} // 可选用于权限请求 implementation com.guolindev.permissionx:permissionx:1.7.1 }添加完成后点击Android Studio右上角的“Sync Now”同步项目。这些库会自动从网络仓库下载。3.3 配置权限与模型文件手势识别需要调用摄像头所以必须在AndroidManifest.xml文件中声明权限manifest ... uses-permission android:nameandroid.permission.CAMERA / application ... ... /application /manifest接下来是最关键的一步放入模型文件。从我们提供的镜像或资源包中找到名为hand_tracking_mobile.binarypb的文件。在Android项目的app/src/main/目录下如果还没有assets文件夹就新建一个。然后将这个模型文件复制进去。这个.binarypb文件是MediaPipe定义好的计算流程图它告诉程序如何处理图像数据、调用哪个模型、以及如何输出结果。没有它我们的应用就无法工作。4. 核心代码实现三步构建识别系统现在我们进入核心的编码环节。整个过程可以分解为三个清晰的步骤启动摄像头、运行识别模型、绘制可视化结果。4.1 第一步用CameraX打开摄像头预览我们使用Google推荐的CameraX库来操作摄像头它比旧的Camera API简单可靠得多。首先在布局文件activity_main.xml中加入一个用于显示相机画面的PreviewView?xml version1.0 encodingutf-8? androidx.constraintlayout.widget.ConstraintLayout xmlns:androidhttp://schemas.android.com/apk/res/android xmlns:apphttp://schemas.android.com/apk/res-auto android:layout_widthmatch_parent android:layout_heightmatch_parent androidx.camera.view.PreviewView android:idid/preview_view android:layout_widthmatch_parent android:layout_heightmatch_parent / !-- 我们之后会在这里叠加一个自定义View来画骨骼 -- com.example.handtracking.OverlayView android:idid/overlay_view android:layout_widthmatch_parent android:layout_heightmatch_parent android:backgroundandroid:color/transparent/ /androidx.constraintlayout.widget.ConstraintLayout然后在MainActivity.kt如果你用Java就是MainActivity.java中编写启动摄像头的逻辑。这里我们用Kotlin示例更简洁class MainActivity : AppCompatActivity() { private lateinit var cameraProviderFuture: ListenableFutureProcessCameraProvider override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) // 请求摄像头权限这里使用了一个简化库你也可以用ActivityResult API PermissionX.init(this) .permissions(Manifest.permission.CAMERA) .request { allGranted, _, _ - if (allGranted) { startCamera() } else { Toast.makeText(this, 需要摄像头权限才能使用手势识别, Toast.LENGTH_LONG).show() } } } private fun startCamera() { val previewView: PreviewView findViewById(R.id.preview_view) cameraProviderFuture ProcessCameraProvider.getInstance(this) cameraProviderFuture.addListener({ val cameraProvider cameraProviderFuture.get() // 构建预览用例 val preview Preview.Builder().build().also { it.setSurfaceProvider(previewView.surfaceProvider) } // 选择后置摄像头 val cameraSelector CameraSelector.DEFAULT_BACK_CAMERA try { // 解绑所有用例再重新绑定 cameraProvider.unbindAll() // 将预览绑定到相机生命周期 cameraProvider.bindToLifecycle(this, cameraSelector, preview) } catch(exc: Exception) { Log.e(Camera, Use case binding failed, exc) } }, ContextCompat.getMainExecutor(this)) } }运行到这一步你的应用应该已经能显示摄像头画面了。4.2 第二步初始化MediaPipe并处理视频流这一步是桥梁负责把摄像头每一帧画面送给MediaPipe模型去分析。我们需要创建一个Helper类HandTrackingHelper.ktclass HandTrackingHelper(context: Context) { private var graph: Graph? null private var processor: FrameProcessor? null // 初始化MediaPipe图 fun initialize() { try { // 1. 初始化Asset管理器用于读取我们放在assets里的模型文件 AndroidAssetUtil.initializeNativeAssetManager(context) // 2. 创建并加载计算图 graph Graph() graph?.loadBinaryGraph(hand_tracking_mobile.binarypb) // 3. 创建帧处理器并指定输出回调 processor FrameProcessor(graph, input_video, hand_landmarks) processor?.addPacketCallback { packet - // 当有识别结果时会回调到这里 val landmarks PacketGetter.getProto(packet, NormalizedLandmarkList.parser()) // 将结果通过LiveData或接口发送给UI层 resultLiveData.postValue(landmarks) } // 4. 启动计算图 graph?.startRunningGraph() } catch (e: Exception) { Log.e(HandTracking, 初始化失败, e) } } // 将摄像头帧送入处理管道 fun sendFrame(frame: Bitmap) { processor?.processFrame(frame) } fun close() { processor?.close() graph?.close() } }在MainActivity中我们修改startCamera函数在预览的同时将每一帧图像送给HandTrackingHelper处理。这需要用到CameraX的ImageAnalysis用例。4.3 第三步绘制炫酷的彩虹骨骼识别结果是一组坐标我们要在屏幕上把它们画出来。我们创建一个自定义ViewOverlayView.kt专门负责绘制class OverlayView(context: Context, attrs: AttributeSet?) : View(context, attrs) { private var landmarkList: NormalizedLandmarkList? null private val fingerColors intArrayOf( Color.YELLOW, // 拇指 Color.MAGENTA, // 食指 Color.CYAN, // 中指 Color.GREEN, // 无名指 Color.RED // 小指 ) private val fingerConnections arrayOf( intArrayOf(0, 1, 2, 3, 4), // 拇指 intArrayOf(0, 5, 6, 7, 8), // 食指 intArrayOf(0, 9, 10, 11, 12), // 中指 intArrayOf(0, 13, 14, 15, 16), // 无名指 intArrayOf(0, 17, 18, 19, 20) // 小指 ) // 这个方法由Activity调用更新要绘制的关节点数据 fun setLandmarks(landmarks: NormalizedLandmarkList?) { this.landmarkList landmarks invalidate() // 触发重绘 } override fun onDraw(canvas: Canvas) { super.onDraw(canvas) landmarkList?.let { landmarks - val landmarkList landmarks.landmarkList // 1. 绘制彩色骨骼线 for (fingerIdx in fingerConnections.indices) { val connections fingerConnections[fingerIdx] val path Path() for (i in connections.indices) { val lm landmarkList[connections[i]] val x lm.x * width val y lm.y * height if (i 0) { path.moveTo(x, y) } else { path.lineTo(x, y) } } val paint Paint().apply { color fingerColors[fingerIdx] strokeWidth 8f style Paint.Style.STROKE } canvas.drawPath(path, paint) } // 2. 绘制白色关节点 val jointPaint Paint().apply { color Color.WHITE strokeWidth 12f style Paint.Style.FILL } for (lm in landmarkList) { val x lm.x * width val y lm.y * height canvas.drawCircle(x, y, 6f, jointPaint) } } } }最后在MainActivity中将HandTrackingHelper识别到的结果实时设置给OverlayView这样彩虹骨骼就能随着你的手势动态绘制在摄像头预览画面之上了。5. 运行测试与效果优化5.1 编译运行见证奇迹完成所有代码后连接你的手机或启动模拟器点击Android Studio的“运行”按钮。首次启动时应用会请求摄像头权限。授权后你应该能看到后置摄像头的画面。对着摄像头做出“点赞”、“比耶”或张开手掌等手势稍等片刻屏幕上就应该出现随着你手指移动而变化的彩色线条和白色点点了恭喜你你已经成功在Android上运行了AI手势识别5.2 常见问题与调优技巧如果效果不理想可以尝试以下调整识别不到或不准确保手部在画面中且光线充足。在HandTrackingHelper初始化图时可以尝试设置更高的检测置信度需要修改.binarypb图的配置进阶操作。检查模型文件hand_tracking_mobile.binarypb是否确实放入了assets文件夹。画面卡顿降低ImageAnalysis用例的图像分辨率。在配置时使用ImageAnalysis.Builder().setTargetResolution(Size(640, 480))。确保绘制操作onDraw不要过于复杂我们的绘制逻辑已经很轻量。想进一步提升体验平滑处理手势坐标可能会轻微抖动。可以在OverlayView中保存最近几帧的坐标然后取平均值来绘制这样骨骼线会更稳定。手势识别在得到21个点后你可以计算手指间的角度、距离来判断具体手势。例如食指和中指的指尖第8和第12点的Y坐标远高于其他指尖且彼此靠近可能就是“比耶”。性能模式对于非常老的设备可以考虑降低处理频率比如每两帧处理一帧。6. 总结6.1 回顾与收获通过这篇教程我们完成了一个完整的Android端AI手势识别应用。我们从零开始搭建了开发环境集成了强大的MediaPipe Hands模型并实现了独特的“彩虹骨骼”可视化。整个过程涵盖了环境配置添加依赖、放置模型文件。摄像头集成使用CameraX获取实时视频流。AI模型调用初始化MediaPipe图并处理每一帧图像。结果可视化在自定义View上绘制彩色手部骨骼。这个项目不仅是一个教程更是一个强大的起点。基于这21个关键点你可以发挥创意开发出更多有趣的应用体感游戏用手势控制角色跳跃、攻击。虚拟乐器在空中弹奏钢琴或吉他。智能演示用手势翻动PPT或控制视频播放。手语翻译辅助识别简单的手语动作。6.2 下一步探索现在你已经掌握了核心的集成方法。可以尝试改为使用前置摄像头实现自拍模式下的手势交互。尝试集成镜像中提供的WebUI功能在浏览器中上传图片测试识别效果辅助调试。探索识别双手并处理双手之间的交互逻辑。技术的魅力在于将想象落地。希望这篇教程能帮助你在Android这片广阔的土地上创造出令人惊叹的手势交互体验。获取更多AI镜像想探索更多AI镜像和应用场景访问 CSDN星图镜像广场提供丰富的预置镜像覆盖大模型推理、图像生成、视频生成、模型微调等多个领域支持一键部署。
返回列表