创建的空 OpenCV 安卓应用程序以支持摄像头

ops/2024/12/27 8:07:53/

在本节中,我们将扩展上一节中创建的空 OpenCV 应用程序以支持摄像头。我们将获取摄像头帧并将其显示在屏幕上。

告诉系统我们需要相机权限。将以下代码添加到文件MyApplication/app/src/main/AndroidManifest.xml

    <uses-permission android:name="android.permission.CAMERA"/><uses-feature android:name="android.hardware.camera" android:required="false"/><uses-feature android:name="android.hardware.camera.autofocus" android:required="false"/><uses-feature android:name="android.hardware.camera.front" android:required="false"/><uses-feature android:name="android.hardware.camera.front.autofocus" android:required="false"/>

  1. 转到activity_main.xml布局并删除带有文本“Hello World!”的 TextView

TextView这也可以在代码或拆分模式下通过从 XML 文件中删除块来完成。

  1. 将相机视图添加到布局中:

    在布局描述中添加方案:

xmlns:opencv = "http://schemas.android.com/apk/res-auto"

   TextView用小部件替换org.opencv.android.JavaCameraView

    <org.opencv.android.JavaCameraViewandroid:layout_width="fill_parent"android:layout_height="fill_parent"android:visibility="gone"android:id="@+id/tutorial1_activity_java_surface_view"opencv:show_fps="true"opencv:camera_id="any" />
  1. 如果你收到布局警告,请用for和properties替换fill_parentmatch_parentandroid:layout_widthandroid:layout_height

您将获得如下代码:

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"xmlns:opencv="http://schemas.android.com/apk/res-auto"android:layout_width="match_parent"android:layout_height="match_parent" ><!-- [camera_view] --><org.opencv.android.JavaCameraViewandroid:layout_width="fill_parent"android:layout_height="fill_parent"android:visibility="gone"android:id="@+id/tutorial1_activity_java_surface_view"opencv:show_fps="true"opencv:camera_id="any" /><!-- [camera_view] --></FrameLayout>
  1. 从 继承主类。CameraActivity 实现相机权限请求和org.opencv.android.CameraActivityCV 应用程序所需的一些其他实用程序。我们想要重写的方法包括onCreateonDestroy、和onPauseonResumegetCameraViewList
  2. 实现接口org.opencv.android.CameraBridgeViewBase.CvCameraViewListener2 onCameraFrame方法应该返回Mat带有内容的对象以供渲染。示例仅返回相机帧以供预览:return inputFrame.rgba();
  3. 分配org.opencv.android.CameraBridgeViewBase对象:
    • 它应该在应用程序启动时创建(onCreate方法),并且该类应该设置为监听器
    • 在暂停/恢复(onPauseonResume方法)时应该禁用/启用它
    • 应在应用程序完成时禁用(onDestroy方法)
    • 应归还getCameraViewList
  4. 您可以选择禁止手机调暗屏幕或锁定:

 getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);

最终的源码:

package org.opencv.samples.tutorial1;import org.opencv.android.CameraActivity;
import org.opencv.android.CameraBridgeViewBase.CvCameraViewFrame;
import org.opencv.android.OpenCVLoader;
import org.opencv.core.Mat;
import org.opencv.android.CameraBridgeViewBase;
import org.opencv.android.CameraBridgeViewBase.CvCameraViewListener2;import android.os.Bundle;
import android.util.Log;
import android.view.SurfaceView;
import android.view.WindowManager;
import android.widget.Toast;import java.util.Collections;
import java.util.List;public class Tutorial1Activity extends CameraActivity implements CvCameraViewListener2 {private static final String TAG = "OCVSample::Activity";private CameraBridgeViewBase mOpenCvCameraView;public Tutorial1Activity() {Log.i(TAG, "Instantiated new " + this.getClass());}@Overridepublic void onCreate(Bundle savedInstanceState) {Log.i(TAG, "called onCreate");super.onCreate(savedInstanceState);if (OpenCVLoader.initLocal()) {Log.i(TAG, "OpenCV loaded successfully");} else {Log.e(TAG, "OpenCV initialization failed!");(Toast.makeText(this, "OpenCV initialization failed!", Toast.LENGTH_LONG)).show();return;}getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);setContentView(R.layout.tutorial1_surface_view);mOpenCvCameraView = (CameraBridgeViewBase) findViewById(R.id.tutorial1_activity_java_surface_view);mOpenCvCameraView.setVisibility(SurfaceView.VISIBLE);mOpenCvCameraView.setCvCameraViewListener(this);}@Overridepublic void onPause(){super.onPause();if (mOpenCvCameraView != null)mOpenCvCameraView.disableView();}@Overridepublic void onResume(){super.onResume();if (mOpenCvCameraView != null)mOpenCvCameraView.enableView();}@Overrideprotected List<? extends CameraBridgeViewBase> getCameraViewList() {return Collections.singletonList(mOpenCvCameraView);}@Overridepublic void onDestroy() {super.onDestroy();if (mOpenCvCameraView != null)mOpenCvCameraView.disableView();}@Overridepublic void onCameraViewStarted(int width, int height) {}@Overridepublic void onCameraViewStopped() {}@Overridepublic Mat onCameraFrame(CvCameraViewFrame inputFrame) {return inputFrame.rgba();}
}

就是这样!现在您可以在设备上运行代码来检查它。

记录一下最重要的步骤

每个带有 UI 的 Android 应用程序都必须实现 Activity 和 View。首先,我们创建空白活动和默认视图布局。最简单的以 OpenCV 为中心的应用程序必须执行 OpenCV 初始化,创建一个视图来显示来自摄像头的预览,并实现CvCameraViewListener2接口以从摄像头获取帧并对其进行处理。

首先,我们使用 XML 布局创建应用程序视图。我们的布局仅包含一个类的全屏组件org.opencv.android.JavaCameraView。此 OpenCV 类继承自CameraBridgeViewBase扩展类SurfaceView,并在底层使用标准 Android 相机 API。

CvCameraViewListener2接口允许您在从相机抓取帧之后和在屏幕上渲染之前添加一些处理步骤。最重要的方法是onCameraFrame。这是一个回调函数,在从相机检索帧时调用。它期望该onCameraFrame函数返回将在屏幕上绘制的 RGBA 帧。

回调将相机中的帧作为类对象传递给我们的类CvCameraViewFrame。此对象具有rgba()gray()方法,可让用户获取彩色或单通道灰度帧作为Mat类对象。

笔记

不要保存或使用回调CvCameraViewFrame之外的对象onCameraFrame。此对象没有自己的状态,并且其在回调之外的行为不可预测!


http://www.ppmy.cn/ops/139320.html

相关文章

40分钟学 Go 语言高并发:服务性能调优实战

服务性能调优实战 一、性能优化实战概述 优化阶段主要内容关键指标重要程度瓶颈定位收集性能指标&#xff0c;确定瓶颈位置CPU、内存、延迟、吞吐量⭐⭐⭐⭐⭐代码优化优化算法、并发、内存使用代码执行时间、内存分配⭐⭐⭐⭐⭐系统调优调整系统参数、资源配置系统资源利用率…

Leecode经典题4--查找数组中的多数元素+Boyer-Moore 投票算法

题目描述&#xff1a; 给定一个大小为 n 的数组 nums &#xff0c;返回其中的多数元素。多数元素是指在数组中出现次数 大于 ⌊ n/2 ⌋ 的元素。 你可以假设数组是非空的&#xff0c;并且给定的数组总是存在多数元素。 输入输出示例 输入&#xff1a;nums [2,2,1,1,1,2,2] 输出…

关于linux 下的中断

1. /proc/irq/<irq_number>/ 下属性详解 在 Linux 系统中&#xff0c;每个中断号&#xff08;IRQ&#xff09;都有一个对应的目录 /proc/irq/<irq_number>/&#xff0c;包含与该中断相关的属性文件。这些文件用于查看和配置中断的具体行为。 以下是 /proc/irq/&l…

Qt Designer Ui设计 功能增加

效果展示 输入密码&#xff0c;密码错误&#xff0c;弹出提示 密码正确&#xff0c;弹出提示并且关闭原窗口 代码&#xff08;只提供重要关键主代码&#xff09;lxh_log.py代码&#xff1a; import sysfrom PySide6.QtWidgets import QApplication, QWidget, QPushButtonfrom …

安装更新upgrade导致ubuntu崩溃

安装更新导致ubuntu崩溃 前言uuid编不过&#xff0c;导致的崩溃 记录一些ubuntu崩溃的过程。 目前只有一个&#xff0c;以后遇到都放在这里&#xff0c;以提醒自己。 前言 如果从10000年看现在的linux&#xff0c;不是说不完美&#xff0c;而是糟透了。 linux的版本号&#xf…

【人工智能-科普】图神经网络(GNN):与传统神经网络的区别与优势

文章目录 图神经网络(GNN):与传统神经网络的区别与优势什么是图神经网络?图的基本概念GNN的工作原理GNN与传统神经网络的不同1. 数据结构的不同2. 信息传递方式的不同3. 模型的可扩展性4. 局部与全局信息的结合GNN的应用领域总结图神经网络(GNN):与传统神经网络的区别与…

向量数据库、关系型数据库和NoSQL:从定义到大模型应用的深度解析20241204

&#x1f9e0; 向量数据库、关系型数据库和NoSQL&#xff1a;从定义到大模型应用的深度解析 ✨ 引言 随着数据驱动型技术的普及&#xff0c;数据库系统的选择和优化成为决定技术项目成败的关键。传统关系型数据库&#xff08;RDBMS&#xff09;、非关系型数据库&#xff08;No…

接口性能优化宝典:解决性能瓶颈的策略与实践

目录 一、直面索引 &#xff08;一&#xff09;索引优化的常见场景 &#xff08;二&#xff09;如何检查索引的使用情况 &#xff08;三&#xff09;如何避免索引失效 &#xff08;四&#xff09;强制选择索引 二、提升 SQL 执行效率 &#xff08;一&#xff09;避免不必…