This commit is contained in:
68
deploy/cpp_infer/include/args.h
Normal file
68
deploy/cpp_infer/include/args.h
Normal 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);
|
||||
435
deploy/cpp_infer/include/clipper.h
Normal file
435
deploy/cpp_infer/include/clipper.h
Normal 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
|
||||
102
deploy/cpp_infer/include/ocr_cls.h
Normal file
102
deploy/cpp_infer/include/ocr_cls.h
Normal 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> ×) 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
|
||||
126
deploy/cpp_infer/include/ocr_det.h
Normal file
126
deploy/cpp_infer/include/ocr_det.h
Normal 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> ×) 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
|
||||
133
deploy/cpp_infer/include/ocr_rec.h
Normal file
133
deploy/cpp_infer/include/ocr_rec.h
Normal 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> ×) 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
|
||||
52
deploy/cpp_infer/include/paddleocr.h
Normal file
52
deploy/cpp_infer/include/paddleocr.h
Normal 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
|
||||
66
deploy/cpp_infer/include/paddlestructure.h
Normal file
66
deploy/cpp_infer/include/paddlestructure.h
Normal 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
|
||||
129
deploy/cpp_infer/include/postprocess_op.h
Normal file
129
deploy/cpp_infer/include/postprocess_op.h
Normal 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
|
||||
79
deploy/cpp_infer/include/preprocess_op.h
Normal file
79
deploy/cpp_infer/include/preprocess_op.h
Normal 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
|
||||
119
deploy/cpp_infer/include/structure_layout.h
Normal file
119
deploy/cpp_infer/include/structure_layout.h
Normal 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> ×) 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
|
||||
127
deploy/cpp_infer/include/structure_table.h
Normal file
127
deploy/cpp_infer/include/structure_table.h
Normal 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> ×) 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
|
||||
113
deploy/cpp_infer/include/utility.h
Normal file
113
deploy/cpp_infer/include/utility.h
Normal 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
|
||||
Reference in New Issue
Block a user