我已经弄清楚了,如果你正在使用Visual Studios 2010并使用Windows Forms/设计器,你可以轻松添加它,而且没有任何问题。
将以下项目添加到您的项目中(我警告您一次,不要添加Tesseract解决方案,或更改您添加的项目中的任何设置,除非您喜欢自讨苦吃)
ccmain
ccstruct
ccutil
classify
cube
cutil
dict
image
libtesseract
nutral_networks
textord
viewer
wordrec
你可以添加其他项目,但你真的不想把所有这些都集成在你的项目中,对吧?不需要,分别构建它们即可。
打开项目属性并添加libtesseract作为参考,现在你可以看到它作为一个项目可见,这将使您的项目快速构建而不必检查tesseract中的数百万个警告。[常规属性]->[添加引用]
在解决方案资源管理器中右键单击您的项目,然后单击项目依赖项,确保它依赖于libtesseract甚至所有这些项目,这意味着它们会在您的项目之前构建。
tesseract 2010 Visual Studio项目包含许多配置设置,例如release、release.dll、debug、debug.dll,似乎release.dll设置会生成正确的文件。首先,将解决方案输出设置为release.dll。单击您的项目属性。然后单击配置管理器。如果不可用,请单击解决方案树中的SOLUTION属性,然后单击配置选项卡,您将看到一系列项目和相关的配置设置。您会注意到您的项目未设置为release.dll,即使输出是如此。如果您采取了第二种方法,则仍需单击配置管理器。然后您可以编辑设置,在您的项目设置上单击新建并将其命名为release.dll……与其他设置完全相同,并从release中复制设置。对于Debug也要做同样的事情,这样您就有了从debug设置中复制的debug.dll名称。快完成了
不要尝试更改tesseract的设置以匹配您的设置……那行不通……当新版本发布时,您将无法“扔进去”并继续使用。接受这个事实,在此状态下,您的新模式是Release.dll和Debug.dll。不要紧张……完成后可以返回并从解决方案中删除这些项目。
猜猜库和dll在哪里?在您的项目中,您可能需要添加库目录。有人说要将所有头文件倒入一个单独的文件夹中,以便他们只需要添加一个文件夹到包含文件夹中,但我不这么做。我希望能够删除tesseract文件夹并从zip文件重新加载它而无需额外工作……并且可以完全准备好一次更新或恢复代码。这需要一些工作,您可以通过代码而不是设置来完成,但应该包括包含在2010 tesseract项目文件夹中的所有包含头文件的文件夹,并让它们保持原样。
没有必要向您的项目添加任何文件。只需这些代码行……我还包括了一些额外的代码,用于将一组外国数据转换为不需要保存/加载文件的tiff友好版本。我真好心吧?
现在您可以完全在debug.dll和release.dll中进行调试,一旦您成功将其构建到您的项目中,甚至可以删除所有添加的项目,它将是完美的。没有额外的编译或错误。完全可调试,完全自然。
如果我没记错的话,我无法避免必须将2008/lib/中的文件复制到我的项目发布文件夹中……该死。
在我的项目中的“functions.h”文件里,我放置了以下内容:
#pragma comment (lib, "liblept.lib" )
#define _USE_TESSERACT_
#ifdef _USE_TESSERACT_
#pragma comment (lib, "libtesseract.lib" )
#include <baseapi.h>
#endif
#include <allheaders.h>
在我的主项目中,我将以下内容作为成员放入了一个类中:
tesseract::TessBaseAPI *readSomeNombers
当然,我在某个地方包含了“functions.h”。
然后我将此放入我的类构造函数中:
readSomeNombers = new tesseract::TessBaseAPI();
readSomeNombers ->Init(NULL, "eng" );
readSomeNombers ->SetVariable( "tessedit_char_whitelist", "0123456789,." );
然后我创建了这个类成员函数:以及一个类成员来作为输出,不要反感,我不喜欢返回变量。不是我的风格。在成员函数内部使用图像的内存不需要被销毁,我相信这是一种安全的调用方式,我的测试也证明了这一点。但是,无论如何,你可以做任何事情。
void Gaara::scanTheSpot()
{
Pix *someNewPix;
char* outText;
ostringstream tempStream;
RECT tempRect;
someNewPix = pixCreate( 200 , 40 , 32 );
convertEasyBmpToPix( &scanImage, someNewPix, 87, 42 );
readSomeNombers ->SetImage(someNewPix);
outText = readSomeNombers ->GetUTF8Text();
tempStream.str("");
tempStream << outText;
classMemeberVariable = tempStream.str();
}
我想扫描的信息所在的对象在内存中,并且由&scanImage
指向。这是来自“EasyBMP”库的,但这并不重要。
我在“functions.h”/“functions.cpp”中编写了一个处理它的函数,顺便说一下,我正在循环中进行一些额外的处理,即细化字符、将其变成黑白颜色并反转黑白颜色,这是不必要的。在开发的这个阶段,我仍在寻找改进识别的方法。尽管对于我的目的,这还没有产生过坏数据。我的看法是为了简单起见使用默认的Tess数据。我正在试图以启发式的方式解决一个非常复杂的问题。
void convertEasyBmpToPix( BMP *sourceImage, PIX *outputImage, unsigned startX, unsigned startY )
{
int endX = startX + ( pixGetWidth( outputImage ) );
int endY = startY + ( pixGetHeight( outputImage ) );
unsigned destinationX;
unsigned destinationY = 0;
for( int yLoop = startY; yLoop < endY; yLoop++ )
{
destinationX = 0;
for( int xLoop = startX; xLoop < endX; xLoop++ )
{
if( isWhite( &( sourceImage->GetPixel( xLoop, yLoop ) ) ) )
{
pixSetRGBPixel( outputImage, destinationX, destinationY, 0,0,0 );
}
else
{
pixSetRGBPixel( outputImage, destinationX, destinationY, 255,255,255 );
}
destinationX++;
}
destinationY++;
}
}
bool isWhite( RGBApixel *image )
{
if(
( image->Red < 50 ) ||
( image->Blue < 50 ) ||
( image->Green < 50 )
)
{
return false;
}
else
{
return true;
}
}
我不喜欢的一件事是在函数外部声明像素大小的方式。如果我试图在函数内部这样做,我会得到意想不到的结果……如果在内部分配内存,则在离开时会被销毁。
g m a i l
这绝不是我最优美的作品,但也为了简单而大刀阔斧地摆脱了它。我为什么要分享这个,我不知道。我应该把它留给自己。
我的名字是什么?Kage.Sabaku.No.Gaara
在让你走之前,我应该提到我的Windows表单应用程序和默认设置之间的细微差别。即我使用“多字节”字符集。项目属性……等等……给狗一根骨头,也许能投一票?
p.p.s. 我不想说,但我对host.c做了一个改变,如果你使用64位,你也可以这样做。否则你就自己想办法吧……但我的原因有点疯狂,不需要效仿。
typedef unsigned int uinT32;
#if (_MSC_VER >= 1200) //%%% vkr for VC 6.0
typedef _int64 inT64;
typedef unsigned _int64 uinT64;
#else
typedef long long int inT64;
typedef unsigned long long int uinT64;
#endif //%%% vkr for VC 6.0
typedef float FLOAT32;
typedef double FLOAT64;
typedef unsigned char BOOL8;