Refactor microfeatures a bit.

This commit is contained in:
Egor Pugin 2021-04-07 17:29:46 +03:00
parent 47715e576a
commit edfce72340
7 changed files with 30 additions and 51 deletions

View File

@ -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.

View File

@ -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

View File

@ -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

View File

@ -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 */

View File

@ -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];
}
}

View File

@ -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"

View File

@ -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;
}