I’m building an app for Android that uses the Tesseract library in a asynchronous call.
The method for performing the OCR works great untill I call it on a different thread. The exceptions I get are:
*1: java.Lang.Unsatisfiedlinkerror: Library opencv_core not found; tried [/vendor/lib/libopencv_core.so, /system/lib/libopencv_core.so]
2: System.TypeInitializationException: An exception was thrown by the type initializer for Emgu.CV.CvInvoke*
The code I’m using:
protected override void OnStart()
{
base.OnStart();
ImageView testimage = FindViewById<ImageView>(Resource.Id.TestImage);
testimage.SetImageBitmap(ScanImage);
ThreadPool.QueueUserWorkItem(state => {
PerformOCR();
});
}
protected void PerformOCR() //object state
{
//Get the tesseract directory
Java.IO.File myDir = Android.OS.Environment.ExternalStorageDirectory;
Tesseract _ocr = new Tesseract(myDir.ToString() + "/tesseract/", "eng", Tesseract.OcrEngineMode.OEM_TESSERACT_CUBE_COMBINED);
//Image optimization
Image<Gray, Byte> passport = new Image<Gray, Byte>(ScanImage);
Image<Gray, float> sobel = passport.Sobel(1, 0, 5);
sobel.Add(passport.Sobel(0, 1, 5));
passport = passport.Add(sobel.Convert<Gray, byte>());
_ocr.Recognize(passport);
string text = _ocr.GetText();
RunOnUiThread(() => SpecificationsText.Text = text);
}
The image used in the OCR is stored in a static class.
Ok, I’ve solved my own problem.
For some reason the tesseract initialization cannot be done in an asynchronous method, so by removing the initialization from the method call and doing it somewhere else my problem was solved.