术语“ 增强现实(AR)通常是指实时将数字信息与用户环境集成。 AR可以使用户界面更加沉浸式和直观,将实时信息叠加到现实世界中,以使任务更加高效且容易发生错误。例如,在仓库管理中,AR可用于跟踪货架上物品的清单。在医院,AR可以帮助识别管和瓶子,在零售中,它可以显示产品信息。在本文中,我们将演示如何使用ARCore和Dynamsoft Barcode Reader标记多个条形码并避免误读。
先决条件
- 兼容Google Play Services for AR(Arcore)1.24或更高版本的Arcore兼容设备
- Android Studio 4.1或更高版本
2D条形码覆盖摄像机预览
通常,我们在相机预览上显示条形码结果如下:
覆盖层呈现在位于相机预览上方的2D画布上,同时显示条形码信息及其边界框。
在相机视图上绘制覆盖层可以被视为增强现实的基本形式。一个更先进的AR系统通常涉及了解环境的几何形状并以使它们在现实世界中似乎存在的方式放置数字对象,从而适当响应相机的视图或环境本身的变化。
在以下各节中,我们将结合Arcore和DynamSoft条形码读取器SDK,以增强条形码扫描体验。
关于Arcore和DynamSoft条形码读取器
- Arcore是Google建立增强现实(AR)体验的平台。通过利用三个关键技术 - 运动跟踪,环境理解和光估计 - 弧形使您的手机能够感知其环境,了解世界并以更全面和上下文的方式与信息互动。
- DynamSoft条形码读取器SDK是用于Windows,Linux,MacOS,Android,iOS和Web的商业条形码扫描库。它支持各种条形码类型,包括QR代码,Datamatrix,PDF417,代码128,代码39,EAN 13,UPC-A等。它还提供了30天的免费试用许可证。
将Google的Arcore与Dynamoft Android条形码SDK结合在一起
让我们从Arcore的示例项目开始:https://github.com/googlesamples/arcore-ml-sample。
Kotlin中编写的Android样品演示了如何利用Arcore和计算机视觉算法进行对象检测和跟踪。对我们来说,主要目标是对条形码的检测和跟踪。将DynamSoft条形码读取器集成到示例项目中涉及一系列步骤。
将DynamSoft条形码读取器SDK添加到项目
-
将DynamSoft存储库来源
https://download2.dynamsoft.com/maven/aar
添加到项目的build.gradle
文件:
allprojects { repositories { google() mavenLocal() mavenCentral() maven { url "https://download2.dynamsoft.com/maven/aar" } } }
-
在应用程序的
build.gradle
文件中配置依赖关系:
implementation 'com.dynamsoft:dynamsoftbarcodereader:9.6.20'
在Kotlin中检测条形码,QR码和datamatrix
-
在
MainActivity.kt
中,设置许可证密钥。您可以从here获得免费的试用许可证。
import com.dynamsoft.dbr.BarcodeReader BarcodeReader.initLicense("LICENSE-KEY") { isSuccessful, e -> runOnUiThread { if (!isSuccessful) { e.printStackTrace() Log.e(TAG, "Failed to verify the license: $e") } } }
-
在
AppRenderer.kt
中创建条形码读取器对象:
import com.dynamsoft.dbr.BarcodeReader import com.dynamsoft.dbr.BarcodeReaderException import com.dynamsoft.dbr.EnumImagePixelFormat import com.dynamsoft.dbr.Point var reader: BarcodeReader? = null fun bindView(view: MainActivityView) { try { reader = BarcodeReader() val settings = reader!!.runtimeSettings settings.expectedBarcodesCount = 999 reader!!.updateRuntimeSettings(settings) } catch (e: BarcodeReaderException) { e.printStackTrace() } }
-
找到以
launch(Dispatchers.IO)
开头的代码块。您可以利用获得的相机图像检测条形码:
if (reader != null) { var bytes = ByteArray(cameraImage.planes[0].buffer.remaining()) cameraImage.planes[0].buffer.get(bytes) var results = reader!!.decodeBuffer(bytes, cameraImage.width, cameraImage.height, cameraImage.planes[0].rowStride, EnumImagePixelFormat.IPF_NV21) objectResults = emptyList() if (results != null && results.isNotEmpty()) { val tmp: MutableList<DetectedObjectResult> = mutableListOf() for (result in results) { var points = result.localizationResult.resultPoints var confidence = 100 val (x1, y1) = points[0].x to points[0].y val (x2, y2) = points[1].x to points[1].y val (x3, y3) = points[2].x to points[2].y val (x4, y4) = points[3].x to points[3].y val centerX = (x1 + x2 + x3 + x4) / 4 val centerY = (y1 + y2 + y3 + y4) / 4 val content = result.barcodeText val label = "✓" val detectedObjectResult = DetectedObjectResult(confidence.toFloat(), label, centerX.toInt() to centerY.toInt(), content) tmp.add(detectedObjectResult) } objectResults = tmp } }
条形码检测结果包含四个点,这是条形码的四个角。我们可以计算条形码的中心点并将其用作标签的锚点。
val (x1, y1) = points[0].x to points[0].y
val (x2, y2) = points[1].x to points[1].y
val (x3, y3) = points[2].x to points[2].y
val (x4, y4) = points[3].x to points[3].y
val centerX = (x1 + x2 + x3 + x4) / 4
val centerY = (y1 + y2 + y3 + y4) / 4
我们将条形码结果转换为DetectedObjectResult
列表,稍后将在屏幕上渲染。
如果将label
设置为result.barcodeText
,则条形码的内容将显示在屏幕上。
该效果适用于孤立的条形码。但是,如果相机视图中出现多个条形码,则显示器可能会过度拥挤。要解决此问题,我们可以将label
设置为✓
并在列表视图中显示条形码内容。
启用相机自动焦点
默认情况下,ARCORE摄像机设置为固定焦点,这可以使条形码显得模糊。为了提高条形码检测准确性,必须使用自动焦点。
将开关按钮添加到UI中以切换焦点模式。
-
在
activity_main.xml
布局文件中创建一个开关按钮:
<androidx.appcompat.widget.SwitchCompat android:id="@+id/switch_focus_mode" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentEnd="true" android:checked="false" android:text="@string/switch_focus_mode" android:textColor="#ffffff" />
-
在
MainActivityView.kt
中,获取对开关按钮的引用:
var focusModeSwitch = root.findViewById<SwitchCompat>(R.id.switch_focus_mode)
-
在
AppRenderer.kt
中注册开关按钮的OnCheckedChangeListener
:
view.focusModeSwitch.setOnCheckedChangeListener { _, isChecked -> val session = activity.arCoreSessionHelper.sessionCache ?: return@setOnCheckedChangeListener val config = session.config config.focusMode = if (isChecked) Config.FocusMode.AUTO else Config.FocusMode.FIXED session.configure(config) }
源代码
https://github.com/yushulx/android-arcore-barcode-qr-detection