Where is cv.h supposed to be? Am I supposed to follow the instructions here to install openCV for Windows/c++… or is there an oF-specific thing I’m supposed to do?
I tried the link you posted in your last post. In the Windows section there, I followed the link to the Tesseract at UB Mannheim page, but the windows installer there was to set up an executable and didn’t make any lib files…
Next, I tried the method in that stackoverflow thread. The installation was successful, but the include, lib, and bin folders contain many, many files and I’m not sure which are needed in my project and where I need to put them or if I need to rename them…
@s_e_p I got this running fine on OSX in Xcode a while ago - but I do remember some fiddling with links and libraries had to be done - apologies - i dont remember exactly what I did at the time but the structure of the working addon and a working project (on Mac) looked like this - in case it helps?
I think the best bet would be to add all the .a or .lib files generated by the build process into the addon folder in the same format as used by the ofxOpenCv addon. ie addons/ofxTesseract/libs/tesseract/lib/vs/x64/
Then you could use the Project Generator to make a new project with the addon and it should add the libs correctly to the linker.
Note: you might need to separate Debug and Release libs or just use release libs and only build for release.
Feel free to share the file list from the build and we can help you id which files you need.
Hey @danb . Actually, it’s because I watched your video that I started messing with this, so thank you! It looks like you have some lib files in your bin folder (idk what the dylib extension is though…)
@theo OK, I tried regenerating the sln file after moving, as you said, all the .lib files installed via the stackoverflow approach (from the directory installed/x64-windows/lib) into addons/ofxTesseract/libs/tesseract/lib/vs/x64/
but it didn’t work. I do get less errors now than before though:
Now, the stackoverflow method (vcpkg) also generated h files, so I wonder if I need to replace the original header files in the include folder (baseapi.h & thresholder.h) with those files… Here’s a screenshot of the vcpkg-generated include folder:
Am I being lazy? Should I look through each of these header files individually and look for a file that resembles the original baseapi.h…? Or is the problem really just the lib files…?
I’ve also tried installing cmake and using that to build from the original repo, but I don’t really get that either. I followed the instructions here, and got this:
Ah yeah - you might want to add the files from the include/tesseract/ folder and that might fix those errors. as the API might have changed between the version in the addon and the vcpkg version.
@theo OK, I’ve copied all the header files (but none of the folders) from fcpkg/installed/x64-windows/include/tesseract into ofxTesseract/libs/tesseract/include:
OK, commenting out the accuracy stuff allowed it to build.!
@theo So after I set the location of the eng.traineddata file properly, using the file that originally came with this repo, I ran and got a stream of ‘Bad read of inttemp!’ messages. Then I tried downloading the eng.traineddata file from here. I would expect this to work because the readme says it’s for versions 4.0.0 and newer and the version.h of the files I’m using (gotten with vcpkg) says this is version 5.3.1 of Tesseract. But when I run it, the program immediately exits with an error. Running in debug mode shows an access violation bug set off by runOcr():
Not sure if the medianblur thing is important though… Does blurring help legibility in some cases? And if so, should I replace this call with one to another ofxCv::medianBlur? Having both ofxCv and ofxOpenCv as needed addons isn’t ideal if I’m going to be forking ofxTesseract for Windows though…
EDIT2: Now that I think about it, this CvUtils file isn’t even part of the ofxTesseract addon, so I guess I don’t need to do anything about that…
@danb Hey, have you added the code from your video to your GitHub? I cant find it. The parts of your code for detection work well and curious about how you cleanText() method works (dictionary comparison).
EDIT: Ah, sorry, I watched again and in your video you haven’t implemented it yet. I thought you had due to the existence of cleanText()
I looked into this myself and adopted the code here. I also added functionality to check for upper/lower-case variations:
struct Lexicon
{
Lexicon()
{
cout << "um " << endl;
//std::ifstream input("data\\dict.txt");
std::ifstream input("C:\\Users\\selli\\openFrameworks\\addons\\ofxCustom\\textData\\dict.txt");
if (input.is_open())
{
std::cout << "lex opened" << endl;
}
else
{
std::cout << "lex not opened " << endl;
}
for (std::string line; std::getline(input, line);)
{
//cout << "insert: " << line << endl;
words.insert(line);
}
}
bool contains(std::string const& word, bool checkAllLower = false, bool checkAllUpper = true) const
{
bool isWord = words.count(word);
if (isWord)
{
//cout << word << " is a word" << endl;
return true;
}
if (checkAllLower)
{
std::string wordLower = word;
for (int i = 0; i < wordLower.size(); ++i)
{
wordLower[i] = std::tolower(wordLower[i]);
}
if (words.count(wordLower))
{
//cout << wordLower << " is a lower word" << endl;
return true;
}
}
if (checkAllUpper)
{
std::string wordUpper = word;
for (int i = 0; i < wordUpper.size(); ++i)
{
wordUpper[i] = std::tolower(wordUpper[i]);
}
if (words.count(wordUpper))
{
//cout << wordUpper << " is an upper word" << endl;
return true;
}
}
return false;
}
std::set<std::string> words;
};
This works well… the lexicon text file I found included every single letter as a word, so I had to get rid of those. That includes ‘a’ and ‘I’. Despite being important words, they get detected constantly. I may consider restoring them if I find other ways to increase accuracy (maybe using blur?)
yep - that is coming in the next video - at the moment the cleantext() routine just removes line breaks and allows concatenation - but is waiting for just the kind of process you added !
string ofApp::cleanText(string textIn){
// clean out carriage returns from text
textIn.erase( std::remove(textIn.begin(), textIn.end(), '\n'), textIn.end() );
return textIn;
}
I’ve been messing with it and found so far two ways to affect sensitivity/accuracy.
Applying a little bit of blur will reduce false positives
making the image monochrome seems to help a lot. Red text on white background doesn’t get picked up, but does when I make the image grayscale.
Big problem I’m noticing now is that some fonts don’t get picked up at all. I was hoping there’d be a quick way to get training data for different fonts, but I may need to create my own training data or else resign myself to incomplete recognition.
I found the technical description from the tesseract documentation on improving recognition helpful to understand what it’s looking for Improving the quality of the output | tessdoc