Tesseract-OCR 3.04在Windows7 vs2013上编译过程

从https://github.com/tesseract-ocr/tesseract下载最新源码,commit id: 86acff5, 2016.06.07. 里面有个vs2010目录,用vs2013打开tesseract.sln。Tesseract依赖图像库Leptonica,Leptonica的编译过程可以参考http://blog.csdn.net/fengbingchun/article/details/44275233,它的源码在https://github.com/fengbingchun/Liblept_Test,将Leptonica静态库及头文件加入到libtesseract304工程属性配置中。修改tesseract中equationdetect.cpp文件,将

static const STRING kCharsToEx[] = {"'", "`", "\"", "\\", ",", ".",
	"〈", "〉", "《", "》", "」", "「", ""};

修改为

static const STRING kCharsToEx[] = { "'", "`", "\"", "\\", ",", ".",
	"<", ">", "<<", ">>", "" };
分别在LIB_Debug和LIB_Release下编译libtesseract304工程,便能生成tesseract静态库。

仿照libtesseract304工程,编译tesseract工程,将静态库zlib、tiff、lept和tesseract加入到工程属性中即可。

新建Tesseract-OCR_Test控制台工程,将相应头文件和静态库加入到此工程中,测试代码来自于src/api/tesseractmain.cpp,如下:

#include <iostream>

#include "allheaders.h"
#include "baseapi.h"
#include "basedir.h"
#include "renderer.h"
#include "strngs.h"
#include "tprintf.h"
#include "openclwrapper.h"
#include "osdetect.h"

void PrintVersionInfo() {
	char *versionStrP;

	printf("tesseract %s\n", tesseract::TessBaseAPI::Version());

	versionStrP = getLeptonicaVersion();
	printf(" %s\n", versionStrP);
	lept_free(versionStrP);

	versionStrP = getImagelibVersions();
	printf("  %s\n", versionStrP);
	lept_free(versionStrP);
}

void PrintUsage(const char* program) {
	printf(
		"Usage:\n"
		"  %s --help | --help-psm | --version\n"
		"  %s --list-langs [--tessdata-dir PATH]\n"
		"  %s --print-parameters [options...] [configfile...]\n"
		"  %s imagename|stdin outputbase|stdout [options...] [configfile...]\n",
		program, program, program, program);
}

void PrintHelpForPSM() {
	const char* msg =
		"Page segmentation modes:\n"
		"  0    Orientation and script detection (OSD) only.\n"
		"  1    Automatic page segmentation with OSD.\n"
		"  2    Automatic page segmentation, but no OSD, or OCR.\n"
		"  3    Fully automatic page segmentation, but no OSD. (Default)\n"
		"  4    Assume a single column of text of variable sizes.\n"
		"  5    Assume a single uniform block of vertically aligned text.\n"
		"  6    Assume a single uniform block of text.\n"
		"  7    Treat the image as a single text line.\n"
		"  8    Treat the image as a single word.\n"
		"  9    Treat the image as a single word in a circle.\n"
		" 10    Treat the image as a single character.\n";

	printf("%s", msg);
}

void PrintHelpMessage(const char* program) {
	PrintUsage(program);

	const char* ocr_options =
		"OCR options:\n"
		"  --tessdata-dir PATH   Specify the location of tessdata path.\n"
		"  --user-words PATH     Specify the location of user words file.\n"
		"  --user-patterns PATH  Specify the location of user patterns file.\n"
		"  -l LANG[+LANG]        Specify language(s) used for OCR.\n"
		"  -c VAR=VALUE          Set value for config variables.\n"
		"                        Multiple -c arguments are allowed.\n"
		"  -psm NUM              Specify page segmentation mode.\n"
		"NOTE: These options must occur before any configfile.\n";

	printf("\n%s\n", ocr_options);
	PrintHelpForPSM();

	const char *single_options =
		"Single options:\n"
		"  -h, --help            Show this help message.\n"
		"  --help-psm            Show page segmentation modes.\n"
		"  -v, --version         Show version information.\n"
		"  --list-langs          List available languages for tesseract engine.\n"
		"  --print-parameters    Print tesseract parameters to stdout.\n";

	printf("\n%s", single_options);
}

void SetVariablesFromCLArgs(tesseract::TessBaseAPI* api, int argc, char** argv) {
	char opt1[256], opt2[255];
	for (int i = 0; i < argc; i++) {
		if (strcmp(argv[i], "-c") == 0 && i + 1 < argc) {
			strncpy(opt1, argv[i + 1], 255);
			opt1[255] = '\0';
			char *p = strchr(opt1, '=');
			if (!p) {
				fprintf(stderr, "Missing = in configvar assignment\n");
				exit(1);
			}
			*p = 0;
			strncpy(opt2, strchr(argv[i + 1], '=') + 1, 255);
			opt2[254] = 0;
			++i;

			if (!api->SetVariable(opt1, opt2)) {
				fprintf(stderr, "Could not set option: %s=%s\n", opt1, opt2);
			}
		}
	}
}

void PrintLangsList(tesseract::TessBaseAPI* api) {
	GenericVector<STRING> languages;
	api->GetAvailableLanguagesAsVector(&languages);
	printf("List of available languages (%d):\n", languages.size());
	for (int index = 0; index < languages.size(); ++index) {
		STRING& string = languages[index];
		printf("%s\n", string.string());
	}
	api->End();
}

void PrintBanner() {
	tprintf("Tesseract Open Source OCR Engine v%s with Leptonica\n",
		tesseract::TessBaseAPI::Version());
}

void FixPageSegMode(tesseract::TessBaseAPI* api,
	tesseract::PageSegMode pagesegmode) {
	if (api->GetPageSegMode() == tesseract::PSM_SINGLE_BLOCK)
		api->SetPageSegMode(pagesegmode);
}

// NOTE: arg_i is used here to avoid ugly *i so many times in this function
void ParseArgs(const int argc, char** argv,
	const char** lang,
	const char** image,
	const char** outputbase,
	const char** datapath,
	bool* list_langs,
	bool* print_parameters,
	GenericVector<STRING>* vars_vec,
	GenericVector<STRING>* vars_values,
	int* arg_i,
	tesseract::PageSegMode* pagesegmode) {
	if (argc == 1) {
		PrintHelpMessage(argv[0]);
		exit(0);
	}

	if (argc == 2) {
		if ((strcmp(argv[1], "-h") == 0) ||
			(strcmp(argv[1], "--help") == 0)) {
			PrintHelpMessage(argv[0]);
			exit(0);
		}
		if ((strcmp(argv[1], "--help-psm") == 0)) {
			PrintHelpForPSM();
			exit(0);
		}
		if ((strcmp(argv[1], "-v") == 0) ||
			(strcmp(argv[1], "--version") == 0)) {
			PrintVersionInfo();
			exit(0);
		}
	}

	bool noocr = false;
	int i = 1;
	while (i < argc && (*outputbase == NULL || argv[i][0] == '-')) {
		if (strcmp(argv[i], "-l") == 0 && i + 1 < argc) {
			*lang = argv[i + 1];
			++i;
		}
		else if (strcmp(argv[i], "--tessdata-dir") == 0 && i + 1 < argc) {
			*datapath = argv[i + 1];
			++i;
		}
		else if (strcmp(argv[i], "--user-words") == 0 && i + 1 < argc) {
			vars_vec->push_back("user_words_file");
			vars_values->push_back(argv[i + 1]);
			++i;
		}
		else if (strcmp(argv[i], "--user-patterns") == 0 && i + 1 < argc) {
			vars_vec->push_back("user_patterns_file");
			vars_values->push_back(argv[i + 1]);
			++i;
		}
		else if (strcmp(argv[i], "--list-langs") == 0) {
			noocr = true;
			*list_langs = true;
		}
		else if (strcmp(argv[i], "-psm") == 0 && i + 1 < argc) {
			*pagesegmode = static_cast<tesseract::PageSegMode>(atoi(argv[i + 1]));
			++i;
		}
		else if (strcmp(argv[i], "--print-parameters") == 0) {
			noocr = true;
			*print_parameters = true;
		}
		else if (strcmp(argv[i], "-c") == 0 && i + 1 < argc) {
			// handled properly after api init
			++i;
		}
		else if (*image == NULL) {
			*image = argv[i];
		}
		else if (*outputbase == NULL) {
			*outputbase = argv[i];
		}
		++i;
	}

	*arg_i = i;

	if (argc == 2 && strcmp(argv[1], "--list-langs") == 0) {
		*list_langs = true;
		noocr = true;
	}

	if (*outputbase == NULL && noocr == false) {
		PrintHelpMessage(argv[0]);
		exit(1);
	}
}

void PreloadRenderers(tesseract::TessBaseAPI* api,
	tesseract::PointerVector<tesseract::TessResultRenderer>* renderers,
	tesseract::PageSegMode pagesegmode,
	const char* outputbase) {
	if (pagesegmode == tesseract::PSM_OSD_ONLY) {
		renderers->push_back(new tesseract::TessOsdRenderer(outputbase));
	}
	else {
		bool b;
		api->GetBoolVariable("tessedit_create_hocr", &b);
		if (b) {
			bool font_info;
			api->GetBoolVariable("hocr_font_info", &font_info);
			renderers->push_back(
				new tesseract::TessHOcrRenderer(outputbase, font_info));
		}

		api->GetBoolVariable("tessedit_create_tsv", &b);
		if (b) {
			bool font_info;
			api->GetBoolVariable("hocr_font_info", &font_info);
			renderers->push_back(
				new tesseract::TessTsvRenderer(outputbase, font_info));
		}

		api->GetBoolVariable("tessedit_create_pdf", &b);
		if (b) {
			renderers->push_back(new tesseract::TessPDFRenderer(outputbase,
				api->GetDatapath()));
		}

		api->GetBoolVariable("tessedit_write_unlv", &b);
		if (b) {
			renderers->push_back(new tesseract::TessUnlvRenderer(outputbase));
		}

		api->GetBoolVariable("tessedit_create_boxfile", &b);
		if (b) {
			renderers->push_back(new tesseract::TessBoxTextRenderer(outputbase));
		}

		api->GetBoolVariable("tessedit_create_txt", &b);
		if (b || renderers->empty()) {
			renderers->push_back(new tesseract::TessTextRenderer(outputbase));
		}
	}

	if (!renderers->empty()) {
		// Since the PointerVector auto-deletes, null-out the renderers that are
		// added to the root, and leave the root in the vector.
		for (int r = 1; r < renderers->size(); ++r) {
			(*renderers)[0]->insert((*renderers)[r]);
			(*renderers)[r] = NULL;
		}
	}
}

int main(int argc, char **argv)
{
	const char* lang = "eng";
	const char* image = NULL;
	const char* outputbase = NULL;
	const char* datapath = NULL;
	bool list_langs = false;
	bool print_parameters = false;
	GenericVector<STRING> vars_vec, vars_values;
	int arg_i = 1;
	tesseract::PageSegMode pagesegmode = tesseract::PSM_AUTO;

	ParseArgs(argc, argv,
		&lang, &image, &outputbase, &datapath,
		&list_langs, &print_parameters,
		&vars_vec, &vars_values, &arg_i, &pagesegmode);

	bool banner = false;
	if (outputbase != NULL && strcmp(outputbase, "-") &&
		strcmp(outputbase, "stdout")) {
		banner = true;
	}

	PERF_COUNT_START("Tesseract:main")
		tesseract::TessBaseAPI api;

	api.SetOutputName(outputbase);

	int init_failed = api.Init(datapath, lang, tesseract::OEM_DEFAULT,
		&(argv[arg_i]), argc - arg_i, &vars_vec, &vars_values, false);
	if (init_failed) {
		fprintf(stderr, "Could not initialize tesseract.\n");
		exit(1);
	}

	SetVariablesFromCLArgs(&api, argc, argv);

	if (list_langs) {
		PrintLangsList(&api);
		exit(0);
	}

	if (print_parameters) {
		FILE* fout = stdout;
		fprintf(stdout, "Tesseract parameters:\n");
		api.PrintVariables(fout);
		api.End();
		exit(0);
	}

	FixPageSegMode(&api, pagesegmode);

	if (pagesegmode == tesseract::PSM_AUTO_ONLY) {
		int ret_val = 0;

		Pix* pixs = pixRead(image);
		if (!pixs) {
			fprintf(stderr, "Cannot open input file: %s\n", image);
			exit(2);
		}

		api.SetImage(pixs);

		tesseract::Orientation orientation;
		tesseract::WritingDirection direction;
		tesseract::TextlineOrder order;
		float deskew_angle;

		tesseract::PageIterator* it = api.AnalyseLayout();
		if (it) {
			it->Orientation(&orientation, &direction, &order, &deskew_angle);
			tprintf("Orientation: %d\nWritingDirection: %d\nTextlineOrder: %d\n" \
				"Deskew angle: %.4f\n",
				orientation, direction, order, deskew_angle);
		}
		else {
			ret_val = 1;
		}

		delete it;

		pixDestroy(&pixs);
		exit(ret_val);
	}

	// set in_training_mode to true when using one of these configs:
	// ambigs.train, box.train, box.train.stderr, linebox, rebox
	bool b = false;
	bool in_training_mode =
		(api.GetBoolVariable("tessedit_ambigs_training", &b) && b) ||
		(api.GetBoolVariable("tessedit_resegment_from_boxes", &b) && b) ||
		(api.GetBoolVariable("tessedit_make_boxes_from_boxes", &b) && b);

	tesseract::PointerVector<tesseract::TessResultRenderer> renderers;

	if (in_training_mode) {
		renderers.push_back(NULL);
	}
	else {
		PreloadRenderers(&api, &renderers, pagesegmode, outputbase);
	}

	if (!renderers.empty()) {
		if (banner) PrintBanner();
		bool succeed = api.ProcessPages(image, NULL, 0, renderers[0]);
		if (!succeed) {
			fprintf(stderr, "Error during processing.\n");
			exit(1);
		}
	}

	PERF_COUNT_END
	return 0;                      // Normal exit
}

GitHub: https://github.com/fengbingchun/Tesseract-OCR_Test

你可能感兴趣的:(Tesseract-OCR 3.04在Windows7 vs2013上编译过程)