Upload first version
This commit is contained in:
parent
f95d5a63b0
commit
3bdf2003ec
898 changed files with 1405811 additions and 1 deletions
0
examples/ppocr-det/cpp/.gitkeep
Normal file
0
examples/ppocr-det/cpp/.gitkeep
Normal file
77
examples/ppocr-det/cpp/build-android.sh
Executable file
77
examples/ppocr-det/cpp/build-android.sh
Executable file
|
|
@ -0,0 +1,77 @@
|
|||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
#
|
||||
# Copyright (C) 2024–2025 Amlogic, Inc. 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.
|
||||
#
|
||||
|
||||
usage() {
|
||||
echo "Usage: $0 [-a <target_abi>]"
|
||||
echo " -a <target_abi> : Target ABI (default: arm64-v8a)"
|
||||
echo " -h : Show this help message"
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Default values
|
||||
TARGET_ABI=arm64-v8a
|
||||
|
||||
# Parse arguments
|
||||
while getopts 'a:h' opt; do
|
||||
case "$opt" in
|
||||
a)
|
||||
TARGET_ABI=$OPTARG
|
||||
;;
|
||||
h)
|
||||
usage
|
||||
;;
|
||||
*)
|
||||
usage
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [ -z "${ANDROID_NDK_PATH}" ]; then
|
||||
if [ -n "${ANDROID_NDK}" ]; then
|
||||
ANDROID_NDK_PATH=${ANDROID_NDK}
|
||||
elif [ -n "${ANDROID_NDK_HOME}" ]; then
|
||||
ANDROID_NDK_PATH=${ANDROID_NDK_HOME}
|
||||
else
|
||||
echo "Error: ANDROID_NDK_PATH is not set."
|
||||
echo "Please set ANDROID_NDK_PATH to your Android NDK directory."
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
ROOT_PWD=$(cd "$(dirname $0)" && pwd)
|
||||
BUILD_DIR=${ROOT_PWD}/build/android
|
||||
|
||||
echo "Building for Android..."
|
||||
echo "NDK_PATH: ${ANDROID_NDK_PATH}"
|
||||
echo "TARGET_ABI: ${TARGET_ABI}"
|
||||
echo "BUILD_DIR: ${BUILD_DIR}"
|
||||
|
||||
mkdir -p ${BUILD_DIR}
|
||||
cd ${BUILD_DIR}
|
||||
|
||||
cmake ../../src \
|
||||
-DCMAKE_TOOLCHAIN_FILE=${ANDROID_NDK_PATH}/build/cmake/android.toolchain.cmake \
|
||||
-DANDROID_ABI=${TARGET_ABI} \
|
||||
-DANDROID_PLATFORM=android-24 \
|
||||
-DCMAKE_BUILD_TYPE=Release \
|
||||
-DOpenCV_DIR=${ROOT_PWD}/../../../dependency/opencv/opencv-android-sdk-build/sdk/native/jni/abi-${TARGET_ABI}
|
||||
|
||||
make -j4
|
||||
|
||||
echo "Build complete. Executable in ${BUILD_DIR}/paddleocr_det_demo"
|
||||
78
examples/ppocr-det/cpp/build-linux.sh
Executable file
78
examples/ppocr-det/cpp/build-linux.sh
Executable file
|
|
@ -0,0 +1,78 @@
|
|||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
#
|
||||
# Copyright (C) 2024–2025 Amlogic, Inc. 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.
|
||||
#
|
||||
|
||||
usage() {
|
||||
echo "Usage: $0 [-a <target_arch>]"
|
||||
echo " -a <target_arch> : Target architecture (default: aarch64)"
|
||||
echo " -h : Show this help message"
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Default values
|
||||
TARGET_ARCH=aarch64
|
||||
|
||||
# Parse arguments
|
||||
while getopts 'a:h' opt; do
|
||||
case "$opt" in
|
||||
a)
|
||||
TARGET_ARCH=$OPTARG
|
||||
;;
|
||||
h)
|
||||
usage
|
||||
;;
|
||||
*)
|
||||
usage
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# Default to aarch64-linux-gnu if GCC_COMPILER is not set
|
||||
GCC_COMPILER=${GCC_COMPILER:-aarch64-linux-gnu}
|
||||
|
||||
# Set compilers
|
||||
export CC=${GCC_COMPILER}-gcc
|
||||
export CXX=${GCC_COMPILER}-g++
|
||||
|
||||
# Validate compiler
|
||||
if ! command -v ${CC} &> /dev/null; then
|
||||
echo "Error: Compiler ${CC} not found."
|
||||
echo "Please set GCC_COMPILER environment variable to your cross-compiler path prefix."
|
||||
echo "Example: export GCC_COMPILER=/path/to/toolchain/bin/aarch64-linux-gnu"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
ROOT_PWD=$(cd "$(dirname $0)" && pwd)
|
||||
BUILD_DIR=${ROOT_PWD}/build/linux
|
||||
|
||||
echo "Building for Linux..."
|
||||
echo "COMPILER: ${CC}"
|
||||
echo "TARGET_ARCH: ${TARGET_ARCH}"
|
||||
echo "BUILD_DIR: ${BUILD_DIR}"
|
||||
|
||||
mkdir -p ${BUILD_DIR}
|
||||
cd ${BUILD_DIR}
|
||||
|
||||
cmake ../../src \
|
||||
-DCMAKE_SYSTEM_NAME=Linux \
|
||||
-DCMAKE_SYSTEM_PROCESSOR=${TARGET_ARCH} \
|
||||
-DCMAKE_BUILD_TYPE=Release
|
||||
|
||||
make -j4
|
||||
|
||||
echo "Build complete. Executable in ${BUILD_DIR}/paddleocr_det_demo"
|
||||
44
examples/ppocr-det/cpp/src/CMakeLists.txt
Executable file
44
examples/ppocr-det/cpp/src/CMakeLists.txt
Executable file
|
|
@ -0,0 +1,44 @@
|
|||
cmake_minimum_required(VERSION 3.5)
|
||||
project(yolo_world_demo)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
|
||||
# Set NNSDK path
|
||||
# Set NNSDK path
|
||||
set(NNSDK_ROOT "${CMAKE_SOURCE_DIR}/../../../../dependency/nnsdk")
|
||||
include_directories(${NNSDK_ROOT}/include)
|
||||
include_directories(${CMAKE_SOURCE_DIR}/../../../../common)
|
||||
|
||||
# Set 3rdparty path
|
||||
set(3RDPARTY_DIR "${CMAKE_SOURCE_DIR}/../../../../dependency")
|
||||
|
||||
if(CMAKE_SYSTEM_NAME STREQUAL "Android")
|
||||
if (ANDROID_ABI STREQUAL "arm64-v8a")
|
||||
link_directories(${NNSDK_ROOT}/lib/android/arm64-v8a)
|
||||
else()
|
||||
link_directories(${NNSDK_ROOT}/lib/android/armeabi-v7a)
|
||||
endif()
|
||||
# Android needs log
|
||||
link_libraries(log)
|
||||
elseif(CMAKE_SYSTEM_NAME STREQUAL "Linux")
|
||||
link_directories(${NNSDK_ROOT}/lib/linux/lib64_yocto)
|
||||
endif()
|
||||
|
||||
# Find OpenCV
|
||||
message(STATUS "OpenCV_DIR: ${OpenCV_DIR}")
|
||||
find_package(OpenCV REQUIRED)
|
||||
include_directories(${OpenCV_INCLUDE_DIRS})
|
||||
|
||||
add_executable(paddleocr_det_demo
|
||||
main.cpp
|
||||
postprocess.cpp
|
||||
postprocess.h
|
||||
clipper.cpp
|
||||
clipper.h
|
||||
${CMAKE_SOURCE_DIR}/../../../../common/model_loader.cpp
|
||||
)
|
||||
|
||||
target_link_libraries(paddleocr_det_demo
|
||||
${OpenCV_LIBS}
|
||||
nnsdk
|
||||
)
|
||||
4379
examples/ppocr-det/cpp/src/clipper.cpp
Executable file
4379
examples/ppocr-det/cpp/src/clipper.cpp
Executable file
File diff suppressed because it is too large
Load diff
425
examples/ppocr-det/cpp/src/clipper.h
Executable file
425
examples/ppocr-det/cpp/src/clipper.h
Executable file
|
|
@ -0,0 +1,425 @@
|
|||
/*******************************************************************************
|
||||
* *
|
||||
* 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 <cstdlib>
|
||||
#include <cstring>
|
||||
#include <functional>
|
||||
#include <list>
|
||||
#include <ostream>
|
||||
#include <queue>
|
||||
#include <set>
|
||||
#include <stdexcept>
|
||||
#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) : X(x), Y(y), Z(z){};
|
||||
#else
|
||||
IntPoint(cInt x = 0, cInt y = 0) : X(x), Y(y){};
|
||||
#endif
|
||||
|
||||
friend inline bool operator==(const IntPoint &a, const IntPoint &b) {
|
||||
return a.X == b.X && a.Y == b.Y;
|
||||
}
|
||||
friend inline bool operator!=(const IntPoint &a, const IntPoint &b) {
|
||||
return a.X != b.X || a.Y != b.Y;
|
||||
}
|
||||
};
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
typedef std::vector<IntPoint> Path;
|
||||
typedef std::vector<Path> Paths;
|
||||
|
||||
inline Path &operator<<(Path &poly, const IntPoint &p) {
|
||||
poly.push_back(p);
|
||||
return poly;
|
||||
}
|
||||
inline Paths &operator<<(Paths &polys, const Path &p) {
|
||||
polys.push_back(p);
|
||||
return polys;
|
||||
}
|
||||
|
||||
std::ostream &operator<<(std::ostream &s, const IntPoint &p);
|
||||
std::ostream &operator<<(std::ostream &s, const Path &p);
|
||||
std::ostream &operator<<(std::ostream &s, const Paths &p);
|
||||
|
||||
struct DoublePoint {
|
||||
double X;
|
||||
double Y;
|
||||
DoublePoint(double x = 0, double y = 0) : X(x), Y(y) {}
|
||||
DoublePoint(IntPoint ip) : X((double)ip.X), Y((double)ip.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();
|
||||
virtual ~PolyNode(){};
|
||||
Path Contour;
|
||||
PolyNodes Children;
|
||||
PolyNode *Parent;
|
||||
PolyNode *GetNext() const;
|
||||
bool IsHole() const;
|
||||
bool IsOpen() const;
|
||||
int ChildCount() const;
|
||||
|
||||
private:
|
||||
// PolyNode& operator =(PolyNode& other);
|
||||
unsigned Index; // node index in Parent.Children
|
||||
bool m_IsOpen;
|
||||
JoinType m_jointype;
|
||||
EndType m_endtype;
|
||||
PolyNode *GetNextSiblingUp() const;
|
||||
void AddChild(PolyNode &child);
|
||||
friend class Clipper; // to access Index
|
||||
friend class ClipperOffset;
|
||||
};
|
||||
|
||||
class PolyTree : public PolyNode {
|
||||
public:
|
||||
~PolyTree() { Clear(); };
|
||||
PolyNode *GetFirst() const;
|
||||
void Clear();
|
||||
int Total() const;
|
||||
|
||||
private:
|
||||
// PolyTree& operator =(PolyTree& other);
|
||||
PolyNodes AllNodes;
|
||||
friend class Clipper; // to access AllNodes
|
||||
};
|
||||
|
||||
bool Orientation(const Path &poly);
|
||||
double Area(const Path &poly);
|
||||
int PointInPolygon(const IntPoint &pt, const Path &path);
|
||||
|
||||
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);
|
||||
|
||||
void CleanPolygon(const Path &in_poly, Path &out_poly, double distance = 1.415);
|
||||
void CleanPolygon(Path &poly, double distance = 1.415);
|
||||
void CleanPolygons(const Paths &in_polys, Paths &out_polys,
|
||||
double distance = 1.415);
|
||||
void CleanPolygons(Paths &polys, double distance = 1.415);
|
||||
|
||||
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);
|
||||
|
||||
void PolyTreeToPaths(const PolyTree &polytree, Paths &paths);
|
||||
void ClosedPathsFromPolyTree(const PolyTree &polytree, Paths &paths);
|
||||
void OpenPathsFromPolyTree(PolyTree &polytree, Paths &paths);
|
||||
|
||||
void ReversePath(Path &p);
|
||||
void ReversePaths(Paths &p);
|
||||
|
||||
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();
|
||||
virtual ~ClipperBase();
|
||||
virtual bool AddPath(const Path &pg, PolyType PolyTyp, bool Closed);
|
||||
bool AddPaths(const Paths &ppg, PolyType PolyTyp, bool Closed);
|
||||
virtual void Clear();
|
||||
IntRect GetBounds();
|
||||
bool PreserveCollinear() { return m_PreserveCollinear; };
|
||||
void PreserveCollinear(bool value) { m_PreserveCollinear = value; };
|
||||
|
||||
protected:
|
||||
void DisposeLocalMinimaList();
|
||||
TEdge *AddBoundsToLML(TEdge *e, bool IsClosed);
|
||||
virtual void Reset();
|
||||
TEdge *ProcessBound(TEdge *E, bool IsClockwise);
|
||||
void InsertScanbeam(const cInt Y);
|
||||
bool PopScanbeam(cInt &Y);
|
||||
bool LocalMinimaPending();
|
||||
bool PopLocalMinima(cInt Y, const LocalMinimum *&locMin);
|
||||
OutRec *CreateOutRec();
|
||||
void DisposeAllOutRecs();
|
||||
void DisposeOutRec(PolyOutList::size_type index);
|
||||
void SwapPositionsInAEL(TEdge *edge1, TEdge *edge2);
|
||||
void DeleteFromAEL(TEdge *e);
|
||||
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);
|
||||
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);
|
||||
bool Execute(ClipType clipType, PolyTree &polytree, PolyFillType subjFillType,
|
||||
PolyFillType clipFillType);
|
||||
bool ReverseSolution() { return m_ReverseOutput; };
|
||||
void ReverseSolution(bool value) { m_ReverseOutput = value; };
|
||||
bool StrictlySimple() { return m_StrictSimple; };
|
||||
void StrictlySimple(bool value) { m_StrictSimple = value; };
|
||||
// set the callback function for z value filling on intersections (otherwise Z
|
||||
// is 0)
|
||||
#ifdef use_xyz
|
||||
void ZFillFunction(ZFillCallback zFillFunc);
|
||||
#endif
|
||||
protected:
|
||||
virtual bool ExecuteInternal();
|
||||
|
||||
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);
|
||||
bool IsEvenOddFillType(const TEdge &edge) const;
|
||||
bool IsEvenOddAltFillType(const TEdge &edge) const;
|
||||
void InsertLocalMinimaIntoAEL(const cInt botY);
|
||||
void InsertEdgeIntoAEL(TEdge *edge, TEdge *startEdge);
|
||||
void AddEdgeToSEL(TEdge *edge);
|
||||
bool PopEdgeFromSEL(TEdge *&edge);
|
||||
void CopyAELToSEL();
|
||||
void DeleteFromSEL(TEdge *e);
|
||||
void SwapPositionsInSEL(TEdge *edge1, TEdge *edge2);
|
||||
bool IsContributing(const TEdge &edge) const;
|
||||
bool IsTopHorz(const cInt XPos);
|
||||
void DoMaxima(TEdge *e);
|
||||
void ProcessHorizontals();
|
||||
void ProcessHorizontal(TEdge *horzEdge);
|
||||
void AddLocalMaxPoly(TEdge *e1, TEdge *e2, const IntPoint &pt);
|
||||
OutPt *AddLocalMinPoly(TEdge *e1, TEdge *e2, const IntPoint &pt);
|
||||
OutRec *GetOutRec(int idx);
|
||||
void AppendPolygon(TEdge *e1, TEdge *e2);
|
||||
void IntersectEdges(TEdge *e1, TEdge *e2, IntPoint &pt);
|
||||
OutPt *AddOutPt(TEdge *e, const IntPoint &pt);
|
||||
OutPt *GetLastOutPt(TEdge *e);
|
||||
bool ProcessIntersections(const cInt topY);
|
||||
void BuildIntersectList(const cInt topY);
|
||||
void ProcessIntersectList();
|
||||
void ProcessEdgesAtTopOfScanbeam(const cInt topY);
|
||||
void BuildResult(Paths &polys);
|
||||
void BuildResult2(PolyTree &polytree);
|
||||
void SetHoleState(TEdge *e, OutRec *outrec);
|
||||
void DisposeIntersectNodes();
|
||||
bool FixupIntersectionOrder();
|
||||
void FixupOutPolygon(OutRec &outrec);
|
||||
void FixupOutPolyline(OutRec &outrec);
|
||||
bool IsHole(TEdge *e);
|
||||
bool FindOwnerFromSplitRecs(OutRec &outRec, OutRec *&currOrfl);
|
||||
void FixHoleLinkage(OutRec &outrec);
|
||||
void AddJoin(OutPt *op1, OutPt *op2, const IntPoint offPt);
|
||||
void ClearJoins();
|
||||
void ClearGhostJoins();
|
||||
void AddGhostJoin(OutPt *op, const IntPoint offPt);
|
||||
bool JoinPoints(Join *j, OutRec *outRec1, OutRec *outRec2);
|
||||
void JoinCommonEdges();
|
||||
void DoSimplePolygons();
|
||||
void FixupFirstLefts1(OutRec *OldOutRec, OutRec *NewOutRec);
|
||||
void FixupFirstLefts2(OutRec *InnerOutRec, OutRec *OuterOutRec);
|
||||
void FixupFirstLefts3(OutRec *OldOutRec, OutRec *NewOutRec);
|
||||
#ifdef use_xyz
|
||||
void SetZ(IntPoint &pt, TEdge &e1, TEdge &e2);
|
||||
#endif
|
||||
};
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
class ClipperOffset {
|
||||
public:
|
||||
ClipperOffset(double miterLimit = 2.0, double roundPrecision = 0.25);
|
||||
~ClipperOffset();
|
||||
void AddPath(const Path &path, JoinType joinType, EndType endType);
|
||||
void AddPaths(const Paths &paths, JoinType joinType, EndType endType);
|
||||
void Execute(Paths &solution, double delta);
|
||||
void Execute(PolyTree &solution, double delta);
|
||||
void Clear();
|
||||
double MiterLimit;
|
||||
double ArcTolerance;
|
||||
|
||||
private:
|
||||
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();
|
||||
void DoOffset(double delta);
|
||||
void OffsetPoint(int j, int &k, JoinType jointype);
|
||||
void DoSquare(int j, int k);
|
||||
void DoMiter(int j, int k, double r);
|
||||
void DoRound(int j, int k);
|
||||
};
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
class clipperException : public std::exception {
|
||||
public:
|
||||
clipperException(const char *description) : m_descr(description) {}
|
||||
virtual ~clipperException() throw() {}
|
||||
virtual const char *what() const throw() { return m_descr.c_str(); }
|
||||
|
||||
private:
|
||||
std::string m_descr;
|
||||
};
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
} // ClipperLib namespace
|
||||
|
||||
#endif // clipper_hpp
|
||||
91
examples/ppocr-det/cpp/src/main.cpp
Executable file
91
examples/ppocr-det/cpp/src/main.cpp
Executable file
|
|
@ -0,0 +1,91 @@
|
|||
/*
|
||||
* Copyright (C) 2024–2025 Amlogic, Inc. 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.
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <opencv2/opencv.hpp>
|
||||
#include <chrono>
|
||||
#include "nn_sdk.h"
|
||||
#include "model_loader.h"
|
||||
#include "postprocess.h"
|
||||
|
||||
const std::string DEFAULT_OUTPUT_PATH = "result.png";
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
if (argc < 3) {
|
||||
printf("Usage: %s <model_path> <image_path> [output_path]\n", argv[0]);
|
||||
return -1;
|
||||
}
|
||||
|
||||
std::string model_path = argv[1];
|
||||
std::string image_path = argv[2];
|
||||
std::string output_path = (argc > 3) ? argv[3] : DEFAULT_OUTPUT_PATH;
|
||||
|
||||
printf("Model: %s\n", model_path.c_str());
|
||||
printf("Image: %s\n", image_path.c_str());
|
||||
|
||||
// 1. Initialize Network
|
||||
void* ctx = init_network(model_path.c_str());
|
||||
if (!ctx) {
|
||||
fprintf(stderr, "Failed to initialize network\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
// 2. Load Image
|
||||
cv::Mat img = cv::imread(image_path);
|
||||
if (img.empty()) {
|
||||
fprintf(stderr, "Failed to load image: %s\n", image_path.c_str());
|
||||
uninit_network(ctx);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// 3. Preprocess
|
||||
auto start_time = std::chrono::high_resolution_clock::now();
|
||||
cv::Mat pre_image;
|
||||
float scale = 1.0f;
|
||||
preprocess(img, pre_image, MODEL_INPUT_WIDTH, MODEL_INPUT_HEIGHT, scale);
|
||||
|
||||
printf("scale: %f\n", scale);
|
||||
// 4. Inference
|
||||
nn_output* outdata = (nn_output*)run_paddleocr_network(ctx, pre_image, MODEL_INPUT_WIDTH, MODEL_INPUT_HEIGHT, MODEL_INPUT_CHANNELS);
|
||||
if (!outdata) {
|
||||
fprintf(stderr, "Inference failed\n");
|
||||
uninit_network(ctx);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// 5. Postprocess
|
||||
float* out0 = (float*)outdata->out[0].buf;
|
||||
|
||||
std::vector<Object> results;
|
||||
postprocess(out0, img, BOX_SCORE_THRESH, BOX_THRESH, results, scale);
|
||||
|
||||
auto end_time = std::chrono::high_resolution_clock::now();
|
||||
std::chrono::duration<double, std::milli> inference_time = end_time - start_time;
|
||||
printf("Inference + Postprocess time: %.2f ms\n", inference_time.count());
|
||||
printf("Results: %zu\n", results.size());
|
||||
|
||||
// 6. Draw and Save
|
||||
cv::Mat res = draw_objects(img, results);
|
||||
cv::imwrite(output_path, res);
|
||||
printf("Saved result to %s\n", output_path.c_str());
|
||||
|
||||
// 7. Cleanup
|
||||
uninit_network(ctx);
|
||||
|
||||
return 0;
|
||||
}
|
||||
272
examples/ppocr-det/cpp/src/postprocess.cpp
Executable file
272
examples/ppocr-det/cpp/src/postprocess.cpp
Executable file
|
|
@ -0,0 +1,272 @@
|
|||
/*
|
||||
* Copyright (C) 2024–2025 Amlogic, Inc. 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.
|
||||
*/
|
||||
|
||||
#include "postprocess.h"
|
||||
|
||||
#include "clipper.h"
|
||||
#include <algorithm>
|
||||
#include <limits>
|
||||
#include <cstdint>
|
||||
|
||||
int preprocess(const cv::Mat& image, cv::Mat& pre_image, const int width, const int height, float& scale ) {
|
||||
if (image.empty() || width <= 0 || height <= 0)
|
||||
return -1;
|
||||
|
||||
int w = image.cols;
|
||||
int h = image.rows;
|
||||
float width_ratio = (float) image.cols / width;
|
||||
float height_ratio = (float) image.rows / height;
|
||||
float ratio_max = std::max(width_ratio, height_ratio);
|
||||
|
||||
int new_w = std::min(int(image.cols / ratio_max), w);
|
||||
int new_h = std::min(int(image.rows / ratio_max), h);
|
||||
|
||||
cv::Mat resized_img;
|
||||
cv::resize(image, resized_img, cv::Size(new_w, new_h));
|
||||
|
||||
pre_image = cv::Mat::zeros(height, width, CV_8UC3);
|
||||
cv::Rect roi_rect = cv::Rect(0, 0, new_w, new_h);
|
||||
|
||||
resized_img.copyTo(pre_image(roi_rect));
|
||||
scale = ratio_max;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int postprocess(float* out, const cv::Mat& image, float box_score_thresh, float box_thresh, std::vector<Object>& result, float scale) {
|
||||
|
||||
if (out == NULL)
|
||||
return -1;
|
||||
cv::Mat pred_map(MODEL_INPUT_HEIGHT, MODEL_INPUT_WIDTH, CV_32FC1, out);
|
||||
|
||||
cv::Mat bit_map;
|
||||
bit_map = pred_map > box_thresh;
|
||||
cv::Mat dila_ele =
|
||||
cv::getStructuringElement(cv::MORPH_RECT, cv::Size(3, 3));
|
||||
cv::dilate(bit_map, bit_map, dila_ele, cv::Point(-1, -1), 1);
|
||||
|
||||
result = find_box(pred_map, bit_map, box_score_thresh, 1.5f, image, scale);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void* run_paddleocr_network(void* qcontext, cv::Mat& image, const int width, const int height, const int channel) {
|
||||
unsigned char* rawdata = image.data;
|
||||
|
||||
nn_input inData;
|
||||
memset(&inData, 0, sizeof(nn_input));
|
||||
inData.input_type = BINARY_RAW_DATA;
|
||||
inData.input = rawdata;
|
||||
inData.input_index = 0;
|
||||
inData.size = width * height * channel * sizeof(uint8_t);
|
||||
|
||||
int ret = aml_module_input_set(qcontext, &inData);
|
||||
if (ret) {
|
||||
printf("aml_module_input_set fail for index %d. Ret=%d", 0, ret);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
aml_output_config_t outconfig;
|
||||
memset(&outconfig, 0, sizeof(aml_output_config_t));
|
||||
outconfig.typeSize = sizeof(aml_output_config_t);
|
||||
outconfig.format = AML_OUTDATA_FLOAT32;
|
||||
return aml_module_output_get(qcontext, outconfig);
|
||||
}
|
||||
|
||||
std::vector<Object> find_box(const cv::Mat pred_map, const cv::Mat& bit_map,
|
||||
const float box_score_thresh, const float unclip_ratio,
|
||||
const cv::Mat& image, float scale) {
|
||||
|
||||
std::vector<Object> res_boxes;
|
||||
res_boxes.clear();
|
||||
|
||||
std::vector<std::vector<cv::Point>> contours;
|
||||
cv::findContours(bit_map, contours, cv::RETR_LIST, cv::CHAIN_APPROX_SIMPLE);
|
||||
|
||||
int num_coutours = contours.size() >= MAX_CANDIDATES ? MAX_CANDIDATES : contours.size();
|
||||
|
||||
for (int i = 0; i < num_coutours; i++) {
|
||||
if (contours[i].size() <= 2) {
|
||||
continue;
|
||||
}
|
||||
|
||||
float min_side_len;
|
||||
float perimeter;
|
||||
Object text_box;
|
||||
|
||||
std::vector<cv::Point> min_box = get_min_boxes(contours[i], min_side_len, perimeter);
|
||||
|
||||
if (min_side_len < MIN_SIZE)
|
||||
continue;
|
||||
|
||||
// score
|
||||
float score = get_box_score_fast(pred_map, contours[i]);
|
||||
|
||||
if (score < box_score_thresh)
|
||||
continue;
|
||||
|
||||
//--- use clipper
|
||||
std::vector<cv::Point> clip_box = unclip(min_box, perimeter, unclip_ratio);
|
||||
std::vector<cv::Point> clip_min_box = get_min_boxes(clip_box, min_side_len, perimeter);
|
||||
|
||||
if (min_side_len < MIN_SIZE + 2)
|
||||
continue;
|
||||
|
||||
for (int j = 0; j < clip_min_box.size(); ++j) {
|
||||
clip_min_box[j].x = (float)(clip_min_box[j].x / 1.0f);
|
||||
clip_min_box[j].x = std::min(std::max(int(clip_min_box[j].x * scale), 0), image.cols);
|
||||
|
||||
clip_min_box[j].y = (float)(clip_min_box[j].y / 1.0f);
|
||||
clip_min_box[j].y = std::min(std::max(int(clip_min_box[j].y * scale), 0), image.rows);
|
||||
|
||||
text_box.box.push_back(clip_min_box[j]);
|
||||
}
|
||||
|
||||
text_box.score = score;
|
||||
// printf("text detect:%f \n", score);
|
||||
res_boxes.push_back(text_box);
|
||||
}
|
||||
|
||||
return res_boxes;
|
||||
}
|
||||
|
||||
std::vector<cv::Point> get_min_boxes(const std::vector<cv::Point>& in_vec, float& min_side_len, float& perimeter) {
|
||||
std::vector<cv::Point> min_box_vec;
|
||||
cv::RotatedRect text_rect = cv::minAreaRect(in_vec);
|
||||
cv::Mat box_point2f;
|
||||
cv::boxPoints(text_rect, box_point2f);
|
||||
|
||||
float* p1 = (float*) box_point2f.data;
|
||||
std::vector<cv::Point> temp_vec;
|
||||
|
||||
for (int i = 0; i < 4; ++i, p1 += 2) {
|
||||
temp_vec.emplace_back(int(p1[0]), int(p1[1]));
|
||||
}
|
||||
|
||||
std::sort(temp_vec.begin(), temp_vec.end(), cv_point_compare);
|
||||
|
||||
int index1, index2, index3, index4;
|
||||
|
||||
if (temp_vec[1].y > temp_vec[0].y) {
|
||||
index1 = 0;
|
||||
index4 = 1;
|
||||
}
|
||||
else {
|
||||
index1 = 1;
|
||||
index4 = 0;
|
||||
}
|
||||
|
||||
if (temp_vec[3].y > temp_vec[2].y) {
|
||||
index2 = 2;
|
||||
index3 = 3;
|
||||
}
|
||||
else {
|
||||
index2 = 3;
|
||||
index3 = 2;
|
||||
}
|
||||
|
||||
min_box_vec.clear();
|
||||
|
||||
min_box_vec.push_back(temp_vec[index1]);
|
||||
min_box_vec.push_back(temp_vec[index2]);
|
||||
min_box_vec.push_back(temp_vec[index3]);
|
||||
min_box_vec.push_back(temp_vec[index4]);
|
||||
|
||||
min_side_len = std::min(text_rect.size.width, text_rect.size.height);
|
||||
perimeter = 2.f * (text_rect.size.width + text_rect.size.height);
|
||||
|
||||
return min_box_vec;
|
||||
}
|
||||
|
||||
float get_box_score_fast(const cv::Mat& in_mat, const std::vector<cv::Point>& in_box) {
|
||||
std::vector<cv::Point> box = in_box;
|
||||
int width = in_mat.cols;
|
||||
int height = in_mat.rows;
|
||||
|
||||
int max_x = -1;
|
||||
int max_y = -1;
|
||||
int min_x = std::numeric_limits<int>::max();
|
||||
int min_y = std::numeric_limits<int>::max();
|
||||
|
||||
for (int i = 0; i < box.size(); ++i) {
|
||||
if (max_x < box[i].x)
|
||||
max_x = box[i].x;
|
||||
if (max_y < box[i].y)
|
||||
max_y = box[i].y;
|
||||
if (min_x > box[i].x)
|
||||
min_x = box[i].x;
|
||||
if (min_y > box[i].y)
|
||||
min_y = box[i].y;
|
||||
}
|
||||
|
||||
max_x = std::min(std::max(max_x, 0), width - 1);
|
||||
max_y = std::min(std::max(max_y, 0), height - 1);
|
||||
min_x = std::max(std::min(min_x, width - 1), 0);
|
||||
min_y = std::max(std::min(min_y, height - 1), 0);
|
||||
|
||||
for (int i = 0; i < box.size(); ++i) {
|
||||
box[i].x = box[i].x - min_x;
|
||||
box[i].y = box[i].y - min_y;
|
||||
}
|
||||
|
||||
std::vector<std::vector<cv::Point>> mask_box;
|
||||
mask_box.push_back(box);
|
||||
|
||||
cv::Mat mask_mat(max_y - min_y + 1, max_x - min_x + 1, CV_8UC1, cv::Scalar(0, 0, 0));
|
||||
cv::fillPoly(mask_mat, mask_box, cv::Scalar(1, 1, 1), 1);
|
||||
|
||||
return cv::mean(in_mat(cv::Rect(cv::Point(min_x, min_y), cv::Point(max_x + 1, max_y + 1))).clone(), mask_mat).val[0];
|
||||
}
|
||||
|
||||
std::vector<cv::Point> unclip(const std::vector<cv::Point>& in_box, float perimeter, float unclip_ratio) {
|
||||
std::vector<cv::Point> out_box;
|
||||
ClipperLib::Path poly;
|
||||
|
||||
for (int i = 0; i < in_box.size(); ++i) {
|
||||
poly.push_back(ClipperLib::IntPoint(in_box[i].x, in_box[i].y));
|
||||
}
|
||||
|
||||
double distance = unclip_ratio * ClipperLib::Area(poly) / (double) perimeter;
|
||||
|
||||
ClipperLib::ClipperOffset clipper_offset;
|
||||
clipper_offset.AddPath(poly, ClipperLib::JoinType::jtRound, ClipperLib::EndType::etClosedPolygon);
|
||||
ClipperLib::Paths polys;
|
||||
polys.push_back(poly);
|
||||
clipper_offset.Execute(polys, distance);
|
||||
|
||||
out_box.clear();
|
||||
|
||||
for (int i = 0; i < polys.size(); ++i) {
|
||||
ClipperLib::Path temp_poly = polys[i];
|
||||
for (int j = 0; j < temp_poly.size(); ++j) {
|
||||
out_box.emplace_back(temp_poly[j].X, temp_poly[j].Y);
|
||||
}
|
||||
}
|
||||
|
||||
return out_box;
|
||||
}
|
||||
|
||||
bool cv_point_compare(const cv::Point& a, const cv::Point& b) {
|
||||
return a.x < b.x;
|
||||
}
|
||||
|
||||
cv::Mat draw_objects(cv::Mat image, const std::vector<Object>& results) {
|
||||
for (int i = 0; i < results.size(); i++) {
|
||||
cv::polylines(image, results[i].box, true, cv::Scalar(0, 0, 255), 2);
|
||||
}
|
||||
|
||||
return image;
|
||||
}
|
||||
61
examples/ppocr-det/cpp/src/postprocess.h
Executable file
61
examples/ppocr-det/cpp/src/postprocess.h
Executable file
|
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
* Copyright (C) 2024–2025 Amlogic, Inc. 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.
|
||||
*/
|
||||
|
||||
#ifndef __AMLNN_PADDLEOCR_DET_DEMO_POSTPROCESS_H__
|
||||
#define __AMLNN_PADDLEOCR_DET_DEMO_POSTPROCESS_H__
|
||||
|
||||
#include <opencv2/opencv.hpp>
|
||||
#include <vector>
|
||||
|
||||
#include "nn_sdk.h"
|
||||
|
||||
const int MIN_SIZE = 3;
|
||||
const int MAX_CANDIDATES = 1000;
|
||||
const int MODEL_INPUT_WIDTH = 640;
|
||||
const int MODEL_INPUT_HEIGHT = 640;
|
||||
const int MODEL_INPUT_CHANNELS = 3;
|
||||
const float BOX_SCORE_THRESH = 0.5;
|
||||
const float BOX_THRESH = 0.3;
|
||||
|
||||
typedef struct {
|
||||
float score;
|
||||
|
||||
std::vector<cv::Point> box;
|
||||
} Object;
|
||||
|
||||
void* run_paddleocr_network(void* qcontext, cv::Mat& image, const int width, const int height, const int channel);
|
||||
|
||||
int preprocess(const cv::Mat& image, cv::Mat& pre_image, const int width, const int height, float& scale );
|
||||
|
||||
int postprocess(float* out, const cv::Mat& image, float box_score_thresh, float box_thresh, std::vector<Object>& result, float scale);
|
||||
|
||||
std::vector<Object> find_box(const cv::Mat pred_map, const cv::Mat& bit_map,
|
||||
const float box_score_thresh, const float unclip_ratio,
|
||||
const cv::Mat& image, float scale);
|
||||
|
||||
std::vector<cv::Point> get_min_boxes(const std::vector<cv::Point>& in_vec,
|
||||
float& min_side_len, float& perimeter);
|
||||
|
||||
float get_box_score_fast(const cv::Mat& in_mat, const std::vector<cv::Point>& in_box);
|
||||
|
||||
std::vector<cv::Point> unclip(const std::vector<cv::Point>& in_box, float perimeter, float unclip_ratio);
|
||||
|
||||
bool cv_point_compare(const cv::Point& a, const cv::Point& b);
|
||||
|
||||
cv::Mat draw_objects(cv::Mat image, const std::vector<Object>& results);
|
||||
|
||||
|
||||
#endif
|
||||
Loading…
Add table
Add a link
Reference in a new issue