multithreading - 捕获每一帧以识别文本 ARcore - 我需要使用信号量吗?
问题描述
我正在开发一个应用程序,我想在其中实时识别文本。
起初我使用onTapListener所以每当用户在屏幕上点击时,当前帧就会被捕获,然后调用文本识别。
现在我想完全实时地做到这一点,这样用户就不会点击屏幕来捕捉当前帧。但是每个当前帧都将被捕获,直到一个捕获的当前帧的文本将被识别。
出于这个原因,我创建了一个全局布尔字段名locked,它初始化为false,我将它用作“储物柜”,稍后您会看到。
private boolean locked = false;
在onUpdateFrame(FrameTime frameTime)方法中,我使用了上述全局变量locked。当第一个特征点被跟踪时,我“锁定”了更新。所以只有当前线程会捕获当前帧。如果识别的数据为空,我将locked = true 以便捕获下一帧。
这是我的代码
public void onUpdateFrame(FrameTime frameTime) {
Frame frame = arFragment.getArSceneView().getArFrame();
// If there is no frame, just return.
if (frame == null) {
return;
}
//Making sure ARCore is tracking some feature points, makes the augmentation little stable.
if(frame.getCamera().getTrackingState()==TrackingState.TRACKING && !locked) {
locked = true;
if (mProgressDialog == null) {
mProgressDialog = ProgressDialog.show(this, "Processing",
"OCR...", true);
} else {
mProgressDialog.show();
}
executor.execute(() -> {
Bitmap b = captureImage();
final String[] text = {getOCRResult(b)};
handler.post(() -> {
if(text[0] != null && !text[0].equals("")){
doSomething();
}
else{
locked = false;
}
}
这虽然行不通。当检测到表面时,我的应用程序立即崩溃。
我收到以下错误,该错误所涉及的Toast指的是我在方法captureImage()中拥有的 Toast
E/AndroidRuntime: 致命异常: pool-1-thread-1 进程: opencv.org, PID: 27860 java.lang.RuntimeException: Can't toast on a thread that has not called Looper.prepare()
我无法理解我做错了什么。我听说过信号量,这就是我问这个问题的原因。我应该使用信号量,我是否需要这样的东西才能让我的应用程序正常工作。据我了解,我随时需要一个线程来捕获当前帧。有人可以帮我我有点迷路吗?谢谢你
解决方案
您收到此错误的原因是您无法在非 UI 线程上显示 toast 或任何 UI。
处理此问题的常用方法是在 UI 线程上创建一个“处理程序”并向其消息队列发送一条消息,要求它发布该线程。
您可以在此答案中看到 Java 和 Kotlin 中的示例:Can't create handler inside thread that has not called Looper.prepare()
更多关于 Handler 的信息:https ://developer.android.com/reference/android/os/Handler
推荐阅读
- c# - 调用局部视图
- domain-driven-design - DDD - 如何在应用层重用代码?
- apache-spark - pySpark .join() 具有不同的列名,不能在运行前硬编码
- python - Plotly:如何交替背景网格颜色?
- powershell - 通过 Windows 服务运行的交互式应用程序
- python - boto3 如何通过 python 脚本使用 AWS SSM 服务安装云手表代理
- python - 我正在尝试使 GET 方法显示 webserver 目录中的所有文件
- javascript - 将数据从 PostgreSQL 转换为 JavaScript 变量
- matlab - Matlab 'FrequencyRange' 上的 stft 函数不是可识别的参数
- swift - 从 Locale swift 获取货币名称