first commit
Some checks are pending
Build/Publish Develop Docs / deploy (push) Waiting to run

This commit is contained in:
2025-07-02 08:57:16 +03:00
commit 56532cc9a9
1901 changed files with 457695 additions and 0 deletions

View File

@@ -0,0 +1,68 @@
// Copyright (c) 2020 PaddlePaddle Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#include <gflags/gflags.h>
// common args
DECLARE_bool(use_gpu);
DECLARE_bool(use_tensorrt);
DECLARE_int32(gpu_id);
DECLARE_int32(gpu_mem);
DECLARE_int32(cpu_threads);
DECLARE_bool(enable_mkldnn);
DECLARE_string(precision);
DECLARE_bool(benchmark);
DECLARE_string(output);
DECLARE_string(image_dir);
DECLARE_string(type);
// detection related
DECLARE_string(det_model_dir);
DECLARE_string(limit_type);
DECLARE_int32(limit_side_len);
DECLARE_double(det_db_thresh);
DECLARE_double(det_db_box_thresh);
DECLARE_double(det_db_unclip_ratio);
DECLARE_bool(use_dilation);
DECLARE_string(det_db_score_mode);
DECLARE_bool(visualize);
// classification related
DECLARE_bool(use_angle_cls);
DECLARE_string(cls_model_dir);
DECLARE_double(cls_thresh);
DECLARE_int32(cls_batch_num);
// recognition related
DECLARE_string(rec_model_dir);
DECLARE_int32(rec_batch_num);
DECLARE_string(rec_char_dict_path);
DECLARE_int32(rec_img_h);
DECLARE_int32(rec_img_w);
// layout model related
DECLARE_string(layout_model_dir);
DECLARE_string(layout_dict_path);
DECLARE_double(layout_score_threshold);
DECLARE_double(layout_nms_threshold);
// structure model related
DECLARE_string(table_model_dir);
DECLARE_int32(table_max_len);
DECLARE_int32(table_batch_num);
DECLARE_string(table_char_dict_path);
DECLARE_bool(merge_no_span_structure);
// forward related
DECLARE_bool(det);
DECLARE_bool(rec);
DECLARE_bool(cls);
DECLARE_bool(table);
DECLARE_bool(layout);

View File

@@ -0,0 +1,435 @@
/*******************************************************************************
* *
* Author : Angus Johnson * Version : 6.4.2 * Date : 27 February
*2017 * Website :
*http://www.angusj.com * Copyright :
*Angus Johnson 2010-2017 *
* *
* License: * Use, modification & distribution is subject to Boost Software
*License Ver 1. * http://www.boost.org/LICENSE_1_0.txt *
* *
* Attributions: * The code in this library is an extension of Bala Vatti's
*clipping algorithm: * "A generic solution to polygon clipping" *
* Communications of the ACM, Vol 35, Issue 7 (July 1992) pp 56-63. *
* http://portal.acm.org/citation.cfm?id=129906 *
* *
* Computer graphics and geometric modeling: implementation and algorithms * By
*Max K. Agoston *
* Springer; 1 edition (January 4, 2005) *
* http://books.google.com/books?q=vatti+clipping+agoston *
* *
* See also: * "Polygon Offsetting by Computing Winding Numbers" * Paper no.
*DETC2005-85513 pp. 565-575 * ASME 2005
*International Design Engineering Technical Conferences * and
*Computers and Information in Engineering Conference (IDETC/CIE2005) *
* September 24-28, 2005 , Long Beach, California, USA *
* http://www.me.berkeley.edu/~mcmains/pubs/DAC05OffsetPolygon.pdf *
* *
*******************************************************************************/
#pragma once
#ifndef clipper_hpp
#define clipper_hpp
#define CLIPPER_VERSION "6.4.2"
// use_int32: When enabled 32bit ints are used instead of 64bit ints. This
// improve performance but coordinate values are limited to the range +/- 46340
//#define use_int32
// use_xyz: adds a Z member to IntPoint. Adds a minor cost to performance.
//#define use_xyz
// use_lines: Enables line clipping. Adds a very minor cost to performance.
#define use_lines
// use_deprecated: Enables temporary support for the obsolete functions
//#define use_deprecated
#include <list>
#include <queue>
#include <string>
#include <vector>
namespace ClipperLib {
enum ClipType { ctIntersection, ctUnion, ctDifference, ctXor };
enum PolyType { ptSubject, ptClip };
// By far the most widely used winding rules for polygon filling are
// EvenOdd & NonZero (GDI, GDI+, XLib, OpenGL, Cairo, AGG, Quartz, SVG, Gr32)
// Others rules include Positive, Negative and ABS_GTR_EQ_TWO (only in OpenGL)
// see http://glprogramming.com/red/chapter11.html
enum PolyFillType { pftEvenOdd, pftNonZero, pftPositive, pftNegative };
#ifdef use_int32
typedef int cInt;
static cInt const loRange = 0x7FFF;
static cInt const hiRange = 0x7FFF;
#else
typedef signed long long cInt;
static cInt const loRange = 0x3FFFFFFF;
static cInt const hiRange = 0x3FFFFFFFFFFFFFFFLL;
typedef signed long long long64; // used by Int128 class
typedef unsigned long long ulong64;
#endif
struct IntPoint {
cInt X;
cInt Y;
#ifdef use_xyz
cInt Z;
IntPoint(cInt x = 0, cInt y = 0, cInt z = 0) noexcept : X(x), Y(y), Z(z) {}
IntPoint(IntPoint const &ip) noexcept : X(ip.X), Y(ip.Y), Z(ip.Z) {}
#else
IntPoint(cInt x = 0, cInt y = 0) noexcept : X(x), Y(y) {}
IntPoint(IntPoint const &ip) noexcept : X(ip.X), Y(ip.Y) {}
#endif
inline void reset(cInt x = 0, cInt y = 0) noexcept {
X = x;
Y = y;
}
friend inline bool operator==(const IntPoint &a, const IntPoint &b) noexcept {
return a.X == b.X && a.Y == b.Y;
}
friend inline bool operator!=(const IntPoint &a, const IntPoint &b) noexcept {
return a.X != b.X || a.Y != b.Y;
}
};
//------------------------------------------------------------------------------
typedef std::vector<IntPoint> Path;
typedef std::vector<Path> Paths;
inline Path &operator<<(Path &poly, IntPoint &&p) noexcept {
poly.emplace_back(std::forward<IntPoint>(p));
return poly;
}
inline Paths &operator<<(Paths &polys, Path &&p) noexcept {
polys.emplace_back(std::forward<Path>(p));
return polys;
}
std::ostream &operator<<(std::ostream &s, const IntPoint &p) noexcept;
std::ostream &operator<<(std::ostream &s, const Path &p) noexcept;
std::ostream &operator<<(std::ostream &s, const Paths &p) noexcept;
struct DoublePoint {
double X;
double Y;
DoublePoint(double x = 0, double y = 0) noexcept : X(x), Y(y) {}
DoublePoint(IntPoint const &ip) noexcept : X((double)ip.X), Y((double)ip.Y) {}
inline void reset(double x = 0, double y = 0) noexcept {
X = x;
Y = y;
}
};
//------------------------------------------------------------------------------
#ifdef use_xyz
typedef void (*ZFillCallback)(IntPoint &e1bot, IntPoint &e1top, IntPoint &e2bot,
IntPoint &e2top, IntPoint &pt);
#endif
enum InitOptions {
ioReverseSolution = 1,
ioStrictlySimple = 2,
ioPreserveCollinear = 4
};
enum JoinType { jtSquare, jtRound, jtMiter };
enum EndType {
etClosedPolygon,
etClosedLine,
etOpenButt,
etOpenSquare,
etOpenRound
};
class PolyNode;
typedef std::vector<PolyNode *> PolyNodes;
class PolyNode {
public:
PolyNode() noexcept;
virtual ~PolyNode() {}
Path Contour;
PolyNodes Children;
PolyNode *Parent;
PolyNode *GetNext() const noexcept;
bool IsHole() const noexcept;
bool IsOpen() const noexcept;
int ChildCount() const noexcept;
private:
// PolyNode& operator =(PolyNode& other);
unsigned Index; // node index in Parent.Children
bool m_IsOpen;
JoinType m_jointype;
EndType m_endtype;
PolyNode *GetNextSiblingUp() const noexcept;
void AddChild(PolyNode &child) noexcept;
friend class Clipper; // to access Index
friend class ClipperOffset;
};
class PolyTree : public PolyNode {
public:
~PolyTree() { Clear(); }
PolyNode *GetFirst() const noexcept;
void Clear() noexcept;
int Total() const noexcept;
private:
// PolyTree& operator =(PolyTree& other);
PolyNodes AllNodes;
friend class Clipper; // to access AllNodes
};
bool Orientation(const Path &poly) noexcept;
double Area(const Path &poly) noexcept;
int PointInPolygon(const IntPoint &pt, const Path &path) noexcept;
#if 0
void SimplifyPolygon(const Path &in_poly, Paths &out_polys,
PolyFillType fillType = pftEvenOdd);
void SimplifyPolygons(const Paths &in_polys, Paths &out_polys,
PolyFillType fillType = pftEvenOdd);
void SimplifyPolygons(Paths &polys, PolyFillType fillType = pftEvenOdd);
#endif
void CleanPolygon(const Path &in_poly, Path &out_poly,
double distance = 1.415) noexcept;
void CleanPolygon(Path &poly, double distance = 1.415) noexcept;
void CleanPolygons(const Paths &in_polys, Paths &out_polys,
double distance = 1.415) noexcept;
void CleanPolygons(Paths &polys, double distance = 1.415) noexcept;
#if 0
void MinkowskiSum(const Path &pattern, const Path &path, Paths &solution,
bool pathIsClosed);
void MinkowskiSum(const Path &pattern, const Paths &paths, Paths &solution,
bool pathIsClosed);
void MinkowskiDiff(const Path &poly1, const Path &poly2, Paths &solution);
#endif
void PolyTreeToPaths(const PolyTree &polytree, Paths &paths) noexcept;
void ClosedPathsFromPolyTree(const PolyTree &polytree, Paths &paths) noexcept;
void OpenPathsFromPolyTree(PolyTree &polytree, Paths &paths) noexcept;
void ReversePath(Path &p) noexcept;
void ReversePaths(Paths &p) noexcept;
struct IntRect {
cInt left;
cInt top;
cInt right;
cInt bottom;
};
// enums that are used internally ...
enum EdgeSide { esLeft = 1, esRight = 2 };
// forward declarations (for stuff used internally) ...
struct TEdge;
struct IntersectNode;
struct LocalMinimum;
struct OutPt;
struct OutRec;
struct Join;
typedef std::vector<OutRec *> PolyOutList;
typedef std::vector<TEdge *> EdgeList;
typedef std::vector<Join *> JoinList;
typedef std::vector<IntersectNode *> IntersectList;
//------------------------------------------------------------------------------
// ClipperBase is the ancestor to the Clipper class. It should not be
// instantiated directly. This class simply abstracts the conversion of sets of
// polygon coordinates into edge objects that are stored in a LocalMinima list.
class ClipperBase {
public:
ClipperBase() noexcept;
virtual ~ClipperBase();
virtual bool AddPath(const Path &pg, PolyType PolyTyp, bool Closed);
bool AddPaths(const Paths &ppg, PolyType PolyTyp, bool Closed);
virtual void Clear() noexcept;
IntRect GetBounds() noexcept;
bool PreserveCollinear() const noexcept { return m_PreserveCollinear; }
void PreserveCollinear(bool value) noexcept { m_PreserveCollinear = value; }
protected:
void DisposeLocalMinimaList() noexcept;
TEdge *AddBoundsToLML(TEdge *e, bool IsClosed) noexcept;
virtual void Reset() noexcept;
TEdge *ProcessBound(TEdge *E, bool IsClockwise) noexcept;
void InsertScanbeam(const cInt Y) noexcept;
bool PopScanbeam(cInt &Y) noexcept;
bool LocalMinimaPending() noexcept;
bool PopLocalMinima(cInt Y, const LocalMinimum *&locMin) noexcept;
OutRec *CreateOutRec() noexcept;
void DisposeAllOutRecs() noexcept;
void DisposeOutRec(PolyOutList::size_type index) noexcept;
void SwapPositionsInAEL(TEdge *edge1, TEdge *edge2) noexcept;
void DeleteFromAEL(TEdge *e) noexcept;
void UpdateEdgeIntoAEL(TEdge *&e);
typedef std::vector<LocalMinimum> MinimaList;
MinimaList::iterator m_CurrentLM;
MinimaList m_MinimaList;
bool m_UseFullRange;
EdgeList m_edges;
bool m_PreserveCollinear;
bool m_HasOpenPaths;
PolyOutList m_PolyOuts;
TEdge *m_ActiveEdges;
typedef std::priority_queue<cInt> ScanbeamList;
ScanbeamList m_Scanbeam;
};
//------------------------------------------------------------------------------
class Clipper : public virtual ClipperBase {
public:
Clipper(int initOptions = 0) noexcept;
bool Execute(ClipType clipType, Paths &solution,
PolyFillType fillType = pftEvenOdd);
bool Execute(ClipType clipType, Paths &solution, PolyFillType subjFillType,
PolyFillType clipFillType);
bool Execute(ClipType clipType, PolyTree &polytree,
PolyFillType fillType = pftEvenOdd) noexcept;
bool Execute(ClipType clipType, PolyTree &polytree, PolyFillType subjFillType,
PolyFillType clipFillType) noexcept;
bool ReverseSolution() const noexcept { return m_ReverseOutput; }
void ReverseSolution(bool value) noexcept { m_ReverseOutput = value; }
bool StrictlySimple() const noexcept { return m_StrictSimple; }
void StrictlySimple(bool value) noexcept { m_StrictSimple = value; }
// set the callback function for z value filling on intersections (otherwise Z
// is 0)
#ifdef use_xyz
void ZFillFunction(ZFillCallback zFillFunc) noexcept;
#endif
protected:
virtual bool ExecuteInternal() noexcept;
private:
JoinList m_Joins;
JoinList m_GhostJoins;
IntersectList m_IntersectList;
ClipType m_ClipType;
typedef std::list<cInt> MaximaList;
MaximaList m_Maxima;
TEdge *m_SortedEdges;
bool m_ExecuteLocked;
PolyFillType m_ClipFillType;
PolyFillType m_SubjFillType;
bool m_ReverseOutput;
bool m_UsingPolyTree;
bool m_StrictSimple;
#ifdef use_xyz
ZFillCallback m_ZFill; // custom callback
#endif
void SetWindingCount(TEdge &edge) noexcept;
bool IsEvenOddFillType(const TEdge &edge) const noexcept;
bool IsEvenOddAltFillType(const TEdge &edge) const noexcept;
void InsertLocalMinimaIntoAEL(const cInt botY) noexcept;
void InsertEdgeIntoAEL(TEdge *edge, TEdge *startEdge) noexcept;
void AddEdgeToSEL(TEdge *edge) noexcept;
bool PopEdgeFromSEL(TEdge *&edge) noexcept;
void CopyAELToSEL() noexcept;
void DeleteFromSEL(TEdge *e) noexcept;
void SwapPositionsInSEL(TEdge *edge1, TEdge *edge2) noexcept;
bool IsContributing(const TEdge &edge) const noexcept;
bool IsTopHorz(const cInt XPos) noexcept;
void DoMaxima(TEdge *e);
void ProcessHorizontals() noexcept;
void ProcessHorizontal(TEdge *horzEdge) noexcept;
void AddLocalMaxPoly(TEdge *e1, TEdge *e2, const IntPoint &pt) noexcept;
OutPt *AddLocalMinPoly(TEdge *e1, TEdge *e2, const IntPoint &pt) noexcept;
OutRec *GetOutRec(int idx) noexcept;
void AppendPolygon(TEdge *e1, TEdge *e2) noexcept;
void IntersectEdges(TEdge *e1, TEdge *e2, IntPoint &pt) noexcept;
OutPt *AddOutPt(TEdge *e, const IntPoint &pt) noexcept;
OutPt *GetLastOutPt(TEdge *e) noexcept;
bool ProcessIntersections(const cInt topY);
void BuildIntersectList(const cInt topY) noexcept;
void ProcessIntersectList() noexcept;
void ProcessEdgesAtTopOfScanbeam(const cInt topY);
void BuildResult(Paths &polys) noexcept;
void BuildResult2(PolyTree &polytree) noexcept;
void SetHoleState(TEdge *e, OutRec *outrec) noexcept;
void DisposeIntersectNodes() noexcept;
bool FixupIntersectionOrder() noexcept;
void FixupOutPolygon(OutRec &outrec) noexcept;
void FixupOutPolyline(OutRec &outrec) noexcept;
bool IsHole(TEdge *e) noexcept;
bool FindOwnerFromSplitRecs(OutRec &outRec, OutRec *&currOrfl) noexcept;
void FixHoleLinkage(OutRec &outrec) noexcept;
void AddJoin(OutPt *op1, OutPt *op2, const IntPoint offPt) noexcept;
void ClearJoins() noexcept;
void ClearGhostJoins() noexcept;
void AddGhostJoin(OutPt *op, const IntPoint offPt) noexcept;
bool JoinPoints(Join *j, OutRec *outRec1, OutRec *outRec2) noexcept;
void JoinCommonEdges() noexcept;
void DoSimplePolygons() noexcept;
void FixupFirstLefts1(OutRec *OldOutRec, OutRec *NewOutRec) noexcept;
void FixupFirstLefts2(OutRec *InnerOutRec, OutRec *OuterOutRec) noexcept;
void FixupFirstLefts3(OutRec *OldOutRec, OutRec *NewOutRec) noexcept;
#ifdef use_xyz
void SetZ(IntPoint &pt, TEdge &e1, TEdge &e2) noexcept;
#endif
};
//------------------------------------------------------------------------------
class ClipperOffset {
public:
ClipperOffset(double miterLimit = 2.0, double roundPrecision = 0.25) noexcept;
~ClipperOffset();
void AddPath(const Path &path, JoinType joinType, EndType endType) noexcept;
void AddPaths(const Paths &paths, JoinType joinType,
EndType endType) noexcept;
bool Execute(Paths &solution, double delta) noexcept;
bool Execute(PolyTree &solution, double delta) noexcept;
void Clear() noexcept;
private:
double MiterLimit;
double ArcTolerance;
Paths m_destPolys;
Path m_srcPoly;
Path m_destPoly;
std::vector<DoublePoint> m_normals;
double m_delta, m_sinA, m_sin, m_cos;
double m_miterLim, m_StepsPerRad;
IntPoint m_lowest;
PolyNode m_polyNodes;
void FixOrientations() noexcept;
void DoOffset(double delta) noexcept;
void OffsetPoint(int j, int &k, JoinType jointype) noexcept;
void DoSquare(int j, int k) noexcept;
void DoMiter(int j, int k, double r) noexcept;
void DoRound(int j, int k) noexcept;
};
//------------------------------------------------------------------------------
class clipperException : public std::exception {
public:
clipperException(const char *description) noexcept : m_descr(description) {}
~clipperException() {}
virtual const char *what() const noexcept { return m_descr.c_str(); }
private:
std::string m_descr;
};
//------------------------------------------------------------------------------
} // namespace ClipperLib
#endif // clipper_hpp

View File

@@ -0,0 +1,102 @@
// Copyright (c) 2020 PaddlePaddle Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#include <fstream>
#include <include/preprocess_op.h>
#include <include/utility.h>
#include <iostream>
#include <memory>
#include <yaml-cpp/yaml.h>
namespace paddle_infer {
class Predictor;
}
namespace PaddleOCR {
class Classifier {
public:
explicit Classifier(const std::string &model_dir, const bool &use_gpu,
const int &gpu_id, const int &gpu_mem,
const int &cpu_math_library_num_threads,
const bool &use_mkldnn, const double &cls_thresh,
const bool &use_tensorrt, const std::string &precision,
const int &cls_batch_num) noexcept {
this->use_gpu_ = use_gpu;
this->gpu_id_ = gpu_id;
this->gpu_mem_ = gpu_mem;
this->cpu_math_library_num_threads_ = cpu_math_library_num_threads;
this->use_mkldnn_ = use_mkldnn;
this->cls_thresh = cls_thresh;
this->use_tensorrt_ = use_tensorrt;
this->precision_ = precision;
this->cls_batch_num_ = cls_batch_num;
std::string yaml_file_path = model_dir + "/inference.yml";
std::ifstream yaml_file(yaml_file_path);
if (yaml_file.is_open()) {
std::string model_name;
try {
YAML::Node config = YAML::LoadFile(yaml_file_path);
if (config["Global"] && config["Global"]["model_name"]) {
model_name = config["Global"]["model_name"].as<std::string>();
}
if (!model_name.empty() &&
model_name != "PP-LCNet_x0_25_textline_ori" &&
model_name != "PP-LCNet_x1_0_textline_ori") {
std::cerr << "Error: " << model_name << " is currently not supported."
<< std::endl;
std::exit(EXIT_FAILURE);
}
} catch (const YAML::Exception &e) {
std::cerr << "Failed to load YAML file: " << e.what() << std::endl;
}
}
LoadModel(model_dir);
}
double cls_thresh = 0.9;
// Load Paddle inference model
void LoadModel(const std::string &model_dir) noexcept;
void Run(const std::vector<cv::Mat> &img_list, std::vector<int> &cls_labels,
std::vector<float> &cls_scores, std::vector<double> &times) noexcept;
private:
std::shared_ptr<paddle_infer::Predictor> predictor_;
bool use_gpu_ = false;
int gpu_id_ = 0;
int gpu_mem_ = 4000;
int cpu_math_library_num_threads_ = 4;
bool use_mkldnn_ = false;
std::vector<float> mean_ = {0.5f, 0.5f, 0.5f};
std::vector<float> scale_ = {1 / 0.5f, 1 / 0.5f, 1 / 0.5f};
bool is_scale_ = true;
bool use_tensorrt_ = false;
std::string precision_ = "fp32";
int cls_batch_num_ = 1;
// pre-process
ClsResizeImg resize_op_;
Normalize normalize_op_;
PermuteBatch permute_op_;
}; // class Classifier
} // namespace PaddleOCR

View File

@@ -0,0 +1,126 @@
// Copyright (c) 2020 PaddlePaddle Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#include <fstream>
#include <include/postprocess_op.h>
#include <include/preprocess_op.h>
#include <iostream>
#include <memory>
#include <yaml-cpp/yaml.h>
namespace paddle_infer {
class Predictor;
}
namespace PaddleOCR {
class DBDetector {
public:
explicit DBDetector(const std::string &model_dir, const bool &use_gpu,
const int &gpu_id, const int &gpu_mem,
const int &cpu_math_library_num_threads,
const bool &use_mkldnn, const std::string &limit_type,
const int &limit_side_len, const double &det_db_thresh,
const double &det_db_box_thresh,
const double &det_db_unclip_ratio,
const std::string &det_db_score_mode,
const bool &use_dilation, const bool &use_tensorrt,
const std::string &precision) noexcept {
this->use_gpu_ = use_gpu;
this->gpu_id_ = gpu_id;
this->gpu_mem_ = gpu_mem;
this->cpu_math_library_num_threads_ = cpu_math_library_num_threads;
this->use_mkldnn_ = use_mkldnn;
this->limit_type_ = limit_type;
this->limit_side_len_ = limit_side_len;
this->det_db_thresh_ = det_db_thresh;
this->det_db_box_thresh_ = det_db_box_thresh;
this->det_db_unclip_ratio_ = det_db_unclip_ratio;
this->det_db_score_mode_ = det_db_score_mode;
this->use_dilation_ = use_dilation;
this->use_tensorrt_ = use_tensorrt;
this->precision_ = precision;
std::string yaml_file_path = model_dir + "/inference.yml";
std::ifstream yaml_file(yaml_file_path);
if (yaml_file.is_open()) {
std::string model_name;
try {
YAML::Node config = YAML::LoadFile(yaml_file_path);
if (config["Global"] && config["Global"]["model_name"]) {
model_name = config["Global"]["model_name"].as<std::string>();
}
if (!model_name.empty() && model_name != "PP-OCRv5_mobile_det" &&
model_name != "PP-OCRv5_server_det") {
std::cerr << "Error: " << model_name << " is currently not supported."
<< std::endl;
std::exit(EXIT_FAILURE);
}
} catch (const YAML::Exception &e) {
std::cerr << "Failed to load YAML file: " << e.what() << std::endl;
}
}
LoadModel(model_dir);
}
// Load Paddle inference model
void LoadModel(const std::string &model_dir) noexcept;
// Run predictor
void Run(const cv::Mat &img,
std::vector<std::vector<std::vector<int>>> &boxes,
std::vector<double> &times) noexcept;
private:
std::shared_ptr<paddle_infer::Predictor> predictor_;
bool use_gpu_ = false;
int gpu_id_ = 0;
int gpu_mem_ = 4000;
int cpu_math_library_num_threads_ = 4;
bool use_mkldnn_ = false;
std::string limit_type_ = "max";
int limit_side_len_ = 960;
double det_db_thresh_ = 0.3;
double det_db_box_thresh_ = 0.5;
double det_db_unclip_ratio_ = 2.0;
std::string det_db_score_mode_ = "slow";
bool use_dilation_ = false;
bool visualize_ = true;
bool use_tensorrt_ = false;
std::string precision_ = "fp32";
std::vector<float> mean_ = {0.485f, 0.456f, 0.406f};
std::vector<float> scale_ = {1 / 0.229f, 1 / 0.224f, 1 / 0.225f};
bool is_scale_ = true;
// pre-process
ResizeImgType0 resize_op_;
Normalize normalize_op_;
Permute permute_op_;
// post-process
DBPostProcessor post_processor_;
};
} // namespace PaddleOCR

View File

@@ -0,0 +1,133 @@
// Copyright (c) 2020 PaddlePaddle Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#include <fstream>
#include <include/preprocess_op.h>
#include <include/utility.h>
#include <iostream>
#include <memory>
#include <yaml-cpp/yaml.h>
namespace paddle_infer {
class Predictor;
}
namespace PaddleOCR {
class CRNNRecognizer {
public:
explicit CRNNRecognizer(const std::string &model_dir, const bool &use_gpu,
const int &gpu_id, const int &gpu_mem,
const int &cpu_math_library_num_threads,
const bool &use_mkldnn, const std::string &label_path,
const bool &use_tensorrt,
const std::string &precision,
const int &rec_batch_num, const int &rec_img_h,
const int &rec_img_w) noexcept {
this->use_gpu_ = use_gpu;
this->gpu_id_ = gpu_id;
this->gpu_mem_ = gpu_mem;
this->cpu_math_library_num_threads_ = cpu_math_library_num_threads;
this->use_mkldnn_ = use_mkldnn;
this->use_tensorrt_ = use_tensorrt;
this->precision_ = precision;
this->rec_batch_num_ = rec_batch_num;
this->rec_img_h_ = rec_img_h;
this->rec_img_w_ = rec_img_w;
std::vector<int> rec_image_shape = {3, rec_img_h, rec_img_w};
this->rec_image_shape_ = rec_image_shape;
std::string new_label_path = label_path;
std::string yaml_file_path = model_dir + "/inference.yml";
std::ifstream yaml_file(yaml_file_path);
if (yaml_file.is_open()) {
std::string model_name;
std::vector<std::string> rec_char_list;
try {
YAML::Node config = YAML::LoadFile(yaml_file_path);
if (config["Global"] && config["Global"]["model_name"]) {
model_name = config["Global"]["model_name"].as<std::string>();
}
if (!model_name.empty() && model_name != "PP-OCRv5_mobile_rec" &&
model_name != "PP-OCRv5_server_rec") {
std::cerr << "Error: " << model_name << " is currently not supported."
<< std::endl;
std::exit(EXIT_FAILURE);
}
if (config["PostProcess"] && config["PostProcess"]["character_dict"]) {
rec_char_list = config["PostProcess"]["character_dict"]
.as<std::vector<std::string>>();
}
} catch (const YAML::Exception &e) {
std::cerr << "Failed to load YAML file: " << e.what() << std::endl;
}
if (label_path == "../../ppocr/utils/ppocr_keys_v1.txt" &&
!rec_char_list.empty()) {
std::string new_rec_char_dict_path = model_dir + "/ppocr_keys.txt";
std::ofstream new_file(new_rec_char_dict_path);
if (new_file.is_open()) {
for (const auto &character : rec_char_list) {
new_file << character << '\n';
}
new_label_path = new_rec_char_dict_path;
}
}
}
this->label_list_ = Utility::ReadDict(new_label_path);
this->label_list_.emplace(this->label_list_.begin(),
"#"); // blank char for ctc
this->label_list_.emplace_back(" ");
LoadModel(model_dir);
}
// Load Paddle inference model
void LoadModel(const std::string &model_dir) noexcept;
void Run(const std::vector<cv::Mat> &img_list,
std::vector<std::string> &rec_texts,
std::vector<float> &rec_text_scores,
std::vector<double> &times) noexcept;
private:
std::shared_ptr<paddle_infer::Predictor> predictor_;
bool use_gpu_ = false;
int gpu_id_ = 0;
int gpu_mem_ = 4000;
int cpu_math_library_num_threads_ = 4;
bool use_mkldnn_ = false;
std::vector<std::string> label_list_;
std::vector<float> mean_ = {0.5f, 0.5f, 0.5f};
std::vector<float> scale_ = {1 / 0.5f, 1 / 0.5f, 1 / 0.5f};
bool is_scale_ = true;
bool use_tensorrt_ = false;
std::string precision_ = "fp32";
int rec_batch_num_ = 6;
int rec_img_h_ = 32;
int rec_img_w_ = 320;
std::vector<int> rec_image_shape_ = {3, rec_img_h_, rec_img_w_};
// pre-process
CrnnResizeImg resize_op_;
Normalize normalize_op_;
PermuteBatch permute_op_;
}; // class CrnnRecognizer
} // namespace PaddleOCR

View File

@@ -0,0 +1,52 @@
// Copyright (c) 2020 PaddlePaddle Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#include <include/utility.h>
namespace PaddleOCR {
class PPOCR {
public:
explicit PPOCR() noexcept;
virtual ~PPOCR();
std::vector<std::vector<OCRPredictResult>>
ocr(const std::vector<cv::Mat> &img_list, bool det = true, bool rec = true,
bool cls = true) noexcept;
std::vector<OCRPredictResult> ocr(const cv::Mat &img, bool det = true,
bool rec = true, bool cls = true) noexcept;
void reset_timer() noexcept;
void benchmark_log(int img_num) noexcept;
protected:
std::vector<double> time_info_det = {0, 0, 0};
std::vector<double> time_info_rec = {0, 0, 0};
std::vector<double> time_info_cls = {0, 0, 0};
void det(const cv::Mat &img,
std::vector<OCRPredictResult> &ocr_results) noexcept;
void rec(const std::vector<cv::Mat> &img_list,
std::vector<OCRPredictResult> &ocr_results) noexcept;
void cls(const std::vector<cv::Mat> &img_list,
std::vector<OCRPredictResult> &ocr_results) noexcept;
private:
struct PPOCR_PRIVATE;
PPOCR_PRIVATE *pri_;
};
} // namespace PaddleOCR

View File

@@ -0,0 +1,66 @@
// Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#include <include/paddleocr.h>
namespace PaddleOCR {
class PaddleStructure : public PPOCR {
public:
explicit PaddleStructure() noexcept;
~PaddleStructure();
std::vector<StructurePredictResult> structure(const cv::Mat &img,
bool layout = false,
bool table = true,
bool ocr = false) noexcept;
void reset_timer() noexcept;
void benchmark_log(int img_num) noexcept;
private:
struct STRUCTURE_PRIVATE;
STRUCTURE_PRIVATE *pri_;
std::vector<double> time_info_table = {0, 0, 0};
std::vector<double> time_info_layout = {0, 0, 0};
void layout(const cv::Mat &img,
std::vector<StructurePredictResult> &structure_result) noexcept;
void table(const cv::Mat &img,
StructurePredictResult &structure_result) noexcept;
std::string rebuild_table(const std::vector<std::string> &rec_html_tags,
const std::vector<std::vector<int>> &rec_boxes,
std::vector<OCRPredictResult> &ocr_result) noexcept;
float dis(const std::vector<int> &box1,
const std::vector<int> &box2) noexcept;
static bool comparison_dis(const std::vector<float> &dis1,
const std::vector<float> &dis2) noexcept {
if (dis1[1] < dis2[1]) {
return true;
} else if (dis1[1] == dis2[1]) {
return dis1[0] < dis2[0];
} else {
return false;
}
}
};
} // namespace PaddleOCR

View File

@@ -0,0 +1,129 @@
// Copyright (c) 2020 PaddlePaddle Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#include <include/utility.h>
namespace PaddleOCR {
class DBPostProcessor {
public:
void GetContourArea(const std::vector<std::vector<float>> &box,
float unclip_ratio, float &distance) noexcept;
cv::RotatedRect UnClip(const std::vector<std::vector<float>> &box,
const float &unclip_ratio) noexcept;
float **Mat2Vec(const cv::Mat &mat) noexcept;
std::vector<std::vector<int>>
OrderPointsClockwise(const std::vector<std::vector<int>> &pts) noexcept;
std::vector<std::vector<float>> GetMiniBoxes(const cv::RotatedRect &box,
float &ssid) noexcept;
float BoxScoreFast(const std::vector<std::vector<float>> &box_array,
const cv::Mat &pred) noexcept;
float PolygonScoreAcc(const std::vector<cv::Point> &contour,
const cv::Mat &pred) noexcept;
std::vector<std::vector<std::vector<int>>>
BoxesFromBitmap(const cv::Mat &pred, const cv::Mat &bitmap,
const float &box_thresh, const float &det_db_unclip_ratio,
const std::string &det_db_score_mode) noexcept;
void FilterTagDetRes(std::vector<std::vector<std::vector<int>>> &boxes,
float ratio_h, float ratio_w,
const cv::Mat &srcimg) noexcept;
private:
static bool XsortInt(const std::vector<int> &a,
const std::vector<int> &b) noexcept;
static bool XsortFp32(const std::vector<float> &a,
const std::vector<float> &b) noexcept;
std::vector<std::vector<float>> Mat2Vector(const cv::Mat &mat) noexcept;
inline int _max(int a, int b) const noexcept { return a >= b ? a : b; }
inline int _min(int a, int b) const noexcept { return a >= b ? b : a; }
template <class T> inline T clamp(T x, T min, T max) const noexcept {
if (x > max)
return max;
if (x < min)
return min;
return x;
}
inline float clampf(float x, float min, float max) const noexcept {
if (x > max)
return max;
if (x < min)
return min;
return x;
}
};
class TablePostProcessor {
public:
void init(const std::string &label_path,
bool merge_no_span_structure = true) noexcept;
void Run(const std::vector<float> &loc_preds,
const std::vector<float> &structure_probs,
std::vector<float> &rec_scores,
const std::vector<int> &loc_preds_shape,
const std::vector<int> &structure_probs_shape,
std::vector<std::vector<std::string>> &rec_html_tag_batch,
std::vector<std::vector<std::vector<int>>> &rec_boxes_batch,
const std::vector<int> &width_list,
const std::vector<int> &height_list) noexcept;
private:
std::vector<std::string> label_list_;
const std::string end = "eos";
const std::string beg = "sos";
};
class PicodetPostProcessor {
public:
void init(const std::string &label_path, const double score_threshold = 0.4,
const double nms_threshold = 0.5,
const std::vector<int> &fpn_stride = {8, 16, 32, 64}) noexcept;
void Run(std::vector<StructurePredictResult> &results,
const std::vector<std::vector<float>> &outs,
const std::vector<int> &ori_shape,
const std::vector<int> &resize_shape, int eg_max) noexcept;
inline size_t fpn_stride_size() const noexcept { return fpn_stride_.size(); }
private:
StructurePredictResult disPred2Bbox(const std::vector<float> &bbox_pred,
int label, float score, int x, int y,
int stride,
const std::vector<int> &im_shape,
int reg_max) noexcept;
void nms(std::vector<StructurePredictResult> &input_boxes,
float nms_threshold) noexcept;
std::vector<int> fpn_stride_ = {8, 16, 32, 64};
std::vector<std::string> label_list_;
double score_threshold_ = 0.4;
double nms_threshold_ = 0.5;
int num_class_ = 5;
};
} // namespace PaddleOCR

View File

@@ -0,0 +1,79 @@
// Copyright (c) 2020 PaddlePaddle Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#include <opencv2/imgproc.hpp>
namespace PaddleOCR {
class Normalize {
public:
virtual void Run(cv::Mat &im, const std::vector<float> &mean,
const std::vector<float> &scale,
const bool is_scale = true) noexcept;
};
// RGB -> CHW
class Permute {
public:
virtual void Run(const cv::Mat &im, float *data) noexcept;
};
class PermuteBatch {
public:
virtual void Run(const std::vector<cv::Mat> &imgs, float *data) noexcept;
};
class ResizeImgType0 {
public:
virtual void Run(const cv::Mat &img, cv::Mat &resize_img,
const std::string &limit_type, int limit_side_len,
float &ratio_h, float &ratio_w, bool use_tensorrt) noexcept;
};
class CrnnResizeImg {
public:
virtual void Run(const cv::Mat &img, cv::Mat &resize_img, float wh_ratio,
bool use_tensorrt = false,
const std::vector<int> &rec_image_shape = {3, 32,
320}) noexcept;
};
class ClsResizeImg {
public:
virtual void
Run(const cv::Mat &img, cv::Mat &resize_img, bool use_tensorrt = false,
const std::vector<int> &rec_image_shape = {3, 48, 192}) noexcept;
};
class TableResizeImg {
public:
virtual void Run(const cv::Mat &img, cv::Mat &resize_img,
const int max_len = 488) noexcept;
};
class TablePadImg {
public:
virtual void Run(const cv::Mat &img, cv::Mat &resize_img,
const int max_len = 488) noexcept;
};
class Resize {
public:
virtual void Run(const cv::Mat &img, cv::Mat &resize_img, const int h,
const int w) noexcept;
};
} // namespace PaddleOCR

View File

@@ -0,0 +1,119 @@
// Copyright (c) 2020 PaddlePaddle Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#include <fstream>
#include <include/postprocess_op.h>
#include <include/preprocess_op.h>
#include <iostream>
#include <memory>
#include <yaml-cpp/yaml.h>
namespace paddle_infer {
class Predictor;
}
namespace PaddleOCR {
class StructureLayoutRecognizer {
public:
explicit StructureLayoutRecognizer(
const std::string &model_dir, const bool &use_gpu, const int &gpu_id,
const int &gpu_mem, const int &cpu_math_library_num_threads,
const bool &use_mkldnn, const std::string &label_path,
const bool &use_tensorrt, const std::string &precision,
const double &layout_score_threshold,
const double &layout_nms_threshold) noexcept {
this->use_gpu_ = use_gpu;
this->gpu_id_ = gpu_id;
this->gpu_mem_ = gpu_mem;
this->cpu_math_library_num_threads_ = cpu_math_library_num_threads;
this->use_mkldnn_ = use_mkldnn;
this->use_tensorrt_ = use_tensorrt;
this->precision_ = precision;
std::string new_label_path = label_path;
std::string yaml_file_path = model_dir + "/inference.yml";
std::ifstream yaml_file(yaml_file_path);
if (yaml_file.is_open()) {
std::string model_name;
std::vector<std::string> rec_char_list;
try {
YAML::Node config = YAML::LoadFile(yaml_file_path);
if (config["Global"] && config["Global"]["model_name"]) {
model_name = config["Global"]["model_name"].as<std::string>();
}
if (!model_name.empty()) {
std::cerr << "Error: " << model_name << " is currently not supported."
<< std::endl;
std::exit(EXIT_FAILURE);
}
if (config["PostProcess"] && config["PostProcess"]["character_dict"]) {
rec_char_list = config["PostProcess"]["character_dict"]
.as<std::vector<std::string>>();
}
} catch (const YAML::Exception &e) {
std::cerr << "Failed to load YAML file: " << e.what() << std::endl;
}
if (label_path == "../../ppocr/utils/ppocr_keys_v1.txt" &&
!rec_char_list.empty()) {
std::string new_rec_char_dict_path = model_dir + "/ppocr_keys.txt";
std::ofstream new_file(new_rec_char_dict_path);
if (new_file.is_open()) {
for (const auto &character : rec_char_list) {
new_file << character << '\n';
}
new_label_path = new_rec_char_dict_path;
}
}
}
this->post_processor_.init(new_label_path, layout_score_threshold,
layout_nms_threshold);
LoadModel(model_dir);
}
// Load Paddle inference model
void LoadModel(const std::string &model_dir) noexcept;
void Run(const cv::Mat &img, std::vector<StructurePredictResult> &result,
std::vector<double> &times) noexcept;
private:
std::shared_ptr<paddle_infer::Predictor> predictor_;
bool use_gpu_ = false;
int gpu_id_ = 0;
int gpu_mem_ = 4000;
int cpu_math_library_num_threads_ = 4;
bool use_mkldnn_ = false;
std::vector<float> mean_ = {0.485f, 0.456f, 0.406f};
std::vector<float> scale_ = {1 / 0.229f, 1 / 0.224f, 1 / 0.225f};
bool is_scale_ = true;
bool use_tensorrt_ = false;
std::string precision_ = "fp32";
// pre-process
Resize resize_op_;
Normalize normalize_op_;
Permute permute_op_;
// post-process
PicodetPostProcessor post_processor_;
};
} // namespace PaddleOCR

View File

@@ -0,0 +1,127 @@
// Copyright (c) 2020 PaddlePaddle Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#include <fstream>
#include <include/postprocess_op.h>
#include <include/preprocess_op.h>
#include <iostream>
#include <memory>
#include <yaml-cpp/yaml.h>
namespace paddle_infer {
class Predictor;
}
namespace PaddleOCR {
class StructureTableRecognizer {
public:
explicit StructureTableRecognizer(
const std::string &model_dir, const bool &use_gpu, const int &gpu_id,
const int &gpu_mem, const int &cpu_math_library_num_threads,
const bool &use_mkldnn, const std::string &label_path,
const bool &use_tensorrt, const std::string &precision,
const int &table_batch_num, const int &table_max_len,
const bool &merge_no_span_structure) noexcept {
this->use_gpu_ = use_gpu;
this->gpu_id_ = gpu_id;
this->gpu_mem_ = gpu_mem;
this->cpu_math_library_num_threads_ = cpu_math_library_num_threads;
this->use_mkldnn_ = use_mkldnn;
this->use_tensorrt_ = use_tensorrt;
this->precision_ = precision;
this->table_batch_num_ = table_batch_num;
this->table_max_len_ = table_max_len;
std::string new_label_path = label_path;
std::string yaml_file_path = model_dir + "/inference.yml";
std::ifstream yaml_file(yaml_file_path);
if (yaml_file.is_open()) {
std::string model_name;
std::vector<std::string> rec_char_list;
try {
YAML::Node config = YAML::LoadFile(yaml_file_path);
if (config["Global"] && config["Global"]["model_name"]) {
model_name = config["Global"]["model_name"].as<std::string>();
}
if (!model_name.empty()) {
std::cerr << "Error: " << model_name << " is currently not supported."
<< std::endl;
std::exit(EXIT_FAILURE);
}
if (config["PostProcess"] && config["PostProcess"]["character_dict"]) {
rec_char_list = config["PostProcess"]["character_dict"]
.as<std::vector<std::string>>();
}
} catch (const YAML::Exception &e) {
std::cerr << "Failed to load YAML file: " << e.what() << std::endl;
}
if (label_path == "../../ppocr/utils/ppocr_keys_v1.txt" &&
!rec_char_list.empty()) {
std::string new_rec_char_dict_path = model_dir + "/ppocr_keys.txt";
std::ofstream new_file(new_rec_char_dict_path);
if (new_file.is_open()) {
for (const auto &character : rec_char_list) {
new_file << character << '\n';
}
new_label_path = new_rec_char_dict_path;
}
}
}
this->post_processor_.init(new_label_path, merge_no_span_structure);
LoadModel(model_dir);
}
// Load Paddle inference model
void LoadModel(const std::string &model_dir) noexcept;
void Run(const std::vector<cv::Mat> &img_list,
std::vector<std::vector<std::string>> &rec_html_tags,
std::vector<float> &rec_scores,
std::vector<std::vector<std::vector<int>>> &rec_boxes,
std::vector<double> &times) noexcept;
private:
std::shared_ptr<paddle_infer::Predictor> predictor_;
bool use_gpu_ = false;
int gpu_id_ = 0;
int gpu_mem_ = 4000;
int cpu_math_library_num_threads_ = 4;
bool use_mkldnn_ = false;
int table_max_len_ = 488;
std::vector<float> mean_ = {0.485f, 0.456f, 0.406f};
std::vector<float> scale_ = {1 / 0.229f, 1 / 0.224f, 1 / 0.225f};
bool is_scale_ = true;
bool use_tensorrt_ = false;
std::string precision_ = "fp32";
int table_batch_num_ = 1;
// pre-process
TableResizeImg resize_op_;
Normalize normalize_op_;
PermuteBatch permute_op_;
TablePadImg pad_op_;
// post-process
TablePostProcessor post_processor_;
}; // class StructureTableRecognizer
} // namespace PaddleOCR

View File

@@ -0,0 +1,113 @@
// Copyright (c) 2020 PaddlePaddle Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#include <opencv2/imgproc.hpp>
namespace PaddleOCR {
struct OCRPredictResult {
std::vector<std::vector<int>> box;
std::string text;
float score = -1.0;
float cls_score;
int cls_label = -1;
};
struct StructurePredictResult {
std::vector<float> box;
std::vector<std::vector<int>> cell_box;
std::string type;
std::vector<OCRPredictResult> text_res;
std::string html;
float html_score = -1;
float confidence;
};
class Utility {
public:
static std::vector<std::string> ReadDict(const std::string &path) noexcept;
static void VisualizeBboxes(const cv::Mat &srcimg,
const std::vector<OCRPredictResult> &ocr_result,
const std::string &save_path) noexcept;
static void VisualizeBboxes(const cv::Mat &srcimg,
const StructurePredictResult &structure_result,
const std::string &save_path) noexcept;
template <class ForwardIterator>
inline static size_t argmax(ForwardIterator first,
ForwardIterator last) noexcept {
return std::distance(first, std::max_element(first, last));
}
static void GetAllFiles(const char *dir_name,
std::vector<std::string> &all_inputs) noexcept;
static cv::Mat
GetRotateCropImage(const cv::Mat &srcimage,
const std::vector<std::vector<int>> &box) noexcept;
static std::vector<size_t> argsort(const std::vector<float> &array) noexcept;
static std::string basename(const std::string &filename) noexcept;
static bool PathExists(const char *path) noexcept;
static inline bool PathExists(const std::string &path) noexcept {
return PathExists(path.c_str());
}
static void CreateDir(const char *path) noexcept;
static inline void CreateDir(const std::string &path) noexcept {
CreateDir(path.c_str());
}
static void
print_result(const std::vector<OCRPredictResult> &ocr_result) noexcept;
static cv::Mat crop_image(const cv::Mat &img,
const std::vector<int> &area) noexcept;
static cv::Mat crop_image(const cv::Mat &img,
const std::vector<float> &area) noexcept;
static void sort_boxes(std::vector<OCRPredictResult> &ocr_result) noexcept;
static std::vector<int>
xyxyxyxy2xyxy(const std::vector<std::vector<int>> &box) noexcept;
static std::vector<int> xyxyxyxy2xyxy(const std::vector<int> &box) noexcept;
static float fast_exp(float x) noexcept;
static std::vector<float>
activation_function_softmax(const std::vector<float> &src) noexcept;
static float iou(const std::vector<int> &box1,
const std::vector<int> &box2) noexcept;
static float iou(const std::vector<float> &box1,
const std::vector<float> &box2) noexcept;
private:
static bool comparison_box(const OCRPredictResult &result1,
const OCRPredictResult &result2) noexcept {
if (result1.box[0][1] < result2.box[0][1]) {
return true;
} else if (result1.box[0][1] == result2.box[0][1]) {
return result1.box[0][0] < result2.box[0][0];
} else {
return false;
}
}
};
} // namespace PaddleOCR