#include <vector>
#include <map>
#include <algorithm>
#include <utility>
#include <prodmark/prodmark_integrator.h>
#include "postprocessing.h"
// FIXME: MAKE THIS FILE READABLE
namespace prodmark {
Integrator::Integrator() {
// empty body
}
Integrator::~Integrator() {
// empty body
}
int Integrator::Reset() {
variants_.variants.clear();
best_result_cnt = 0;
max_confidence_of_place.clear();
max_confidence_of_row.clear();
max_confidence_of_serial.clear();
if (variants_.variants.size() | max_confidence_of_place.size() |
max_confidence_of_row.size() | max_confidence_of_serial.size() <= 0)
return NO_ERRORS;
return NO_SENSE;
}
int ComputeAverageConfidenceOfSerial (std::vector<DocumentZoneRecognitionResult>& result,
std::pair< std::vector<DocumentZoneRecognitionResult>, int>& cur_best_result) {
for (size_t i = 0; i < result.size(); ++i) {
for (size_t j = 0; j < result[i].serial_.cells.size(); ++j) {
result[i].serial_.cells[j].SortVariantsByCharacter();
cur_best_result.first[i].serial_.cells[j].SortVariantsByCharacter();
}
}
for (size_t i = 0; i < result.size(); ++i) {
for (size_t j = 0; j < result[i].serial_.cells.size(); ++j) {
for (size_t k = 0; k < result[i].serial_.cells[j].GetVariantCount(); ++k) {
cur_best_result.first[i].serial_.cells[j].GetVariant(k).confidence = (cur_best_result.first[i].serial_.cells[j].GetVariant(k).confidence *
cur_best_result.second +
result[i].serial_.cells[j].GetVariant(k).confidence) /
(cur_best_result.second + 1);
}
}
}
return NO_ERRORS;
}
int ComputeAverageConfidenceOfRow (DocumentZoneRecognitionResult& result,
DocumentZoneRecognitionResult& cur_best_result,
int s) {
for (size_t i = 0; i < result.row_.cells.size(); ++i) {
result.row_.cells[i].SortVariantsByCharacter();
cur_best_result.row_.cells[i].SortVariantsByCharacter();
}
for (size_t i = 0; i < result.row_.cells.size(); ++i) {
for (size_t j = 0; j < result.row_.cells[i].GetVariantCount(); ++j) {
cur_best_result.row_.cells[i].GetVariant(j).confidence = (cur_best_result.row_.cells[i].GetVariant(j).confidence * s +
result.row_.cells[i].GetVariant(j).confidence) / (s + 1);
}
}
return NO_ERRORS;
}
int ComputeAverageConfidenceOfPlace (DocumentZoneRecognitionResult& result,
DocumentZoneRecognitionResult& cur_best_result,
int s) {
for (size_t i = 0; i < result.place_.cells.size(); ++i) {
result.place_.cells[i].SortVariantsByCharacter();
cur_best_result.place_.cells[i].SortVariantsByCharacter();
}
for (size_t i = 0; i < result.place_.cells.size(); ++i) {
for (size_t j = 0; j < result.place_.cells[i].GetVariantCount(); ++j) {
cur_best_result.place_.cells[i].GetVariant(j).confidence = (cur_best_result.place_.cells[i].GetVariant(j).confidence * s +
result.place_.cells[i].GetVariant(j).confidence) / (s + 1);
}
}
return NO_ERRORS;
}
double GetMaxConfidence (RecognitionResult& result) {
double max_confidence = 0;
for (size_t i = 0; i < result.cells.size(); ++i) {
result.cells[i].SortVariantsByConfidence();
max_confidence += result.cells[i].GetVariant(0).confidence - result.cells[i].GetVariant(1).confidence;
}
max_confidence /= result.cells.size();
return max_confidence;
}
bool ComputeBestResult (std::pair<std::string, int>& best_result_,
const std:: string& type,
int& subtype_,
std::map<std::string, std::vector<std::vector <double> > >& max_confidence_of_row,
std::map<std::string, std::vector<std::vector <double> > >& max_confidence_of_place,
std::map<std::string, std::vector<std::vector <double> > >& max_confidence_of_serial,
ProdmarkIntegratorRecognitionVariants& variants_) {
double compare_result_1 = 0, compare_result_2 = 0;
for (size_t i = 0; i < variants_.variants[type].variant[subtype_].first.size(); ++i) {
compare_result_1 += max_confidence_of_row[type][subtype_][i] +
max_confidence_of_place[type][subtype_][i] +
max_confidence_of_serial[type][subtype_][i];
}
compare_result_1 /= variants_.variants[type].variant[subtype_].first.size();
for (size_t i = 0; i < variants_.variants[best_result_.first].variant[best_result_.second].first.size(); ++i) {
compare_result_2 += max_confidence_of_row[best_result_.first][best_result_.second][i] +
max_confidence_of_place[best_result_.first][best_result_.second][i] +
max_confidence_of_serial[best_result_.first][best_result_.second][i];
}
compare_result_2 /= variants_.variants[best_result_.first].variant[best_result_.second].first.size();
return compare_result_1 > compare_result_2;
}
int Integrator::AddResult(const std::string& type,
const std::string& subtype,
std::vector<DocumentZoneRecognitionResult>& result,
bool& may_finish,
const EngineSettings& set) {
if (type == "TAG_N") {
return NO_ERRORS;
}
if (variants_.variants.size() == 0) {
best_result_cnt = 0;
}
int subtype_ = result.size() - 1;
if (variants_.variants[type].variant.size() == 0) {
for (size_t i = 0; i < ((type == "TAG_R") ? (subtype_ + 1) : 1); ++i) {
variants_.variants[type].variant.push_back(make_pair(std::vector<DocumentZoneRecognitionResult>(i + 1), 0));
}
variants_.variants[type].variant[subtype_].first = result;
max_confidence_of_row[type].resize((type == "TAG_R") ? (subtype_ + 1) : 1);
max_confidence_of_row[type][subtype_].resize(result.size());
max_confidence_of_place[type].resize((type == "TAG_R") ? (subtype_ + 1) : 1);
max_confidence_of_place[type][subtype_].resize(result.size());
max_confidence_of_serial[type].resize((type == "TAG_R") ? (subtype_ + 1) : 1);
max_confidence_of_serial[type][subtype_].resize(result.size());
for (size_t i = 0; i < result.size(); ++i) {
max_confidence_of_row[type][subtype_][i] = GetMaxConfidence(result[i].row_);
max_confidence_of_place[type][subtype_][i] = GetMaxConfidence(result[i].place_);
max_confidence_of_serial[type][subtype_][i] = GetMaxConfidence(result[i].serial_);
}
variants_.variants[type].variant[subtype_].second++;
} else {
if (variants_.variants[type].variant.size() <= subtype_) {
for (size_t i = variants_.variants[type].variant.size(); i <= subtype_; ++i) {
variants_.variants[type].variant.push_back(make_pair(std::vector<DocumentZoneRecognitionResult>(i + 1), 0));
}
}
if (variants_.variants[type].variant[subtype_].second == 0) {
variants_.variants[type].variant[subtype_].first = result;
if (max_confidence_of_row[type].size() <= subtype_) {
max_confidence_of_row[type].resize((type == "TAG_R") ? (subtype_ + 1) : 1);
max_confidence_of_place[type].resize((type == "TAG_R") ? (subtype_ + 1) : 1);
max_confidence_of_serial[type].resize((type == "TAG_R") ? (subtype_ + 1) : 1);
}
max_confidence_of_row[type][subtype_].resize(result.size());
max_confidence_of_place[type][subtype_].resize(result.size());
max_confidence_of_serial[type][subtype_].resize(result.size());
for (size_t i = 0; i < result.size(); ++i) {
max_confidence_of_row[type][subtype_][i] = GetMaxConfidence(result[i].row_);
max_confidence_of_place[type][subtype_][i] = GetMaxConfidence(result[i].place_);
max_confidence_of_serial[type][subtype_][i] = GetMaxConfidence(result[i].serial_);
}
variants_.variants[type].variant[subtype_].second++;
} else {
PROPAGATE_ERROR(ComputeAverageConfidenceOfSerial(result,
variants_.variants[type].variant[subtype_]));
for (size_t i = 0; i < result.size(); ++i) {
for (size_t j = 0; j < result[i].serial_.cells.size(); ++j) {
variants_.variants[type].variant[subtype_].first[i].serial_.cells[j].SortVariantsByConfidence();
}
}
for (size_t i = 0; i < result.size(); ++i) {
if (variants_.variants[type].variant[subtype_].first[i].row_.cells.size() == result[i].row_.cells.size()) {
max_confidence_of_row[type][subtype_][i] = std::max (max_confidence_of_row[type][subtype_][i],
GetMaxConfidence(result[i].row_));
PROPAGATE_ERROR(ComputeAverageConfidenceOfRow(result[i],
variants_.variants[type].variant[subtype_].first[i],
variants_.variants[type].variant[subtype_].second));
for (size_t j = 0; j < result[i].row_.cells.size(); ++j) {
variants_.variants[type].variant[subtype_].first[i].row_.cells[j].SortVariantsByConfidence();
}
} else if (max_confidence_of_row[type][subtype_][i] < GetMaxConfidence(result[i].row_)) {
max_confidence_of_row[type][subtype_][i] = GetMaxConfidence(result[i].row_);
variants_.variants[type].variant[subtype_].first[i].row_ = result[i].row_;
}
}
for (size_t i = 0; i < result.size(); ++i) {
if (variants_.variants[type].variant[subtype_].first[i].place_.cells.size() == result[i].place_.cells.size()) {
max_confidence_of_place[type][subtype_][i] = std::max (max_confidence_of_place[type][subtype_][i],
GetMaxConfidence(result[i].place_));
PROPAGATE_ERROR(ComputeAverageConfidenceOfPlace(result[i],
variants_.variants[type].variant[subtype_].first[i],
variants_.variants[type].variant[subtype_].second));
for (size_t j = 0; j < result[i].place_.cells.size(); ++j) {
variants_.variants[type].variant[subtype_].first[i].place_.cells[j].SortVariantsByConfidence();
}
} else if (max_confidence_of_place[type][subtype_][i] < GetMaxConfidence(result[i].place_)) {
max_confidence_of_place[type][subtype_][i] = GetMaxConfidence(result[i].place_);
variants_.variants[type].variant[subtype_].first[i].place_ = result[i].place_;
}
}
for (size_t i = 0; i < result.size(); ++i) {
if (max_confidence_of_serial[type][subtype_][i] < GetMaxConfidence(result[i].serial_)) {
max_confidence_of_serial[type][subtype_][i] = GetMaxConfidence(result[i].serial_);
}
}
variants_.variants[type].variant[subtype_].second++;
}
}
if (best_result_cnt == variants_.variants[type].variant[subtype_].second) {
if (ComputeBestResult(best_result_,
type,
subtype_,
max_confidence_of_row,
max_confidence_of_place,
max_confidence_of_serial,
variants_)) {
best_result_.first = type;
best_result_.second = subtype_;
}
if (best_result_cnt >= set.integ_good_result) {
may_finish = true;
}
} else if (best_result_cnt < variants_.variants[type].variant[subtype_].second) {
best_result_.first = type;
best_result_.second = subtype_;
best_result_cnt = variants_.variants[type].variant[subtype_].second;
if (best_result_cnt >= set.integ_good_result) {
may_finish = true;
}
}
return NO_ERRORS;
}
int Integrator::GetIntegratedResult(Result& result) {
if (variants_.variants.size() <= 0) {
result.SetType("TAG_N");
result.SetSubtype("1");
return NO_ERRORS;
}
std::vector<DocumentZone> document_zones;
PROPAGATE_ERROR(DocumentZonePostprocessing(result,
document_zones,
variants_.variants[best_result_.first].variant[best_result_.second].first));
return NO_ERRORS;
}
const std::string& Integrator::GetType() const {
return best_result_.first;
}
const std::string& Integrator::GetSubType() const {
return best_result_.second > 0 ? "2" : "1";
}
} // namespace prodmark