iam using tesseract ocr for reading german png images in c++ and i got problems with some special characters like
ß ä ö ü and so on.
Do i need to train tesseract for reading this correct or what need to be done?
This is the part of the original image read by tesseract
tesseract::TessBaseAPI *api = new tesseract::TessBaseAPI();
UPDATE
SetConsoleOutputCP(1252);//changed to german.
SetConsoleCP(1252);//changed to german
wcout << "ÄÖÜ?ß" << endl;
// Open input image with leptonica library
Pix *image = pixRead("D:\\Images\\Document.png");
api->Init("D:\\TesseractBeispiele\\Tessaractbeispiel\\Tessaractbeispiel\\tessdata", "deu");
api->SetImage(image);
api->SetVariable("save_blob_choices", "T");
api->SetRectangle(1000, 3000, 9000, 9000);
api->Recognize(NULL);
// Get OCR result
wcout << api->GetUTF8Text());
After changing the Code below the Update
the hard coded umlauts will be shown correctly, but the text from the image issnt correct, what do i need to change?
tesseract version is 3.0.2
leptonica version is 1.68
Tesseract can recognize Unicode characters. Your console may have not been configured to display them.
What encoding/code page is cmd.exe using?
Unicode characters in Windows command line - how?
i don't how to detect German the word from the image in windows environment. but i know how to detect German word to Linux environment. following code may get you some idea.
/*
* word_OCR.cpp
*
* Created on: Jun 23, 2016
* Author: root
*/
#include <tesseract/baseapi.h>
#include <leptonica/allheaders.h>
#include <iostream>
using namespace std;
int main(int argc ,char **argv)
{
Pix *image = pixRead(argv[1]);
if (image == 0) {
cout << "Cannot load input file!\n";
}
tesseract::TessBaseAPI tess;
// insted of the passing "eng" pass "deu".
if (tess.Init("/usr/share/tesseract/tessdata", "deu")) {
fprintf(stderr, "Could not initialize tesseract.\n");
exit(1);
}
tess.SetImage(image);
tess.Recognize(0);
tesseract::ResultIterator *ri = tess.GetIterator();
tesseract::PageIteratorLevel level = tesseract::RIL_WORD;
if(ri!=0)
{
do {
const char *word = ri->GetUTF8Text(level);
cout << word << endl;
delete []word;
} while (ri->Next(level));
delete []ri;
}
}
one thing you have to take care that pass good resolution image then and then it works fine.
Related
Having a hard time getting tesseract to recognize alphanumeric text. These are not dictionary words, and I've set load_system_dawg and load_freq_dawg to false as recommended in the docs.
Sample code showing what I'm doing:
// Compile with: g++ test.cpp $(pkg-config --libs tesseract opencv)
#include <tesseract/baseapi.h>
#include <tesseract/genericvector.h>
#include <opencv2/opencv.hpp>
int main()
{
/* Disabling the dictionaries Tesseract uses should increase recognition
* if most of your text isn't dictionary words. They can be disabled by
* setting both of the configuration variables load_system_dawg and
* load_freq_dawg to false.
* Source: https://github.com/tesseract-ocr/tesseract/wiki/ImproveQuality
*/
GenericVector<STRING> key;
GenericVector<STRING> val;
key.push_back("load_system_dawg");
val.push_back("false");
key.push_back("load_freq_dawg");
val.push_back("false");
// also tried setting tosp_min_sane_kn_sp to both large and small values
#if 0
// unfortunately, this doesn't work in tesseract v4.0
// https://github.com/tesseract-ocr/tesseract/issues/751
key.push_back("tessedit_char_whitelist");
val.push_back("ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789");
#endif
std::unique_ptr<tesseract::TessBaseAPI> tess(new tesseract::TessBaseAPI());
tess->Init(nullptr, "eng", tesseract::OEM_DEFAULT, nullptr, 0, &key, &val, false);
tess->SetPageSegMode(tesseract::PageSegMode::PSM_SINGLE_LINE);
for (const auto filename : {"01.png", "02.png", "03.png", "04.png", "05.png", "06.png", "07.png", "08.png", "09.png", "10.png", "11.png", "12.png"})
{
cv::Mat mat = cv::imread(filename);
tess->SetImage(mat.data, mat.cols, mat.rows, mat.channels(), mat.step1());
char *text = tess->GetUTF8Text();
std::string str;
if (text != nullptr)
{
str = text;
}
delete [] text;
std::cout << "OCR results for " << filename << ": " << str << std::endl;
cv::imshow("image", mat);
cv::waitKey();
}
tess->End();
return 0;
}
The images I'm using and the results I'm seeing from tesseract:
"1K 45" (missing whitespace)
"1K"
"ZaP © 13" (top few pixels are missing so this one doesn't surprise me)
"308 8" ('B' vs '8' I understand, but the missing whitespace means we cannot interpret this text)
"23 B 18"
"" (blank!?)
"SZ2EC 5"
"SZ2EC 3"
"1201" (missing whitespace means we cannot interpret these results)
"a)"
"1 € 13"
"J4E 7"
I'm not looking for 100% recognition, but I think there are likely some configuration items in tesseract that I could be setting to get better results than what I'm currently seeing.
I'm following the tutorial here for setting up OpenCV with Visual Studio (I have 2013 Community edition and OpenCV 2.4.10).
I have the following folder structure:
OpenCVTest
-OpenCVTest.sln
+x64
+Debug
- opencv_core2410d.dll
- opencv_highgui2410d.dll
- OpenCVTest.exe
- OpenCVTest.ilk
- OpenCVTest.pdb
- feck.png
And my source:
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <iostream>
using namespace cv;
using namespace std;
int main(int argc, char** argv)
{
if (argc != 2)
{
cout << " Usage: display_image ImageToLoadAndDisplay" << endl;
return -1;
}
Mat image;
image = imread(argv[1], IMREAD_COLOR); // Read the file
if (!image.data) // Check for invalid input
{
cout << "Could not open or find the image" << std::endl;
return -1;
}
namedWindow("Display window", WINDOW_AUTOSIZE); // Create a window for display.
imshow("Display window", image); // Show our image inside it.
waitKey(0); // Wait for a keystroke in the window
return 0;
}
When I run this in VS or on the command line, I get the following error:
C:\Users\mr\Documents\Visual Studio 2013\Projects\OpenCVTest\x64\Debug>OpenCVTest.exe feck.png
Could not open or find the image
Anybody know why this might be happening?
Update
I have tried giving the full path:
image = imread("C:\Users\mr\Documents\Visual Studio 2013\Projects\OpenCVTest\feck.png", IMREAD_COLOR); // Read the file
and placing the image at the same level as the .sln file, still no luck.
Place your image in OpenCVTest folder like this:
C:\Users\mr\Documents\Visual Studio 2013\Projects\OpenCVTest\OpenCVTest\feck.png
-OpenCVTest.sln
-OpenCVTest <- **HERE**
-ipch
+x64
+Debug
- opencv_core2410d.dll
- opencv_highgui2410d.dll
- OpenCVTest.exe
- OpenCVTest.ilk
- OpenCVTest.pdb
- feck.png
In the tutorial here, under "The local method", it reads:
Then you need to specify the libraries in which the linker should look
into. To do this go to the Linker ‣ Input and under the “Additional
Dependencies” entry add the name of all modules which you want to use:
opencv_core231d.lib
opencv_imgproc231d.lib
opencv_highgui231d.lib
opencv_ml231d.lib
opencv_video231d.lib
opencv_features2d231d.lib
opencv_calib3d231d.lib
opencv_objdetect231d.lib
opencv_contrib231d.lib
opencv_legacy231d.lib
opencv_flann231d.lib
I changed these from opencv_core{version}d.lib to opencv_core{version}.lib (not the debug library) and it seems to work okay now. I can step through the code in Visual Studio and the code appears to work.
i'm starting using opencv with visual studio, these are my sw components and environment:
windows 8.1 (64bit)
visual studio professional 2013
opencv 2.4.9
first of all i've downloaded opencv and extracted all in "C:\OpenCV-2.4.9", then i've created a new environment variable (user variable) OPENCV_DIR with value "C:\OpenCV-2.4.9\opencv\build" and added the string ";%OPENCV_DIR%\x86\vc12\bin" to the existing environment variable Path.
first question: do i should set x64 instead of x86 in the above string value? in general, are all settings right?
then i've created a new win32 console project with visual studio, it creates a function _tmain(int argc, _TCHAR* argv[])inside a .cpp file named .cpp.
second question: what is the reason because i've to use such '_tmain' function instead the classic 'main' function? which is the structure of the calls when i 'run' the project? is that useful? and if i wish use the classic 'main'?
then, i've defined the following code
int main(int argc, char* argv[])
{
if (argc != 2)
{
cout << " Usage: display_image ImageToLoadAndDisplay" << endl;
return -1;
}
Mat image;
image = imread(argv[1], IMREAD_COLOR); // Read the file
if (image.empty()) // Check for invalid input
{
cout << "Could not open or find the image" << std::endl;
return -2;
}
namedWindow("Display window", WINDOW_AUTOSIZE); // Create a window for display.
imshow("Display window", image); // Show our image inside it.
waitKey(0); // Wait for a keystroke in the window
return 0;
}
when i compile and debug with visual studio everything is ok! but i cannot be able to give the requested parameter to the function... it starts and ends with output code -1 (the first if check).
moreover, if i find the .exe and try to run it using the prompt, an error occurs:
"Impossible to run the program because opencv_core249d.dll is not present...... try to reinstall the program".
it is clear that these are common problems but i'm finding these issue so hard... thanks to all!
I am developing an application that requires multiple webcams. In order to make sure that the correct webcam is used for each part of the application, I created some udev rules that SYMLINK the webcam to a specific name, depending on the serial number.
This works great, and I can access the camera by that name using VLC and a variety of other applications.
But when I try to access the camera by that name (or the non-syminked name given by linux) using OpenCV and python, I can't read a frame from the camera and my program hangs. The camera is opened successfully. I've created a sample application in C++ to test if it was perhaps a python/opencv related bug, but the same thing happens in C++ too.
Here is my C++ test application that doesn't work:
#include <iostream>
#include <opencv2/opencv.hpp>
using namespace std;
using namespace cv;
int main (int argc, const char * argv[])
{
VideoCapture cap("/dev/my_custom_name");
if (!cap.isOpened())
return -1;
cout << "Opened..." << endl;
Mat img;
namedWindow("video capture", CV_WINDOW_AUTOSIZE);
while (true)
{
cout << "Trying..." << endl;
cap >> img;
cout << "Got" << endl;
imshow("video capture", img);
if (waitKey(10) >= 0)
break;
}
return 0;
}
I get the Opened... and Trying... messages, but not the Got message.
Any ideas on how to resolve this issue?
(This is all on linux btw).
Thanks
I figured this out. When I opened the capture in VLC, I noticed that it preixed the filename with v4l2://. When I did the same in my application, it worked!
So to reference above, "/dev/my_custom_name" should become "v4l2:///dev/my_custom_name".
I am making a simple FLTK application (in windows) that needs to display PNG images in FL_Window, load them one after the other from disk. I have this code as a starting point but its not displaying the image which I can confirm is in the same folder as the executable:
int main(int argc, char **argv)
{
Fl_Window *main_window = NULL;
fl_register_images();
flw = new Fl_Window(1680,1050,title);
Fl_Shared_Image *a = Fl_Shared_Image::get("picture.png");
if (a != NULL)
{
cout << "Image loaded" << endl;
}
else
{
cout << "No image loaded" << endl; // <==== This is printed
}
flw->begin();
// add image to window code here, not sure what to write but
// image doesnt even load
flw->end();
main_window->show();
int fl_ret = Fl::run();
return fl_ret;
}
Any help greatly appreciated ..
Fl_Shared_Image class used for
"Find or load an image that can be shared by multiple widgets."
use Fl_PNG_Image class
int main() {
fl_register_images();
Fl_Window win(720,486);
Fl_Box box(10,10,720-20,486-20);
Fl_PNG_Image png("picture.png");
box.image(png);
win.show();
return(Fl::run());
}
You only loaded the image.
Birol's answer loaded and displayed box.image(png); the image.
If you are using an IDE, your IDE might be running an executable in another directory.
Give the absolute address of your image, and it should work.