65.9K
CodeProject 正在变化。 阅读更多。
Home

DashCam Android应用程序

emptyStarIconemptyStarIconemptyStarIconemptyStarIconemptyStarIcon

0/5 (0投票)

2019年6月4日

CPOL
viewsIcon

2985

该项目的主要目标是开发一个Android应用程序,该应用程序使用内置摄像头捕捉道路上的物体,并使用机器学习模型来获取相应物体的预测和位置。

您是否使用高通开发者网络上提供的某些硬件和/或软件创建了一个项目? 您想让它在高通开发者网络上展示吗? 告诉我们您的项目

该项目旨在利用Qualcomm®神经处理SDK,该SDK允许您调整在Qualcomm®Snapdragon™移动平台上运行的AI应用程序的性能。 Qualcomm神经处理SDK用于将来自Caffe、Caffe2、ONNX和TensorFlow的训练模型转换为Snapdragon支持的格式(.dlc格式),使开发人员能够使用优化的设备端推理来启用其AI应用程序。

目标

该项目的主要目标是开发一个Android应用程序,该应用程序使用内置摄像头捕捉道路上的物体,并使用机器学习模型来获取相应物体的预测和位置。

所需材料/零件清单/工具

源代码/源代码示例/应用程序可执行文件

构建/组装说明

使用的零件

以下是此项目中使用的项目。

Project components for Dashboard Android Application project

  1. 带QC Dash Cam应用程序的移动显示屏
  2. Snapdragon 835移动硬件开发套件
  3. 外部摄像头设置

部署项目

  1. 从GitHub存储库下载代码。
  2. 编译代码,并从Android Studio运行应用程序,以生成应用程序(apk)文件。

它是如何工作的?

QC_DashCam Android应用程序打开一个相机预览,收集所有帧并将其转换为位图。 网络是通过Neural Network builder构建的,通过传递caffe_mobilenet.dlc作为输入。 然后将位图作为推理提供给模型,该模型返回对象的预测和相应对象的位置。

相机预览的先决条件。

在以下文件中授予获取相机预览帧的权限

        AIML-DashCam-App/app/src/main/AndroidManifest.xml
      
        <uses-permission android:name="android.permission.CAMERA" />

为了使用camera2 API,添加以下功能

        <uses-feature android:name="android.hardware.camera2" />

加载模型

用于神经网络连接和加载模型的代码片段

        final SNPE.NeuralNetworkBuilder builder = new
        SNPE.NeuralNetworkBuilder(mApplicationContext)
        // Allows selecting a runtime order for the network.
        // In the example below use DSP and fall back, in order, to GPU then CPU
        // depending on whether any of the runtimes are available.
        .setRuntimeOrder(DSP, GPU, CPU)
        // Loads a model from DLC file
        .setModel(new File("<model-path>"))
        // Build the network
        network = builder.build();

捕获预览帧

Texture view用于渲染相机预览。 TextureView.SurfaceTextureListener是一个接口,可用于在与此texture view关联的表面纹理可用时发出通知。

        @Override
          public void onSurfaceTextureAvailable(SurfaceTexture surfaceTexture, int i, int i1) {
              Logger.d(TAG, "OnSurfaceTextureAvailable");
                try {
      //id[0] indicates rear camera
                  mCameraManager.openCamera(ids[0], mCameraCallback, mBackgroundHandler);
              } catch (CameraAccessException e) {
                  e.printStackTrace();
              }
          }

相机回调

相机回调,CameraDevice.StateCallback用于接收有关相机设备状态的更新。 在下面的重写方法中,创建surface texture以捕获预览并获取帧。

        @Override
        public void onOpened(@NonNull CameraDevice cameraDevice) {
            Logger.d(TAG, "onOpened()");
            mCameraDevice = cameraDevice;
              mSurfaceTexture = mTextureView.getSurfaceTexture();
        Surface mSurface = new Surface(mSurfaceTexture);
        try {      
            mCameraDevice.createCaptureSession(Arrays.asList(mSurface), new  CameraCapture(),null);
        } catch (CameraAccessException e) {
            e.printStackTrace();
        }
      
        try {
            builder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
            builder.addTarget(mSurface);
        } catch (CameraAccessException e) {
            e.printStackTrace();
        }
        }

从Texture view获取位图

可以从TextureViewonCaptureCompleted回调中使用TotalCaptureResult获取固定高度和宽度的位图。 可以压缩该位图并将其作为输入发送给模型。

        @Override
        public void onCaptureCompleted(@NonNull CameraCaptureSession session, @NonNull CaptureRequest request, @NonNull TotalCaptureResult result) {
            super.onCaptureCompleted(session, request, result);          
            if (mNetworkLoaded) {
                Bitmap mBitmap = mTextureView.getBitmap(Constants.BITMAP_WIDTH, Constants.BITMAP_HEIGHT);

对象推理

位图图像转换为RGBA字节数组,大小为300 * 300 * 3。 基本图像处理取决于模型所需的输入形状的类型,然后需要将该处理后的图像转换为张量。 预测API需要类型为Float的张量格式,该格式返回对象预测和Map<String, FloatTensor>对象中的位置。

        private Map<String, FloatTensor> inferenceOnBitmap(Bitmap inputBitmap) {
            final Map<String, FloatTensor> outputs;
            try {
              if (mNeuralNetwork == null || mInputTensorReused == null || inputBitmap.getWidth() != getInputTensorWidth() || inputBitmap.getHeight() != getInputTensorHeight()) {
                    return null;
                }
                // [0.3ms] Bitmap to RGBA byte array (size: 300*300*3 (RGBA..))
                mBitmapToFloatHelper.bitmapToBuffer(inputBitmap);
                // [2ms] Pre-processing: Bitmap (300,300,4 ints) -> Float Input Tensor (300,300,3 floats)
                mTimeStat.startInterval();
                final float[] inputFloatsHW3 = mBitmapToFloatHelper.bufferToNormalFloatsBGR();
                if (mBitmapToFloatHelper.isFloatBufferBlack())
                    return null;
                mInputTensorReused.write(inputFloatsHW3, 0, inputFloatsHW3.length, 0, 0);
                mTimeStat.stopInterval("i_tensor", 20, false);
                // [31ms on GPU16, 50ms on GPU] execute the inference
                mTimeStat.startInterval();
                outputs = mNeuralNetwork.execute(mInputTensorsMap);
                mTimeStat.stopInterval("nn_exec ", 20, false);
            } catch (Exception e) {
                e.printStackTrace();
                      return null;
            }
            return outputs;
        }

对象定位

模型返回相应的Float张量,从中可以推断出对象的形状及其名称。 Canvas用于在预测对象上绘制一个矩形。

        private void computeFinalGeometry(Box box, Canvas canvas) {
                final int viewWidth = getWidth();
                final int viewHeight = getHeight();
                float y = viewHeight * box.left;
                float x = viewWidth * box.top;
                float y1 = viewHeight * box.right;
                float x1 = viewWidth * box.bottom;
                // draw the text
                String textLabel = (box.type_name != null && !box.type_name.isEmpty()) ? box.type_name : String.valueOf(box.type_id + 2);
                canvas.drawText(textLabel, x + 10, y + 30, mTextPaint);
                // draw the box
              mOutlinePaint.setColor(colorForIndex(box.type_id));
                canvas.drawRect(x, y, x1, y1, mOutlinePaint);
            }

带有模型预测的应用程序的屏幕截图示例

Sample screen shot of the application with model prediction

使用说明

如何安装Android应用程序

  • 您将需要一个Android手机,版本为7.0及以上。
  • 在Windows / Linux系统中安装ADB。
  • 按照以下说明在您的计算机上安装adb工具。 https://developer.android.com.cn/studio/command-line/adb.html
  • 使用ADB工具和以下命令安装应用程序:adb install qc_dashCam.apk
  • 在手机中运行该应用程序。
© . All rights reserved.