简单的Android Camera2与BoofCV
目录
介绍
自动聚焦算法
源代码亮点
第一步:在Android Studio中创建一个新项目
第二步:依赖性
第三步:Android权限
第四步:MainActivity:OnCreate()
第五步:摄像头控制
第六步:图像处理
第七步:绘图
第八步:响应用户触摸
使用其他计算机视觉库
其他例子
结论
本文将演示BoofCV如何大大简化在Android上使用相机的工作。
介绍
本文将演示BoofCV的Android库如何极大地简化了Camera2 API的使用,处理相机图像以及可视化结果。Android开发和 Camera2API都非常复杂,例如 Google的Camera2Basic 示例所示。这个例子涵盖了你需要做的事情的大约1/2。
使用BoofCV,您只需要告诉它您想要的分辨率,实现图像处理功能,以及(可选)编写可视化功能。BoofCV将选择相机,打开相机,创建线程池,同步数据结构,处理Android生命周期(正确打开/关闭相机,停止线程),转换YUV420图像,正确对齐输入像素到屏幕像素,以及根据要求更改相机设置。
我们将在本文中讨论的是编写自己的自动聚焦例程。虽然不像使用最新的深度学习那样性感(例如,对所有物体进行分类,老化你的脸),但这篇文章是关于实用和制作有用的东西。不管你的计算机视觉算法有多么令人惊讶,如果应用程序总是崩溃!一旦你理解了这段代码是如何工作的,你就可以将它与其他算法结合起来,以便将相机专注于狗而不是人。
自动聚焦算法
聚焦和失焦图像的示例。请注意焦点图像中边缘强度如何变大?
内置自动对焦的行为因制造商和计算机视觉应用程序而异,我的经验是他们倾向于专注于除了你想要的任何东西。为了解决这个问题,我们将通过手动控制相机的焦点并使用最大图像“最清晰”找到焦点值来进行自己的自动对焦。图像的清晰度由其梯度强度决定。图像的梯度是其x和y空间导数。梯度的强度可以以不同的方式定义。在这里,我们使用欧几里德范数,即sqrt(dx**2 + dy**2)。
自动聚焦算法是有限状态机,如上所述。它详尽地遍历所有焦点值以选择具有最大边缘强度的焦点值。一旦找到最大边缘强度,它就会固定焦点。您可以通过轻击屏幕重新开始该过程。
源代码亮点
此时,您应该查看Github上的源代码并稍微探索一下代码。我们将逐步完成在源代码本身中设置您自己的项目和重要行的关键步骤。假设您已经对Android开发有所了解,并且为了简洁起见,跳过了一些步骤。
- Github源代码
第一步:在Android Studio中创建一个新项目
这篇文章被标记为中间件,所以我假设你可以在没有图片和视频的情况下做到这一点。最小的SDK必须是22.这是修复了Camera 2 API中一个令人讨厌的bug的第一个版本。
第二步:依赖性
将以下内容添加到app / build.gradle中的依赖项字段。
dependencies {['boofcv-android', 'boofcv-core'].each {String a ->implementation group: 'org.boofcv', name: a, version: '0.32-SNAPSHOT'}
}
您还需要排除一些传递依赖项,因为Android包含自己的版本,并且会发生冲突。
configurations {all*.exclude group: "xmlpull", module: "xmlpull"all*.exclude group: "org.apache.commons", module: "commons-compress"all*.exclude group: "com.thoughtworks.xstream", module: "commons-compress"
}
然后让Android Studio同步您的Gradle文件。
第三步:Android权限
在app / src / main / AndroidManifest.xml中,您需要授予自己对相机的访问权限:
<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera2.full" />
第四步:MainActivity:OnCreate()
您现在应该打开 MainActivity.java 文件。注意这个类如何扩展 VisualzieCamera2Activity。如果您希望在屏幕上呈现某些内容,那么您应该扩展该活动。否则, 如果您只需要相机框架,则可以扩展 SimpleCamera2Activity。
看看 onCreate() 功能。这个功能正在发生很多事情; 获取相机权限,指定输出图像的类型,所需的分辨率以及关闭双缓冲。让我们一行一行进行。
TextureView显示原始相机预览。FrameLayout用于绘制视觉效果。我们还添加了一个触摸侦听器,以便用户可以重新启动焦点算法。稍后会详细介绍。
TextureView view = findViewById(R.id.camera_view);
FrameLayout surface = findViewById(R.id.camera_frame);
surface.setOnClickListener(this);
在这里,我们请求用户访问摄像机。这已经在整个web中广泛地被覆盖,因此请查看源代码,了解如何完成此操作。
requestCameraPermission();
BoofCV需要知道我们想要的图像格式。在这里,我们告诉它给我们一个灰度8位图像。
setImageType(ImageType.single(GrayU8.class));
相机通常支持多种分辨率。BoofCV将为我们选择一个分辨率,但我们应该告诉它我们的要求。下面这行是告诉BoofCV找到一个大约有这么多像素的图像分辨率。通过覆盖selectResolution()函数可以实现更复杂的逻辑。
targetResolution = 640*480;
BoofCV还将自动渲染捕获帧。在这种情况下,我们不想这样做,只显示原始相机Feed。所以让我们关闭这种行为。
bitmapMode = BitmapMode.NONE;
最后,我们告诉它启动相机并使用以下surface和view进行可视化。
startCamera(surface,view);
第五步:摄像头控制
默认情况下,摄像机配置为处于全自动模式。我们不希望这样,所以我们用自己的逻辑覆盖默认configureCamera()函数。BoofCV定义configureCamera()并且它不是内置的Camera2API函数。直接使用Camera2API完成这项工作需要做很多工作
下面的代码注释描述了每个代码块正在做什么。实质上,它是上面实现有限状态机的地方。
@Override
protected void configureCamera(CameraDevice device, CameraCharacteristics characteristics, CaptureRequest.Builder captureRequestBuilder) {// set focus control to manualcaptureRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_OFF);// get a list of acceptable valuesFloat minFocus = characteristics.get(CameraCharacteristics.LENS_INFO_MINIMUM_FOCUS_DISTANCE);switch( state ) {case INITIALIZE:{if( minFocus == null ) {Toast.makeText(this,"manual focus not supported", Toast.LENGTH_SHORT).show();state = State.UNSUPPORTED;} else {focusBestIndex = 0;focusBestValue = 0;focusIndex = 0;focusTime = System.currentTimeMillis()+FOCUS_PERIOD;state = State.FOCUSING;captureRequestBuilder.set(CaptureRequest.LENS_FOCUS_DISTANCE, 0f);}}break;case PENDING:{focusIndex++;if( focusIndex < FOCUS_LEVELS ) {focusTime = System.currentTimeMillis()+FOCUS_PERIOD;captureRequestBuilder.set(CaptureRequest.LENS_FOCUS_DISTANCE, minFocus*focusIndex/(FOCUS_LEVELS-1));state = State.FOCUSING;} else {captureRequestBuilder.set(CaptureRequest.LENS_FOCUS_DISTANCE, minFocus*focusBestIndex/(FOCUS_LEVELS-1));state = State.FIXED;}}break;}
}
第六步:图像处理
BoofCV提供了自己的图像处理功能,可以自动将流式 YUV420_888图像转换为您理解的图像。它还为您启动了一个处理图像的线程。这意味着您可以随意使用而不会崩溃!如果您的图像处理无法跟上相机的进给速度,则会丢弃相框。
@Override
protected void processImage(ImageBase image) {// We specified earlier to give us an 8-bit gray scale imageGrayU8 gray = (GrayU8)image;// Ensure that work space images are the appropriate sizederivX.reshape(gray.width,gray.height);derivY.reshape(gray.width,gray.height);intensity.reshape(gray.width,gray.height);// Compute the gradient and Euclidean edge intensityGImageDerivativeOps.gradient(DerivativeType.SOBEL,gray,derivX,derivY, BorderType.EXTENDED);GGradientToEdgeFeatures.intensityE(derivX, derivY, intensity);// Find the average edge valueedgeValue = ImageStatistics.mean(intensity);
}
第七步:绘图
通常,您需要为SurfaceView创建一个回调,但这也是由您处理的。您仍然需要覆盖下面的onDrawFrame函数。下面的代码是相当标准的Android绘图,这就是它没有突出显示的原因。如果您想了解如何使用BoofCV渲染正在处理的实际图像(不是实时视频输入)并将视觉效果与精确像素对齐,请参阅QR Code示例。
@Override
protected void onDrawFrame(SurfaceView view, Canvas canvas) {super.onDrawFrame(view, canvas);....
}
第八步:响应用户触摸
在onCreate(),我们添加了一个触摸侦听器。这允许用户重新启动自动对焦。下面的代码显示了如何完成此操作。通过等待自动对焦处于FIXED状态,我们无需担心相机是否繁忙,从而简化了代码。
@Override
public void onClick(View v) {// If the user touches the screen and it has already finished focusing, start againif( state == State.FIXED ) {state = State.INITIALIZE;changeCameraConfiguration();}
}
使用其他计算机视觉库
在这个例子中,我们使用BoofCV进行图像处理。没有理由不能使用OpenCV等其他库或您最喜欢的深度学习库(例如Torch)。您需要做的是将BoofCV图像转换为其他库能够理解的图像。这比首先获得图像要容易得多!你可以完全在BoofCV图像中访问原始字节数组和图像特性(例如,width,height,stride)。
其他例子
BoofCV的存储库包括一些额外的极简主义Android示例。
- 计算和可视化图像渐变
- QR码检测与可视化
- 更改相机曝光
结论
我们能够在Android上创建一个功能齐全的计算机视觉应用程序,它可以处理库中的相机设置,同时处理图像并向用户显示信息。在没有广泛了解Android生命周期、Camera2 API如何工作、或者了解YUV420使您能够进入商业领域并且以最少的繁琐工作创建酷的计算机视觉应用程序的情况下,就完成了此任务!
原文地址:https://www.codeproject.com/Articles/1266363/Easy-Android-Camera2-with-BoofCV
简单的Android Camera2与BoofCV相关推荐
- android camera捕捉,通过android camera2 API捕捉4:3相机图片与16:9传感器阵列相机
我想从使用Camera2 API(Android 5.0版本中添加)的Android fron-facing相机以4:3的宽高比捕捉视频.它工作正常,除非相机有16:9传感器阵列(作为三星Galaxy ...
- android Camera2 API使用详解
原文:android Camera2 API使用详解 由于最近需要使用相机拍照等功能,鉴于老旧的相机API问题多多,而且新的设备都是基于安卓5.0以上的,于是本人决定研究一下安卓5.0新引入的Came ...
- Android Camera2 教程 · 第三章 · 预览
Android Camera2 教程 · 第三章 · 预览 DarylGo关注 Android Camera 上一章<Camera2 开启相机>我们学习了如何开启和关闭相机,接下来我们来学 ...
- 【Android Camera2】玩转图像数据 -- NV21图像旋转,镜像,转rgba代码分析,性能优化
[Android Camera2]玩转图像数据 业务场景介绍 NV21数据旋转 逐像素遍历法 NV21数据镜像 逐像素遍历法 中心翻转法 NV21转RGB/RGBA数据 逐像素遍历法 NV21组合操作 ...
- android camera2 API流程分析
Android camera2 API流程分析 Android5.0之后,新推出来了一个类,android.hardware.camera2,与原来的camera的类实现照相和拍视频的流程有所不同,原 ...
- 【Android Camera2】Camera2开源项目源码分析汇总
一.简介 本篇文章为综述汇总类文章,包含后续文章即将分析的使用Camera2实现的开源项目 相关文章: Android Camera系列文章目录索引汇总 Android Camera2 综述 二.开源 ...
- 十分钟实现 Android Camera2 相机拍照
1. 前言 因为工作中要使用Android Camera2 API,但因为Camera2比较复杂,网上资料也比较乱,有一定入门门槛,所以花了几天时间系统研究了下,并在CSDN上记录了下,希望能帮助到更 ...
- android camera2获取摄像头支持的分辨率
android camera2 获取摄像头支持的分辨率 41的for循环我注释了,代码是获取最匹配的分辨率. private Size getMatchingSize2(){Size selectSi ...
- android类中定义颜色,自定义实现简单的Android颜色选择器(附带源码)
在写Android App过程中需要一个简单的颜色选择器,Android自带的ColorPicker和网上的一些ColorPicker都太高端了,都实现了颜色渐变功能,我要的不需要那么复杂,只想提供几 ...
最新文章
- 计算机搞定44年几何难题,原来这2个人25年前猜对了
- SpringBoot实用小技巧之动态设置SpringBoot日志级别
- 防止我们账号被盗的5个方法
- access工具_工具篇之pycharm小技巧-httpclient
- 年底求职难?起薪28万的数据岗位,人才缺口达150万,不限专业学历……
- 【LeetCode-面试算法经典-Java实现】【002-Add Two Numbers (单链表表示的两个数相加)】...
- Linux下的ELF文件、链接、加载与库(含大量图文解析及例程)
- python编程代码执行漏洞_代码执行漏洞 - 安全先师的个人空间 - OSCHINA - 中文开源技术交流社区...
- rest-framework之版本控制
- MySQL服务器安装完之后如何调节性能
- linux软件安装方法
- python学习笔记26(python中__name__的使用)
- 【转】Redis学习---阿里云Redis多线程性能增强版详解
- 在lamp环境下搭建多种论坛(下)
- 简述java中类的构造方法_Java中类的构造方法
- 万能声卡驱动win10_ASIO驱动(多通道版)-无驱外置USB声卡电音驱动
- 人脸识别门禁系统java实现_基于 Java 实现的人脸识别功能(附源码)
- 奉劝那些想把编程学好的学弟学妹们!呕心沥血,袒露心声,掏心掏肺
- 公司知识库的搭建步骤
- Visio中的字体对应Word中字体字号
热门文章
- html 隐藏_HTML实战篇:纯css制作二级横向以及竖向菜单导航
- 计算机加经济学加自动化,MIT经济学家戳破机器人真相:除了能取代你,价值微乎其微...
- 淘宝京东卖家可以用到的小工具和素材资源网站
- python如何写二进制乘法_使用python写乘法口诀表
- 微服务升级优点_SpringCloud微服务架构升级总结
- ajax 验证成功 转跳,利用ajax实现登录:验证完用户信息后如何保存用户信息并实现跳转...
- Windows系统判断是否为64位系统(C++)
- 使用“/proc”系统调试多线程程序挂死的问题:
- CentOS 7 怎样安装或升级最新的内核?
- xlib/x11:创建一个监测键盘事件的窗口-4-箭头控制窗口移动