jfloat Java_com_googlecode_tesseract_android_ResultIterator_nativeConfidence(JNIEnv *env, jclass clazz, jlong nativeResultIterator, jint level) { ResultIterator *resultIterator = (ResultIterator *) nativeResultIterator; PageIteratorLevel enumLevel = (PageIteratorLevel) level; return (jfloat) resultIterator->Confidence(enumLevel); }
void OCRer::OCR(Mat img) { cv::waitKey(100); _tessapi->SetImage((const unsigned char*) img.data, img.cols,img.rows, img.channels(), img.step); _tessapi->Recognize(NULL); ResultIterator *ri = _tessapi->GetIterator(); //return _tessapi->GetUTF8Text(); if (ri != NULL) { all_text= ""; while (ri->Next(RIL_TEXTLINE)) { all_text += ri->GetUTF8Text(RIL_TEXTLINE); } delete ri; } };
jstring Java_com_googlecode_tesseract_android_ResultIterator_nativeGetUTF8Text(JNIEnv *env, jclass clazz, jlong nativeResultIterator, jint level) { ResultIterator *resultIterator = (ResultIterator *) nativeResultIterator; PageIteratorLevel enumLevel = (PageIteratorLevel) level; char *text = resultIterator->GetUTF8Text(enumLevel); jstring result = env->NewStringUTF(text); free(text); return result; }
// @param img: grayscaled and in RGB format (e.g. loaded from file). void OCRer::process_image(Mat img) { if (_motion) { _n_imgs = 0; _motion = false; } if (_n_imgs == 0) { _average_img = img; } else { // detect motion by comparing with _last_img vector<uchar> status; vector<float> err; calcImageDisplacement(_last_img, img, &status, &err); int n = 0; int l = status.size(); for (int i = 0; i < l; i++) { bool matched = (bool) status[i]; if (matched) { n++; } } float fn = (float) n; float fnl = (float) _last_n_features; float p_motion = fabs( (fn - fnl) / fnl ); // "percentage" of motion _last_n_features = n; if (p_motion > MOTION_P_THRESHOLD) _motion = true; else if (_n_imgs < MAX_N_IMGS) { float alpha = 1.0f / (float) (_n_imgs + 1); Mat sum = Mat::zeros(img.size(), CV_32F); // has to be CV_32F or CV_64F accumulate(img, sum); accumulate(_average_img, sum); sum.convertTo(_average_img, _average_img.type(), alpha); } else { return ; } } _last_img = img; _n_imgs++; _tessapi->SetImage((const unsigned char*) _average_img.data, _average_img.cols, _average_img.rows, _average_img.channels(), _average_img.step); _tessapi->Recognize(NULL); ResultIterator *ri = _tessapi->GetIterator(); /* ChoiceIterator* ci; if (ri != NULL) { while ((ri->Next(RIL_SYMBOL))) { const char* symbol = ri->GetUTF8Text(RIL_SYMBOL); if (symbol != 0) { float conf = ri->Confidence(RIL_SYMBOL); std::cout << "\tnext symbol: " << symbol << "\tconf: " << conf << endl; const ResultIterator itr = *ri; ci = new ChoiceIterator(itr); do { std::cout << "\t\t" << ci->GetUTF8Text() << " conf: " << ci->Confidence() << endl; } while(ci->Next()); delete ci; } delete[] symbol; } } */ if (ri != NULL) { // int l, t, r, b; while (ri->Next(RIL_WORD)) { // ri->BoundingBox(RIL_WORD, &l, &t, &r, &b); // cout << "rect = " << l << ", " << r << ", " << t << ", " << b << endl; char *ocr_text = ri->GetUTF8Text(RIL_WORD); if (heuristic(ocr_text)) { if (ri->WordIsFromDictionary()) { _dict_words.insert(string(ocr_text)); // cout << "conf = " << ri->Confidence(RIL_WORD) << endl; } else { _live_words.insert(string(ocr_text)); } } delete[] ocr_text; } delete ri; } }
const std::vector<uint8_t> OneNN::train(std::set<FeatureDesc> feature_descs, std::set<ParameterDesc>, std::set<std::string>, ResultIterator result_iter) const { // Read all of the results data in one go. For each distinct set of input // features, store the best set of results. This is achieved by storing a // hash from a feature set to its current best result. MAGEEC_DEBUG("Collecting results"); std::map<uint64_t, Result> result_map; for (util::Option<Result> result; (result = *result_iter); result_iter = result_iter.next()) { FeatureSet features = result.get().getFeatures(); double value = result.get().getValue(); uint64_t hash = features.hash(); bool result_handled = false; while (!result_handled) { auto curr_entry = result_map.find(hash); if (curr_entry != result_map.end()) { const FeatureSet &curr_features = curr_entry->second.getFeatures(); double curr_value = curr_entry->second.getValue(); if (features == curr_features) { if (value < curr_value) { result_map.at(hash) = result.get(); } result_handled = true; } else { hash++; } } else { result_map.emplace(hash, result.get()); result_handled = true; } } } std::map<unsigned, FeatureType> feature_type; std::map<unsigned, std::pair<double, double>> feature_max_min; std::vector<OneNN::Point> feature_points; // Get all of the feature ids and their types for (auto desc : feature_descs) { // Only integer and boolean feature types are allowed at the moment if (desc.type == FeatureType::kBool || desc.type == FeatureType::kInt) { feature_type[desc.id] = desc.type; } } // Find the max and min of each feature for (auto res : result_map) { FeatureSet features = res.second.getFeatures(); for (auto f : features) { assert(feature_type.count(f->getID())); assert(feature_type[f->getID()] == f->getType()); switch (f->getType()) { case FeatureType::kBool: { if (feature_max_min.count(f->getID()) == 0) feature_max_min[f->getID()] = std::make_pair<double, double>(1.0, 0.0); } case FeatureType::kInt: { int64_t value = static_cast<IntFeature *>(f.get())->getValue(); double double_value = static_cast<double>(value); if (feature_max_min.count(f->getID()) == 0) { feature_max_min[f->getID()] = std::pair<double, double>(double_value, double_value); } else { auto &entry = feature_max_min[f->getID()]; if (double_value < entry.first) entry.first = double_value; if (double_value > entry.second) entry.second = double_value; } } } } } // Add a point for each feature set, normalize the features in the process to // the range [0, 1] for (auto res : result_map) { ParameterSet parameters = res.second.getParameters(); FeatureSet features = res.second.getFeatures(); OneNN::Point point; for (auto f : features) { assert(feature_type[f->getID()] == f->getType()); switch (f->getType()) { case FeatureType::kBool: { bool value = static_cast<BoolFeature *>(f.get())->getValue(); point.features[f->getID()] = value ? 1.0 : 0.0; break; } case FeatureType::kInt: { int64_t value = static_cast<IntFeature *>(f.get())->getValue(); double double_value = static_cast<double>(value); double max = feature_max_min[f->getID()].first; double min = feature_max_min[f->getID()].second; if ((max - min) != 0.0) double_value = (double_value - min) / (max - min); else double_value = 0.0; point.features[f->getID()] = double_value; break; } } } for (auto p : parameters) { switch(p->getType()) { case ParameterType::kBool: { bool value = static_cast<BoolParameter*>(p.get())->getValue(); point.parameters[p->getID()] = value; break; } case ParameterType::kRange: { int64_t value = static_cast<RangeParameter*>(p.get())->getValue(); point.parameters[p->getID()] = value; break; } default: assert(0 && "Unhandled parameter type"); break; } } feature_points.push_back(point); } // Serialize to a blob // Buffer used to store the training blob std::vector<uint8_t> blob; // Emit the number of features, followed by the feature ids, and the // min and max ranges for each feature // | 16 | 16 | 64 | 64 |... // |NumFeatures|FeatID| max | min |... util::write16LE(blob, feature_max_min.size()); for (auto feat_max_min : feature_max_min) { util::write16LE(blob, feat_max_min.first); // FIXME: Make this safe and portable util::write64LE(blob, *reinterpret_cast<uint64_t*>(&feat_max_min.second.first)); util::write64LE(blob, *reinterpret_cast<uint64_t*>(&feat_max_min.second.second)); } // Emit the number of feature points, followed by each feature point in // turn. // | 16 | ?? | ?? | // |NumPoints|FeaturePoint|FeaturePoint|... util::write16LE(blob, feature_points.size()); for (auto point : feature_points) { // Emit each feature point. This consists of each feature value in turn, // followed by each parameter in turn // | 16 | 16 | 64 |...| 16 | 16 | 64 |... // |NumFeatures|FeatID|value|...|NumParameters|ParamID|value|... util::write16LE(blob, point.features.size()); for (auto feature : point.features) { util::write16LE(blob, feature.first); // FIXME: Make this safe and portable util::write64LE(blob, *reinterpret_cast<uint64_t*>(&feature.second)); } util::write16LE(blob, point.parameters.size()); for (auto parameter : point.parameters) { util::write16LE(blob, parameter.first); util::write64LE(blob, *reinterpret_cast<uint64_t*>(¶meter.second)); } } return blob; }