mirror of
https://github.com/tesseract-ocr/tesseract.git
synced 2025-01-21 17:13:09 +08:00
Refactor microfeatures a bit.
This commit is contained in:
parent
47715e576a
commit
edfce72340
@ -51,14 +51,11 @@ FEATURE_SET ExtractMicros(TBLOB *Blob, const DENORM &cn_denorm) {
|
||||
|
||||
for (auto &f : features) {
|
||||
auto Feature = new FEATURE_STRUCT(&MicroFeatureDesc);
|
||||
Feature->Params[MFDirection] = f[ORIENTATION];
|
||||
Feature->Params[MFXPosition] = f[XPOSITION];
|
||||
Feature->Params[MFYPosition] = f[YPOSITION];
|
||||
Feature->Params[MFLength] = f[MFLENGTH];
|
||||
|
||||
// Bulge features are deprecated and should not be used. Set to 0.
|
||||
Feature->Params[MFBulge1] = 0.0f;
|
||||
Feature->Params[MFBulge2] = 0.0f;
|
||||
for (int i = 0; i < (int)MicroFeatureParameter::MFCount; ++i)
|
||||
Feature->Params[i] = f[i];
|
||||
// Bulge features are deprecated and should not be used. Set to 0.
|
||||
Feature->Params[(int)MicroFeatureParameter::MFBulge1] = 0.0f;
|
||||
Feature->Params[(int)MicroFeatureParameter::MFBulge2] = 0.0f;
|
||||
|
||||
#ifndef _WIN32
|
||||
// Assert that feature parameters are well defined.
|
||||
|
@ -23,20 +23,6 @@
|
||||
|
||||
namespace tesseract {
|
||||
|
||||
typedef enum {
|
||||
MFXPosition,
|
||||
MFYPosition,
|
||||
MFLength,
|
||||
MFDirection,
|
||||
MFBulge1,
|
||||
MFBulge2,
|
||||
MFCount // For array sizes.
|
||||
} MF_PARAM_NAME;
|
||||
|
||||
typedef float MicroFeature[MFCount];
|
||||
/*----------------------------------------------------------------------------
|
||||
Private Function Prototypes
|
||||
-----------------------------------------------------------------------------*/
|
||||
FEATURE_SET ExtractMicros(TBLOB *Blob, const DENORM &cn_denorm);
|
||||
|
||||
} // namespace tesseract
|
||||
|
@ -18,29 +18,24 @@
|
||||
#ifndef MFDEFS_H
|
||||
#define MFDEFS_H
|
||||
|
||||
/**----------------------------------------------------------------------------
|
||||
Include Files and Type Defines
|
||||
----------------------------------------------------------------------------**/
|
||||
#include "matchdefs.h"
|
||||
#include "oldlist.h"
|
||||
|
||||
#include <array>
|
||||
#include <forward_list>
|
||||
|
||||
namespace tesseract {
|
||||
|
||||
/* definition of a list of micro-features */
|
||||
using MICROFEATURE = float;
|
||||
using MFBLOCK = std::array<MICROFEATURE, 6>;
|
||||
using MICROFEATURES = std::forward_list<MFBLOCK>;
|
||||
enum class MicroFeatureParameter {
|
||||
MFXPosition,
|
||||
MFYPosition,
|
||||
MFLength,
|
||||
MFDirection,
|
||||
MFBulge1,
|
||||
MFBulge2,
|
||||
|
||||
/* definitions of individual micro-feature parameters */
|
||||
#define XPOSITION 0
|
||||
#define YPOSITION 1
|
||||
#define MFLENGTH 2
|
||||
#define ORIENTATION 3
|
||||
#define FIRSTBULGE 4
|
||||
#define SECONDBULGE 5
|
||||
MFCount // For array sizes.
|
||||
};
|
||||
|
||||
using MicroFeature = std::array<float, (int)MicroFeatureParameter::MFCount>;
|
||||
using MICROFEATURES = std::forward_list<MicroFeature>;
|
||||
|
||||
} // namespace tesseract
|
||||
|
||||
|
@ -36,7 +36,7 @@ double_VAR(classify_max_slope, 2.414213562, "Slope above which lines are called
|
||||
|
||||
MICROFEATURES ConvertToMicroFeatures(MFOUTLINE Outline, MICROFEATURES MicroFeatures);
|
||||
|
||||
MFBLOCK ExtractMicroFeature(MFOUTLINE Start, MFOUTLINE End);
|
||||
MicroFeature ExtractMicroFeature(MFOUTLINE Start, MFOUTLINE End);
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
Public Code
|
||||
@ -125,19 +125,19 @@ MICROFEATURES ConvertToMicroFeatures(MFOUTLINE Outline, MICROFEATURES MicroFeatu
|
||||
* @return New micro-feature or nullptr if the feature was rejected.
|
||||
* @note Globals: none
|
||||
*/
|
||||
MFBLOCK ExtractMicroFeature(MFOUTLINE Start, MFOUTLINE End) {
|
||||
MicroFeature ExtractMicroFeature(MFOUTLINE Start, MFOUTLINE End) {
|
||||
MFEDGEPT *P1, *P2;
|
||||
|
||||
P1 = PointAt(Start);
|
||||
P2 = PointAt(End);
|
||||
|
||||
MFBLOCK NewFeature;
|
||||
NewFeature[XPOSITION] = AverageOf(P1->Point.x, P2->Point.x);
|
||||
NewFeature[YPOSITION] = AverageOf(P1->Point.y, P2->Point.y);
|
||||
NewFeature[MFLENGTH] = DistanceBetween(P1->Point, P2->Point);
|
||||
NewFeature[ORIENTATION] = NormalizedAngleFrom(&P1->Point, &P2->Point, 1.0);
|
||||
NewFeature[FIRSTBULGE] = 0.0f; // deprecated
|
||||
NewFeature[SECONDBULGE] = 0.0f; // deprecated
|
||||
MicroFeature NewFeature;
|
||||
NewFeature[(int)MicroFeatureParameter::MFXPosition] = AverageOf(P1->Point.x, P2->Point.x);
|
||||
NewFeature[(int)MicroFeatureParameter::MFYPosition] = AverageOf(P1->Point.y, P2->Point.y);
|
||||
NewFeature[(int)MicroFeatureParameter::MFLength] = DistanceBetween(P1->Point, P2->Point);
|
||||
NewFeature[(int)MicroFeatureParameter::MFDirection] = NormalizedAngleFrom(&P1->Point, &P2->Point, 1.0);
|
||||
NewFeature[(int)MicroFeatureParameter::MFBulge1] = 0.0f; // deprecated
|
||||
NewFeature[(int)MicroFeatureParameter::MFBulge2] = 0.0f; // deprecated
|
||||
|
||||
return NewFeature;
|
||||
} /* ExtractMicroFeature */
|
||||
|
@ -263,7 +263,7 @@ void TrainingSample::ExtractCharDesc(int int_feature_type, int micro_type, int c
|
||||
num_micro_features_ = char_features->NumFeatures;
|
||||
micro_features_ = new MicroFeature[num_micro_features_];
|
||||
for (uint32_t f = 0; f < num_micro_features_; ++f) {
|
||||
for (int d = 0; d < MFCount; ++d) {
|
||||
for (int d = 0; d < (int)MicroFeatureParameter::MFCount; ++d) {
|
||||
micro_features_[f][d] = char_features->Features[f]->Params[d];
|
||||
}
|
||||
}
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include "intmatcher.h"
|
||||
#include "matrix.h"
|
||||
#include "mf.h"
|
||||
#include "mfdefs.h"
|
||||
#include "picofeat.h"
|
||||
#include "shapetable.h"
|
||||
#include "unicharset.h"
|
||||
|
@ -576,7 +576,7 @@ CLUSTERER *MasterTrainer::SetupForClustering(const ShapeTable &shape_table,
|
||||
int *num_samples) {
|
||||
int desc_index = ShortNameToFeatureType(feature_defs, kMicroFeatureType);
|
||||
int num_params = feature_defs.FeatureDesc[desc_index]->NumParams;
|
||||
ASSERT_HOST(num_params == MFCount);
|
||||
ASSERT_HOST(num_params == (int)MicroFeatureParameter::MFCount);
|
||||
CLUSTERER *clusterer = MakeClusterer(num_params, feature_defs.FeatureDesc[desc_index]->ParamDesc);
|
||||
|
||||
// We want to iterate over the samples of just the one shape.
|
||||
@ -596,7 +596,7 @@ CLUSTERER *MasterTrainer::SetupForClustering(const ShapeTable &shape_table,
|
||||
const TrainingSample *sample = sample_ptrs[i];
|
||||
uint32_t num_features = sample->num_micro_features();
|
||||
for (uint32_t f = 0; f < num_features; ++f) {
|
||||
MakeSample(clusterer, sample->micro_features()[f], sample_id);
|
||||
MakeSample(clusterer, sample->micro_features()[f].data(), sample_id);
|
||||
}
|
||||
++sample_id;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user