TessBaseAPI::Clear() 的语义

The semantics of TessBaseAPI::Clear()

假设我创建了 TessBaseAPI 的两个对象 — xapiyapi — 通过调用 Init() 函数的以下重载来初始化:

int Init(const char * datapath,
         const char * language,
         OcrEngineMode  oem,
         char **    configs,
         int    configs_size,
         const GenericVector< STRING > *    vars_vec,
         const GenericVector< STRING > *    vars_values,
         bool   set_only_non_debug_params 
);

传递完全相同的参数。

由于对象是用相同的参数初始化的,此时 xapiyapi 被假定为从行为1 的角度来看是相同的。我的假设正确吗?我希望如此,因为我没有找到任何对象不相同的原因。


现在我要使用 xapi 从图像中提取信息,但在此之前我多次调用 SetVariable() 以设置更多配置。

bool SetVariable(const char * name, const char * value);

然后我使用 xapi 从图像中提取一些文本。完成提取后,我这样做了:

 xapi.Clear(); //what exactly happens here?

调用Clear()后,我可以交替使用xapiyapi吗?换句话说,我可以假设 xapiyapi 从行为 1 的角度来看此时是相同的吗?我可以说 Clear() 实际上是 reset 功能吗?

1. "behavioral",我指的是准确性方面的性能,而不是 speed/latency。

根据void tesseract::TessBaseAPI::Clear() documentation,调用此函数将释放图像数据和识别结果。它没有说明配置数据。此外,如果作者认为加载配置数据很耗时,它将保持原样:without actually freeing any recognition data that would be time-consuming to reload.

正在回答您的其他问题:

  1. "After the call to Clear(), can I use xapi and yapi interchangeably?" -- 是的,你可以,但结果可能会因为你通过 SetVariable() 应用到 xapi 的不同设置而有所不同,而不是 yapi.

  2. "In other words, can I assume that xapi and yapi are identical at this point from behavioral1 perspective?" -- 根据您使用 SetVariable() 更改的设置,结果可能相同也可能不同。

  3. "Can I say Clear() is actually a reset functionality?" -- 只丢弃识别结果和图像数据,其他保持不变。看你对reset的定义,你可以叫它重置也可以不叫它,毕竟它是一个自由的国家=)

您可以检查Clear() and the full teardown using End(). It's around line 1400 of baseapi.cpp.

之间的区别

Since the objects are initialized with identical arguments, at this point xapi and yapi are assumed to be identical from behavioral perspective. Is my assumption correct?

从一开始我就找不到任何可以反驳这个假设的东西。

调查源代码。

以下参数被清除或重置(如果您愿意):

调用 Clear() 时会调用以下内容:

01402 void TessBaseAPI::Clear() {
01403   if (thresholder_ != NULL)
01404     thresholder_->Clear();
01405   ClearResults();
01406 }

调用 thresholder_->Clear(); 破坏像素(如果不为空)

00044 // Destroy the Pix if there is one, freeing memory.
00045 void ImageThresholder::Clear() {
00046   if (pix_ != NULL) {
00047     pixDestroy(&pix_);
00048     pix_ = NULL;
00049   }
00050   image_data_ = NULL;
00051 }

Clear Results,如下图

01641 void TessBaseAPI::ClearResults() {
01642   if (tesseract_ != NULL) {
01643     tesseract_->Clear();
01644   }
01645   if (page_res_ != NULL) {
01646     delete page_res_;
01647     page_res_ = NULL;
01648   }
01649   recognition_done_ = false;
01650   if (block_list_ == NULL)
01651     block_list_ = new BLOCK_LIST;
01652   else
01653     block_list_->clear();
01654   if (paragraph_models_ != NULL) {
01655     paragraph_models_->delete_data_pointers();
01656     delete paragraph_models_;
01657     paragraph_models_ = NULL;
01658   }
01659 }

页面结果、阻止列表设置为空,相关标志也被重置。

tesseract_->Clear() 发布以下内容:

00413 void Tesseract::Clear() {
00414   pixDestroy(&pix_binary_);
00415   pixDestroy(&cube_binary_);
00416   pixDestroy(&pix_grey_);
00417   pixDestroy(&scaled_color_);
00418   deskew_ = FCOORD(1.0f, 0.0f);
00419   reskew_ = FCOORD(1.0f, 0.0f);
00420   splitter_.Clear();
00421   scaled_factor_ = -1;
00422   ResetFeaturesHaveBeenExtracted();
00423   for (int i = 0; i < sub_langs_.size(); ++i)
00424     sub_langs_[i]->Clear();
00425 }

值得注意的是, SetVariable 不影响初始值:

Only works for non-init variables (init variables should be passed to Init()).

00143 bool TessBaseAPI::SetVariable(const char* name, const char* value) {
00144   if (tesseract_ == NULL) tesseract_ = new Tesseract;
00145   return ParamUtils::SetParam(name, value, SET_PARAM_CONSTRAINT_NON_INIT_ONLY,
00146                               tesseract_->params());
00147 }

After the call to Clear(), can I use xapi and yapi interchangeably?

没有。如果您使用阈值器,当然不会。

Can I say Clear() is actually a reset functionality?

不是在将其恢复到初始状态的意义上。它会将原始对象的某些值更改为 null。它将保留 const char * datapath, const char * language, OcrEngineMode oem, 等参数的繁重工作。这似乎是一种在不删除对象的情况下释放内存的方法。 Inline with "without actually freeing any recognition data that would be time-consuming to reload.".

在调用 Clear() 之后调用 SetImage or TesseractRect,然后再使用 Recognition 或 Get* 函数。

Clear 不会处理 SetVariables,它们只会在通过调用 End() 销毁对象时重置为默认值。

查看 TessbaseApi() class,您可以看到正在初始化的内容以及这些值中的哪些值将使用 Clear() 重置。

00091 TessBaseAPI::TessBaseAPI()
00092   : tesseract_(NULL),
00093     osd_tesseract_(NULL),
00094     equ_detect_(NULL),
00095     // Thresholder is initialized to NULL here, but will be set before use by:
00096     // A constructor of a derived API,  SetThresholder(), or
00097     // created implicitly when used in InternalSetImage.
00098     thresholder_(NULL),
00099     paragraph_models_(NULL),
00100     block_list_(NULL),
00101     page_res_(NULL),
00102     input_file_(NULL),
00103     output_file_(NULL),
00104     datapath_(NULL),
00105     language_(NULL),
00106     last_oem_requested_(OEM_DEFAULT),
00107     recognition_done_(false),
00108     truth_cb_(NULL),
00109     rect_left_(0), rect_top_(0), rect_width_(0), rect_height_(0),
00110     image_width_(0), image_height_(0) {
00111 }

鉴于 class 的基本构造函数是:

(datapath, language, OEM_DEFAULT, NULL, 0, NULL, NULL, false);

这三个参数总是需要的,即makes sense.

If the datapath, OcrEngineMode or the language have changed - start again.
Note that the language_ field stores the last requested language that was initialized successfully, while tesseract_->lang stores the language actually used. They differ only if the requested language was NULL, in which case tesseract_->lang is set to the Tesseract default ("eng").