2

我为我的应用程序使用OpenCV,Vuforia和Tesseract(tess-two)。我的系统是这样工作的:用多线程处理Android相机帧

  1. Vuforia检测目标,并将全帧的OpenCV(JNI)
  2. OpenCV的获取框架,并做了一些图像处理,使其可读的正方体(JNI)
  3. Tesseract(tess-two)从opencv获取字节数组,并对图像执行OCR处理(字节数组)

我的问题从第三部分开始。由于我的目标是实时拍摄相机画面,所以我尝试使用多线程来使UI平滑,并且不会导致实时相机视觉变慢。

我决定使用的AsyncTask的,像这样:

public void getFromNative(final byte[] imagedata, final int width,final int height,final byte [] typeData, final int typeWidth,final int typeHeight) { 

     new AsyncTask<Void, Void, Void>() { 

      @Override 
      protected Void doInBackground(Void... params) { 
       ocr(imagedata, width, height,typeData,typeWidth,typeHeight);      
       return null; 
      } 

     }.execute();     
} 

这让直播相机流比正常的,单个线程的方式平滑。但问题在于,由于实时摄像机帧的启动,它启动了很多AsyncTask,即使我将摄像机从目标转离时,它也会继续对先前创建的AsycnTask执行OCR,并为它们一个接一个地返回结果。除了AsyncTask之外,我尝试了IntenService,但结果是一样的。

我想问问是否有办法解决这个问题,并使过程更有效率。

感谢

回答

0

我的建议,你不要试图识别每一个单帧相机peview取。我们使用以下onPreviewFrame-method:

public final void onPreviewFrame(final byte[] data, final Camera camera) { 
    this.data = data; 
    now = Calendar.getInstance().getTimeInMillis(); 

    if (now - lastRecognitionTime > TIME_BETWEEN_RECOGNITION_STARTS_IN_MILLIS) { 
     lastRecognitionTime = now; 
     startRecognition(); // here you can start your async task 
    } 
} 

这意味着识别过程只启动每隔几个预览画面,这取决于你如何配置TIME_BETWEEN_RECOGNITION_STARTS_IN_MILLIS类似的东西。

+0

谢谢你的建议,但我仍然没有看到这么多的性能增加,问题是特别是与没有这么好的相机和旧设备的设备。我在想也许这个解决方案使用的是不同于AsyncTask的多线程技术。 – koraxis

+0

当设备相对稳定并且移动不太多时,我们只识别帧。此外,我们只分析那些我们确信(或多或少)会使图片清晰的帧。 –