Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Docs update suggestion: building from sources under linux gives error No OCR is available #698

Open
arnwas opened this issue Nov 11, 2023 · 7 comments

Comments

@arnwas
Copy link

arnwas commented Nov 11, 2023

Hi, just about to give audiveris a try, and for various reasons i am about to build it from sources under linux.
I followed the docs and it says, that "Tesseract libraries are automatically pulled as Gradle dependencies", i need just to provide the language files, which are installed via apt-get. As is tesseract itself, though docs say, audiveris would use its own.
./gradle build does not give any error or hint of a problem.
./gradle run gives "No OCR is available".
Only later i found out that TESSDATA_PREFIX being set manually also makes the OCR itself being found.
Maybe your docs could contain a hint to that?

Cheers, Arno

@hbitteur
Copy link
Contributor

@arnwas
Have you read this handbook section on OCR languages?

I'm not a Linux expert at all, but my understanding of using apt-get is that it will install the tesseract program and perhaps some of the program-related language files.

Unfortunately this has nothing to do with Audiveris needs.

  • It needs a tesseract library not a self standing program (the library is pulled at build time by gradle, which is fine).
  • It needs also specific tesseract language files, compatible with the legacy mode used by Audiveris. These files are not the ones bundled by tesseract program (the bundle contains only LSTM model language files). Therefore today you have to download the suitable language files on your own.

I know this is a bit confusing to say the least.
On the TODO list, I have put the issue #692, about a user dialog within Audiveris to handle the downloading of correct language files. This should solve this problem once and for all.

@arnwas
Copy link
Author

arnwas commented Nov 11, 2023

Hi, sorry for confusion, but this was not my point, I had all things, but I was confused that the library itself was not found, and this changed by setting the path for the language files (which are installed by apt-get when selecting the appropriate packages, btw.), not the library.

Yours, Arno

@arnwas
Copy link
Author

arnwas commented Nov 11, 2023

Okay, it is even more confusing. The handbook says, that the tesseract library is provided for while building.
But when running a transcript, it can't be initialize according to the log. But the log does not say why. If i forget to SET the location if the language files, it fails to start, for not having tesseract found. So, something is not as it is said. But, how is it?

@hbitteur
Copy link
Contributor

It fails for not being able to initialize the Tesseract library with the provided arguments (typically the desired legacy mode and the desired languages).
That'all it says.

The tesseract library is certainly present (thanks to Gradle build).
But, at run time, this library may not be able to correctly initialize (probable reason: suitable languages data files are not found).

For the time being, setting the TESSDATA_PREFIX variable is the safest policy. Please read this line aloud several times! :-)

@arnwas
Copy link
Author

arnwas commented Dec 15, 2023

well, error messages telling the problem correctly would certainly help :-)

@hbitteur
Copy link
Contributor

Indeed!

For Audiveris, Tesseract is an external library.
And Tesseract documentation says about the TessbaseAPI.Init(String datapath, String language) method:

  /**
   * Instances are now mostly thread-safe and totally independent,
   * but some global parameters remain. Basically it is safe to use multiple
   * TessBaseAPIs in different threads in parallel, UNLESS:
   * you use SetVariable on some of the Params in classify and textord.
   * If you do, then the effect will be to change it for all your instances.
   *
   * Start tesseract. Returns zero on success and -1 on failure.
   * NOTE that the only members that may be called before Init are those
   * listed above here in the class definition.
   *
   * The datapath must be the name of the tessdata directory.
   * The language is (usually) an ISO 639-3 string or nullptr will default to
   * eng. It is entirely safe (and eventually will be efficient too) to call
   * Init multiple times on the same instance to change language, or just
   * to reset the classifier.
   * The language may be a string of the form [~]<lang>[+[~]<lang>]* indicating
   * that multiple languages are to be loaded. Eg hin+eng will load Hindi and
   * English. Languages may specify internally that they want to be loaded
   * with one or more other languages, so the ~ sign is available to override
   * that. Eg if hin were set to load eng by default, then hin+~eng would force
   * loading only hin. The number of loaded languages is limited only by
   * memory, with the caveat that loading additional languages will impact
   * both speed and accuracy, as there is more work to do to decide on the
   * applicable language, and there is more chance of hallucinating incorrect
   * words.
   * WARNING: On changing languages, all Tesseract parameters are reset
   * back to their default values. (Which may vary between languages.)
   * If you have a rare need to set a Variable that controls
   * initialization for a second call to Init you should explicitly
   * call End() and then use SetVariable before Init. This is only a very
   * rare use case, since there are very few uses that require any parameters
   * to be set before Init.
   *
   * If set_only_non_debug_params is true, only params that do not contain
   * "debug" in the name will be set.
   */
  public native int Init(@Cast("const char*") BytePointer datapath, @Cast("const char*") BytePointer language, @Cast("tesseract::OcrEngineMode") int mode,
             @Cast("char**") PointerPointer configs, int configs_size,
             @Const StringVector vars_vec,
             @Const StringVector vars_values,
             @Cast("bool") boolean set_only_non_debug_params);
  public native int Init(@Cast("const char*") BytePointer datapath, @Cast("const char*") BytePointer language, @Cast("tesseract::OcrEngineMode") int mode,
             @Cast("char**") @ByPtrPtr BytePointer configs, int configs_size,
             @Const StringVector vars_vec,
             @Const StringVector vars_values,
             @Cast("bool") boolean set_only_non_debug_params);
  public native int Init(String datapath, String language, @Cast("tesseract::OcrEngineMode") int mode,
             @Cast("char**") @ByPtrPtr ByteBuffer configs, int configs_size,
             @Const StringVector vars_vec,
             @Const StringVector vars_values,
             @Cast("bool") boolean set_only_non_debug_params);
  public native int Init(@Cast("const char*") BytePointer datapath, @Cast("const char*") BytePointer language, @Cast("tesseract::OcrEngineMode") int mode,
             @Cast("char**") @ByPtrPtr byte[] configs, int configs_size,
             @Const StringVector vars_vec,
             @Const StringVector vars_values,
             @Cast("bool") boolean set_only_non_debug_params);
  public native int Init(String datapath, String language, @Cast("tesseract::OcrEngineMode") int mode,
             @Cast("char**") @ByPtrPtr BytePointer configs, int configs_size,
             @Const StringVector vars_vec,
             @Const StringVector vars_values,
             @Cast("bool") boolean set_only_non_debug_params);
  public native int Init(@Cast("const char*") BytePointer datapath, @Cast("const char*") BytePointer language, @Cast("tesseract::OcrEngineMode") int mode,
             @Cast("char**") @ByPtrPtr ByteBuffer configs, int configs_size,
             @Const StringVector vars_vec,
             @Const StringVector vars_values,
             @Cast("bool") boolean set_only_non_debug_params);
  public native int Init(String datapath, String language, @Cast("tesseract::OcrEngineMode") int mode,
             @Cast("char**") @ByPtrPtr byte[] configs, int configs_size,
             @Const StringVector vars_vec,
             @Const StringVector vars_values,
             @Cast("bool") boolean set_only_non_debug_params);
  public native int Init(@Cast("const char*") BytePointer datapath, @Cast("const char*") BytePointer language, @Cast("tesseract::OcrEngineMode") int oem);
  public native int Init(String datapath, String language, @Cast("tesseract::OcrEngineMode") int oem);
  public native int Init(@Cast("const char*") BytePointer datapath, @Cast("const char*") BytePointer language);
  public native int Init(String datapath, String language);

So, everything is in this line:

Start tesseract. Returns zero on success and -1 on failure.

Audiveris detected a non-zero returned value. That'all it can say.

@mwilck
Copy link

mwilck commented Jan 3, 2024

@arnwas, what about just using the flatpak package?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants