CPP: emplace_back() replaces many push_back()...to improve performance (#14610)
parent
19c58a3974
commit
42a3c77309
|
@ -86,10 +86,17 @@ struct IntPoint {
|
|||
#ifdef use_xyz
|
||||
cInt Z;
|
||||
IntPoint(cInt x = 0, cInt y = 0, cInt z = 0) : X(x), Y(y), Z(z){};
|
||||
IntPoint(IntPoint const &ip) : X(ip.X), Y(ip.Y), Z(ip.Z) {}
|
||||
#else
|
||||
IntPoint(cInt x = 0, cInt y = 0) : X(x), Y(y){};
|
||||
IntPoint(IntPoint const &ip) : 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) {
|
||||
return a.X == b.X && a.Y == b.Y;
|
||||
}
|
||||
|
@ -102,12 +109,12 @@ struct IntPoint {
|
|||
typedef std::vector<IntPoint> Path;
|
||||
typedef std::vector<Path> Paths;
|
||||
|
||||
inline Path &operator<<(Path &poly, const IntPoint &p) {
|
||||
poly.push_back(p);
|
||||
inline Path &operator<<(Path &poly, IntPoint &&p) {
|
||||
poly.emplace_back(std::forward<IntPoint>(p));
|
||||
return poly;
|
||||
}
|
||||
inline Paths &operator<<(Paths &polys, const Path &p) {
|
||||
polys.push_back(p);
|
||||
inline Paths &operator<<(Paths &polys, Path &&p) {
|
||||
polys.emplace_back(std::forward<Path>(p));
|
||||
return polys;
|
||||
}
|
||||
|
||||
|
@ -118,8 +125,12 @@ 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) {}
|
||||
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;
|
||||
}
|
||||
};
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
|
|
|
@ -48,7 +48,7 @@ public:
|
|||
// Load Paddle inference model
|
||||
void LoadModel(const std::string &model_dir);
|
||||
|
||||
void Run(std::vector<cv::Mat> img_list, std::vector<int> &cls_labels,
|
||||
void Run(const std::vector<cv::Mat> &img_list, std::vector<int> &cls_labels,
|
||||
std::vector<float> &cls_scores, std::vector<double> ×);
|
||||
|
||||
private:
|
||||
|
|
|
@ -59,7 +59,8 @@ public:
|
|||
void LoadModel(const std::string &model_dir);
|
||||
|
||||
// Run predictor
|
||||
void Run(cv::Mat &img, std::vector<std::vector<std::vector<int>>> &boxes,
|
||||
void Run(const cv::Mat &img,
|
||||
std::vector<std::vector<std::vector<int>>> &boxes,
|
||||
std::vector<double> ×);
|
||||
|
||||
private:
|
||||
|
|
|
@ -46,9 +46,9 @@ public:
|
|||
this->rec_image_shape_ = rec_image_shape;
|
||||
|
||||
this->label_list_ = Utility::ReadDict(label_path);
|
||||
this->label_list_.insert(this->label_list_.begin(),
|
||||
"#"); // blank char for ctc
|
||||
this->label_list_.push_back(" ");
|
||||
this->label_list_.emplace(this->label_list_.begin(),
|
||||
"#"); // blank char for ctc
|
||||
this->label_list_.emplace_back(" ");
|
||||
|
||||
LoadModel(model_dir);
|
||||
}
|
||||
|
@ -56,7 +56,8 @@ public:
|
|||
// Load Paddle inference model
|
||||
void LoadModel(const std::string &model_dir);
|
||||
|
||||
void Run(std::vector<cv::Mat> img_list, std::vector<std::string> &rec_texts,
|
||||
void Run(const std::vector<cv::Mat> &img_list,
|
||||
std::vector<std::string> &rec_texts,
|
||||
std::vector<float> &rec_text_scores, std::vector<double> ×);
|
||||
|
||||
private:
|
||||
|
|
|
@ -23,13 +23,12 @@ namespace PaddleOCR {
|
|||
class PPOCR {
|
||||
public:
|
||||
explicit PPOCR();
|
||||
~PPOCR() = default;
|
||||
virtual ~PPOCR(){};
|
||||
|
||||
std::vector<std::vector<OCRPredictResult>> ocr(std::vector<cv::Mat> img_list,
|
||||
bool det = true,
|
||||
bool rec = true,
|
||||
bool cls = true);
|
||||
std::vector<OCRPredictResult> ocr(cv::Mat img, bool det = true,
|
||||
std::vector<std::vector<OCRPredictResult>>
|
||||
ocr(const std::vector<cv::Mat> &img_list, bool det = true, bool rec = true,
|
||||
bool cls = true);
|
||||
std::vector<OCRPredictResult> ocr(const cv::Mat &img, bool det = true,
|
||||
bool rec = true, bool cls = true);
|
||||
|
||||
void reset_timer();
|
||||
|
@ -40,10 +39,10 @@ protected:
|
|||
std::vector<double> time_info_rec = {0, 0, 0};
|
||||
std::vector<double> time_info_cls = {0, 0, 0};
|
||||
|
||||
void det(cv::Mat img, std::vector<OCRPredictResult> &ocr_results);
|
||||
void rec(std::vector<cv::Mat> img_list,
|
||||
void det(const cv::Mat &img, std::vector<OCRPredictResult> &ocr_results);
|
||||
void rec(const std::vector<cv::Mat> &img_list,
|
||||
std::vector<OCRPredictResult> &ocr_results);
|
||||
void cls(std::vector<cv::Mat> img_list,
|
||||
void cls(const std::vector<cv::Mat> &img_list,
|
||||
std::vector<OCRPredictResult> &ocr_results);
|
||||
|
||||
private:
|
||||
|
|
|
@ -25,7 +25,7 @@ public:
|
|||
explicit PaddleStructure();
|
||||
~PaddleStructure() = default;
|
||||
|
||||
std::vector<StructurePredictResult> structure(cv::Mat img,
|
||||
std::vector<StructurePredictResult> structure(const cv::Mat &img,
|
||||
bool layout = false,
|
||||
bool table = true,
|
||||
bool ocr = false);
|
||||
|
@ -40,16 +40,16 @@ private:
|
|||
std::unique_ptr<StructureTableRecognizer> table_model_;
|
||||
std::unique_ptr<StructureLayoutRecognizer> layout_model_;
|
||||
|
||||
void layout(cv::Mat img,
|
||||
void layout(const cv::Mat &img,
|
||||
std::vector<StructurePredictResult> &structure_result);
|
||||
|
||||
void table(cv::Mat img, StructurePredictResult &structure_result);
|
||||
void table(const cv::Mat &img, StructurePredictResult &structure_result);
|
||||
|
||||
std::string rebuild_table(std::vector<std::string> rec_html_tags,
|
||||
std::vector<std::vector<int>> rec_boxes,
|
||||
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);
|
||||
|
||||
float dis(std::vector<int> &box1, std::vector<int> &box2);
|
||||
float dis(const std::vector<int> &box1, const std::vector<int> &box2);
|
||||
|
||||
static bool comparison_dis(const std::vector<float> &dis1,
|
||||
const std::vector<float> &dis2) {
|
||||
|
|
|
@ -24,41 +24,43 @@ public:
|
|||
void GetContourArea(const std::vector<std::vector<float>> &box,
|
||||
float unclip_ratio, float &distance);
|
||||
|
||||
cv::RotatedRect UnClip(std::vector<std::vector<float>> box,
|
||||
cv::RotatedRect UnClip(const std::vector<std::vector<float>> &box,
|
||||
const float &unclip_ratio);
|
||||
|
||||
float **Mat2Vec(cv::Mat mat);
|
||||
float **Mat2Vec(const cv::Mat &mat);
|
||||
|
||||
std::vector<std::vector<int>>
|
||||
OrderPointsClockwise(std::vector<std::vector<int>> pts);
|
||||
OrderPointsClockwise(const std::vector<std::vector<int>> &pts);
|
||||
|
||||
std::vector<std::vector<float>> GetMiniBoxes(cv::RotatedRect box,
|
||||
std::vector<std::vector<float>> GetMiniBoxes(const cv::RotatedRect &box,
|
||||
float &ssid);
|
||||
|
||||
float BoxScoreFast(std::vector<std::vector<float>> box_array, cv::Mat pred);
|
||||
float PolygonScoreAcc(std::vector<cv::Point> contour, cv::Mat pred);
|
||||
float BoxScoreFast(const std::vector<std::vector<float>> &box_array,
|
||||
const cv::Mat &pred);
|
||||
float PolygonScoreAcc(const std::vector<cv::Point> &contour,
|
||||
const cv::Mat &pred);
|
||||
|
||||
std::vector<std::vector<std::vector<int>>>
|
||||
BoxesFromBitmap(const cv::Mat pred, const cv::Mat bitmap,
|
||||
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);
|
||||
|
||||
std::vector<std::vector<std::vector<int>>>
|
||||
FilterTagDetRes(std::vector<std::vector<std::vector<int>>> boxes,
|
||||
float ratio_h, float ratio_w, cv::Mat srcimg);
|
||||
void FilterTagDetRes(std::vector<std::vector<std::vector<int>>> &boxes,
|
||||
float ratio_h, float ratio_w, const cv::Mat &srcimg);
|
||||
|
||||
private:
|
||||
static bool XsortInt(std::vector<int> a, std::vector<int> b);
|
||||
static bool XsortInt(const std::vector<int> &a, const std::vector<int> &b);
|
||||
|
||||
static bool XsortFp32(std::vector<float> a, std::vector<float> b);
|
||||
static bool XsortFp32(const std::vector<float> &a,
|
||||
const std::vector<float> &b);
|
||||
|
||||
std::vector<std::vector<float>> Mat2Vector(cv::Mat mat);
|
||||
std::vector<std::vector<float>> Mat2Vector(const cv::Mat &mat);
|
||||
|
||||
inline int _max(int a, int b) { return a >= b ? a : b; }
|
||||
inline int _max(int a, int b) const noexcept { return a >= b ? a : b; }
|
||||
|
||||
inline int _min(int a, int b) { return a >= b ? b : a; }
|
||||
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) {
|
||||
template <class T> inline T clamp(T x, T min, T max) const noexcept {
|
||||
if (x > max)
|
||||
return max;
|
||||
if (x < min)
|
||||
|
@ -66,7 +68,7 @@ private:
|
|||
return x;
|
||||
}
|
||||
|
||||
inline float clampf(float x, float min, float max) {
|
||||
inline float clampf(float x, float min, float max) const noexcept {
|
||||
if (x > max)
|
||||
return max;
|
||||
if (x < min)
|
||||
|
@ -77,37 +79,45 @@ private:
|
|||
|
||||
class TablePostProcessor {
|
||||
public:
|
||||
void init(std::string label_path, bool merge_no_span_structure = true);
|
||||
void Run(std::vector<float> &loc_preds, std::vector<float> &structure_probs,
|
||||
std::vector<float> &rec_scores, std::vector<int> &loc_preds_shape,
|
||||
std::vector<int> &structure_probs_shape,
|
||||
void init(const std::string &label_path, bool merge_no_span_structure = true);
|
||||
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,
|
||||
std::vector<int> &width_list, std::vector<int> &height_list);
|
||||
const std::vector<int> &width_list,
|
||||
const std::vector<int> &height_list);
|
||||
|
||||
private:
|
||||
std::vector<std::string> label_list_;
|
||||
std::string end = "eos";
|
||||
std::string beg = "sos";
|
||||
const std::string end = "eos";
|
||||
const std::string beg = "sos";
|
||||
};
|
||||
|
||||
class PicodetPostProcessor {
|
||||
public:
|
||||
void init(std::string label_path, const double score_threshold = 0.4,
|
||||
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});
|
||||
void Run(std::vector<StructurePredictResult> &results,
|
||||
std::vector<std::vector<float>> outs, std::vector<int> ori_shape,
|
||||
std::vector<int> resize_shape, int eg_max);
|
||||
std::vector<int> fpn_stride_ = {8, 16, 32, 64};
|
||||
const std::vector<std::vector<float>> &outs,
|
||||
const std::vector<int> &ori_shape,
|
||||
const std::vector<int> &resize_shape, int eg_max);
|
||||
inline size_t fpn_stride_size() const { return fpn_stride_.size(); }
|
||||
|
||||
private:
|
||||
StructurePredictResult disPred2Bbox(std::vector<float> bbox_pred, int label,
|
||||
float score, int x, int y, int stride,
|
||||
std::vector<int> im_shape, int reg_max);
|
||||
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);
|
||||
void nms(std::vector<StructurePredictResult> &input_boxes,
|
||||
float nms_threshold);
|
||||
|
||||
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;
|
||||
|
|
|
@ -25,26 +25,26 @@ namespace PaddleOCR {
|
|||
|
||||
class Normalize {
|
||||
public:
|
||||
virtual void Run(cv::Mat *im, const std::vector<float> &mean,
|
||||
virtual void Run(cv::Mat &im, const std::vector<float> &mean,
|
||||
const std::vector<float> &scale, const bool is_scale = true);
|
||||
};
|
||||
|
||||
// RGB -> CHW
|
||||
class Permute {
|
||||
public:
|
||||
virtual void Run(const cv::Mat *im, float *data);
|
||||
virtual void Run(const cv::Mat &im, float *data);
|
||||
};
|
||||
|
||||
class PermuteBatch {
|
||||
public:
|
||||
virtual void Run(const std::vector<cv::Mat> imgs, float *data);
|
||||
virtual void Run(const std::vector<cv::Mat> &imgs, float *data);
|
||||
};
|
||||
|
||||
class ResizeImgType0 {
|
||||
public:
|
||||
virtual void Run(const cv::Mat &img, cv::Mat &resize_img,
|
||||
std::string limit_type, int limit_side_len, float &ratio_h,
|
||||
float &ratio_w, bool use_tensorrt);
|
||||
const std::string &limit_type, int limit_side_len,
|
||||
float &ratio_h, float &ratio_w, bool use_tensorrt);
|
||||
};
|
||||
|
||||
class CrnnResizeImg {
|
||||
|
|
|
@ -47,7 +47,7 @@ public:
|
|||
// Load Paddle inference model
|
||||
void LoadModel(const std::string &model_dir);
|
||||
|
||||
void Run(cv::Mat img, std::vector<StructurePredictResult> &result,
|
||||
void Run(const cv::Mat &img, std::vector<StructurePredictResult> &result,
|
||||
std::vector<double> ×);
|
||||
|
||||
private:
|
||||
|
|
|
@ -48,7 +48,7 @@ public:
|
|||
// Load Paddle inference model
|
||||
void LoadModel(const std::string &model_dir);
|
||||
|
||||
void Run(std::vector<cv::Mat> img_list,
|
||||
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,
|
||||
|
|
|
@ -71,7 +71,7 @@ public:
|
|||
std::vector<std::string> &all_inputs);
|
||||
|
||||
static cv::Mat GetRotateCropImage(const cv::Mat &srcimage,
|
||||
std::vector<std::vector<int>> box);
|
||||
const std::vector<std::vector<int>> &box);
|
||||
|
||||
static std::vector<int> argsort(const std::vector<float> &array);
|
||||
|
||||
|
@ -88,8 +88,9 @@ public:
|
|||
|
||||
static void sorted_boxes(std::vector<OCRPredictResult> &ocr_result);
|
||||
|
||||
static std::vector<int> xyxyxyxy2xyxy(std::vector<std::vector<int>> &box);
|
||||
static std::vector<int> xyxyxyxy2xyxy(std::vector<int> &box);
|
||||
static std::vector<int>
|
||||
xyxyxyxy2xyxy(const std::vector<std::vector<int>> &box);
|
||||
static std::vector<int> xyxyxyxy2xyxy(const std::vector<int> &box);
|
||||
|
||||
static float fast_exp(float x);
|
||||
static std::vector<float>
|
||||
|
|
|
@ -178,7 +178,7 @@ int PolyNode::ChildCount() const { return (int)Childs.size(); }
|
|||
|
||||
void PolyNode::AddChild(PolyNode &child) {
|
||||
unsigned cnt = (unsigned)Childs.size();
|
||||
Childs.push_back(&child);
|
||||
Childs.emplace_back(&child);
|
||||
child.Parent = this;
|
||||
child.Index = cnt;
|
||||
}
|
||||
|
@ -513,7 +513,7 @@ bool SlopesEqual(const TEdge &e1, const TEdge &e2, bool UseFullInt64Range) {
|
|||
}
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
bool SlopesEqual(const IntPoint pt1, const IntPoint pt2, const IntPoint pt3,
|
||||
bool SlopesEqual(const IntPoint &pt1, const IntPoint &pt2, const IntPoint &pt3,
|
||||
bool UseFullInt64Range) {
|
||||
#ifndef use_int32
|
||||
if (UseFullInt64Range)
|
||||
|
@ -526,8 +526,8 @@ bool SlopesEqual(const IntPoint pt1, const IntPoint pt2, const IntPoint pt3,
|
|||
}
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
bool SlopesEqual(const IntPoint pt1, const IntPoint pt2, const IntPoint pt3,
|
||||
const IntPoint pt4, bool UseFullInt64Range) {
|
||||
bool SlopesEqual(const IntPoint &pt1, const IntPoint &pt2, const IntPoint &pt3,
|
||||
const IntPoint &pt4, bool UseFullInt64Range) {
|
||||
#ifndef use_int32
|
||||
if (UseFullInt64Range)
|
||||
return Int128Mul(pt1.Y - pt2.Y, pt3.X - pt4.X) ==
|
||||
|
@ -542,7 +542,7 @@ bool SlopesEqual(const IntPoint pt1, const IntPoint pt2, const IntPoint pt3,
|
|||
inline bool IsHorizontal(TEdge &e) { return e.Dx == HORIZONTAL; }
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
inline double GetDx(const IntPoint pt1, const IntPoint pt2) {
|
||||
inline double GetDx(const IntPoint &pt1, const IntPoint &pt2) {
|
||||
return (pt1.Y == pt2.Y) ? HORIZONTAL
|
||||
: (double)(pt2.X - pt1.X) / (pt2.Y - pt1.Y);
|
||||
}
|
||||
|
@ -914,7 +914,7 @@ TEdge *ClipperBase::ProcessBound(TEdge *E, bool NextIsForward) {
|
|||
locMin.RightBound = E;
|
||||
E->WindDelta = 0;
|
||||
Result = ProcessBound(E, NextIsForward);
|
||||
m_MinimaList.push_back(locMin);
|
||||
m_MinimaList.emplace_back(std::move(locMin));
|
||||
}
|
||||
return Result;
|
||||
}
|
||||
|
@ -1105,12 +1105,12 @@ bool ClipperBase::AddPath(const Path &pg, PolyType PolyTyp, bool Closed) {
|
|||
E->NextInLML = E->Next;
|
||||
E = E->Next;
|
||||
}
|
||||
m_MinimaList.push_back(locMin);
|
||||
m_edges.push_back(edges);
|
||||
m_MinimaList.emplace_back(std::move(locMin));
|
||||
m_edges.emplace_back(edges);
|
||||
return true;
|
||||
}
|
||||
|
||||
m_edges.push_back(edges);
|
||||
m_edges.emplace_back(edges);
|
||||
bool leftBoundIsForward;
|
||||
TEdge *EMin = 0;
|
||||
|
||||
|
@ -1160,7 +1160,7 @@ bool ClipperBase::AddPath(const Path &pg, PolyType PolyTyp, bool Closed) {
|
|||
locMin.LeftBound = 0;
|
||||
else if (locMin.RightBound->OutIdx == Skip)
|
||||
locMin.RightBound = 0;
|
||||
m_MinimaList.push_back(locMin);
|
||||
m_MinimaList.emplace_back(std::move(locMin));
|
||||
if (!leftBoundIsForward)
|
||||
E = E2;
|
||||
}
|
||||
|
@ -1329,7 +1329,7 @@ OutRec *ClipperBase::CreateOutRec() {
|
|||
result->Pts = 0;
|
||||
result->BottomPt = 0;
|
||||
result->PolyNd = 0;
|
||||
m_PolyOuts.push_back(result);
|
||||
m_PolyOuts.emplace_back(result);
|
||||
result->Idx = (int)m_PolyOuts.size() - 1;
|
||||
return result;
|
||||
}
|
||||
|
@ -1858,19 +1858,19 @@ void Clipper::AddJoin(OutPt *op1, OutPt *op2, const IntPoint OffPt) {
|
|||
j->OutPt1 = op1;
|
||||
j->OutPt2 = op2;
|
||||
j->OffPt = OffPt;
|
||||
m_Joins.push_back(j);
|
||||
m_Joins.emplace_back(j);
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
void Clipper::ClearJoins() {
|
||||
for (JoinList::size_type i = 0; i < m_Joins.size(); i++)
|
||||
for (JoinList::size_type i = 0; i < m_Joins.size(); ++i)
|
||||
delete m_Joins[i];
|
||||
m_Joins.resize(0);
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
void Clipper::ClearGhostJoins() {
|
||||
for (JoinList::size_type i = 0; i < m_GhostJoins.size(); i++)
|
||||
for (JoinList::size_type i = 0; i < m_GhostJoins.size(); ++i)
|
||||
delete m_GhostJoins[i];
|
||||
m_GhostJoins.resize(0);
|
||||
}
|
||||
|
@ -1881,7 +1881,7 @@ void Clipper::AddGhostJoin(OutPt *op, const IntPoint OffPt) {
|
|||
j->OutPt1 = op;
|
||||
j->OutPt2 = 0;
|
||||
j->OffPt = OffPt;
|
||||
m_GhostJoins.push_back(j);
|
||||
m_GhostJoins.emplace_back(j);
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
|
@ -2628,10 +2628,10 @@ void Clipper::ProcessHorizontal(TEdge *horzEdge) {
|
|||
}
|
||||
|
||||
if (dir == dLeftToRight) {
|
||||
IntPoint Pt = IntPoint(e->Curr.X, horzEdge->Curr.Y);
|
||||
IntPoint Pt(e->Curr.X, horzEdge->Curr.Y);
|
||||
IntersectEdges(horzEdge, e, Pt);
|
||||
} else {
|
||||
IntPoint Pt = IntPoint(e->Curr.X, horzEdge->Curr.Y);
|
||||
IntPoint Pt(e->Curr.X, horzEdge->Curr.Y);
|
||||
IntersectEdges(e, horzEdge, Pt);
|
||||
}
|
||||
TEdge *eNext = GetNextInAEL(e, dir);
|
||||
|
@ -2751,12 +2751,12 @@ void Clipper::BuildIntersectList(const cInt topY) {
|
|||
if (e->Curr.X > eNext->Curr.X) {
|
||||
IntersectPoint(*e, *eNext, Pt);
|
||||
if (Pt.Y < topY)
|
||||
Pt = IntPoint(TopX(*e, topY), topY);
|
||||
Pt.reset(TopX(*e, topY), topY);
|
||||
IntersectNode *newNode = new IntersectNode;
|
||||
newNode->Edge1 = e;
|
||||
newNode->Edge2 = eNext;
|
||||
newNode->Pt = Pt;
|
||||
m_IntersectList.push_back(newNode);
|
||||
m_IntersectList.emplace_back(newNode);
|
||||
|
||||
SwapPositionsInSEL(e, eNext);
|
||||
isModified = true;
|
||||
|
@ -2877,7 +2877,7 @@ void Clipper::ProcessEdgesAtTopOfScanbeam(const cInt topY) {
|
|||
|
||||
if (IsMaximaEdge) {
|
||||
if (m_StrictSimple)
|
||||
m_Maxima.push_back(e->Top.X);
|
||||
m_Maxima.emplace_back(e->Top.X);
|
||||
TEdge *ePrev = e->PrevInAEL;
|
||||
DoMaxima(e);
|
||||
if (!ePrev)
|
||||
|
@ -3047,10 +3047,10 @@ void Clipper::BuildResult(Paths &polys) {
|
|||
continue;
|
||||
pg.reserve(cnt);
|
||||
for (int i = 0; i < cnt; ++i) {
|
||||
pg.push_back(p->Pt);
|
||||
pg.emplace_back(p->Pt);
|
||||
p = p->Prev;
|
||||
}
|
||||
polys.push_back(pg);
|
||||
polys.emplace_back(pg);
|
||||
}
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
|
@ -3059,7 +3059,7 @@ void Clipper::BuildResult2(PolyTree &polytree) {
|
|||
polytree.Clear();
|
||||
polytree.AllNodes.reserve(m_PolyOuts.size());
|
||||
// add each output polygon/contour to polytree ...
|
||||
for (PolyOutList::size_type i = 0; i < m_PolyOuts.size(); i++) {
|
||||
for (PolyOutList::size_type i = 0; i < m_PolyOuts.size(); ++i) {
|
||||
OutRec *outRec = m_PolyOuts[i];
|
||||
int cnt = PointCount(outRec->Pts);
|
||||
if ((outRec->IsOpen && cnt < 2) || (!outRec->IsOpen && cnt < 3))
|
||||
|
@ -3067,21 +3067,21 @@ void Clipper::BuildResult2(PolyTree &polytree) {
|
|||
FixHoleLinkage(*outRec);
|
||||
PolyNode *pn = new PolyNode();
|
||||
// nb: polytree takes ownership of all the PolyNodes
|
||||
polytree.AllNodes.push_back(pn);
|
||||
polytree.AllNodes.emplace_back(pn);
|
||||
outRec->PolyNd = pn;
|
||||
pn->Parent = 0;
|
||||
pn->Index = 0;
|
||||
pn->Contour.reserve(cnt);
|
||||
OutPt *op = outRec->Pts->Prev;
|
||||
for (int j = 0; j < cnt; j++) {
|
||||
pn->Contour.push_back(op->Pt);
|
||||
pn->Contour.emplace_back(op->Pt);
|
||||
op = op->Prev;
|
||||
}
|
||||
}
|
||||
|
||||
// fixup PolyNode links etc ...
|
||||
polytree.Childs.reserve(m_PolyOuts.size());
|
||||
for (PolyOutList::size_type i = 0; i < m_PolyOuts.size(); i++) {
|
||||
for (PolyOutList::size_type i = 0; i < m_PolyOuts.size(); ++i) {
|
||||
OutRec *outRec = m_PolyOuts[i];
|
||||
if (!outRec->PolyNd)
|
||||
continue;
|
||||
|
@ -3633,12 +3633,12 @@ void ClipperOffset::AddPath(const Path &path, JoinType joinType,
|
|||
while (highI > 0 && path[0] == path[highI])
|
||||
highI--;
|
||||
newNode->Contour.reserve(highI + 1);
|
||||
newNode->Contour.push_back(path[0]);
|
||||
newNode->Contour.emplace_back(path[0]);
|
||||
int j = 0, k = 0;
|
||||
for (int i = 1; i <= highI; i++)
|
||||
for (int i = 1; i <= highI; ++i)
|
||||
if (newNode->Contour[j] != path[i]) {
|
||||
j++;
|
||||
newNode->Contour.push_back(path[i]);
|
||||
newNode->Contour.emplace_back(path[i]);
|
||||
if (path[i].Y > newNode->Contour[k].Y ||
|
||||
(path[i].Y == newNode->Contour[k].Y &&
|
||||
path[i].X < newNode->Contour[k].X))
|
||||
|
@ -3654,12 +3654,12 @@ void ClipperOffset::AddPath(const Path &path, JoinType joinType,
|
|||
if (endType != etClosedPolygon)
|
||||
return;
|
||||
if (m_lowest.X < 0)
|
||||
m_lowest = IntPoint(m_polyNodes.ChildCount() - 1, k);
|
||||
m_lowest.reset(m_polyNodes.ChildCount() - 1, k);
|
||||
else {
|
||||
IntPoint ip = m_polyNodes.Childs[(int)m_lowest.X]->Contour[(int)m_lowest.Y];
|
||||
if (newNode->Contour[k].Y > ip.Y ||
|
||||
(newNode->Contour[k].Y == ip.Y && newNode->Contour[k].X < ip.X))
|
||||
m_lowest = IntPoint(m_polyNodes.ChildCount() - 1, k);
|
||||
m_lowest.reset(m_polyNodes.ChildCount() - 1, k);
|
||||
}
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
|
@ -3705,10 +3705,10 @@ void ClipperOffset::Execute(Paths &solution, double delta) {
|
|||
} else {
|
||||
IntRect r = clpr.GetBounds();
|
||||
Path outer(4);
|
||||
outer[0] = IntPoint(r.left - 10, r.bottom + 10);
|
||||
outer[1] = IntPoint(r.right + 10, r.bottom + 10);
|
||||
outer[2] = IntPoint(r.right + 10, r.top - 10);
|
||||
outer[3] = IntPoint(r.left - 10, r.top - 10);
|
||||
outer[0].reset(r.left - 10, r.bottom + 10);
|
||||
outer[1].reset(r.right + 10, r.bottom + 10);
|
||||
outer[2].reset(r.right + 10, r.top - 10);
|
||||
outer[3].reset(r.left - 10, r.top - 10);
|
||||
|
||||
clpr.AddPath(outer, ptSubject, true);
|
||||
clpr.ReverseSolution(true);
|
||||
|
@ -3732,10 +3732,10 @@ void ClipperOffset::Execute(PolyTree &solution, double delta) {
|
|||
} else {
|
||||
IntRect r = clpr.GetBounds();
|
||||
Path outer(4);
|
||||
outer[0] = IntPoint(r.left - 10, r.bottom + 10);
|
||||
outer[1] = IntPoint(r.right + 10, r.bottom + 10);
|
||||
outer[2] = IntPoint(r.right + 10, r.top - 10);
|
||||
outer[3] = IntPoint(r.left - 10, r.top - 10);
|
||||
outer[0].reset(r.left - 10, r.bottom + 10);
|
||||
outer[1].reset(r.right + 10, r.bottom + 10);
|
||||
outer[2].reset(r.right + 10, r.top - 10);
|
||||
outer[3].reset(r.left - 10, r.top - 10);
|
||||
|
||||
clpr.AddPath(outer, ptSubject, true);
|
||||
clpr.ReverseSolution(true);
|
||||
|
@ -3761,10 +3761,10 @@ void ClipperOffset::DoOffset(double delta) {
|
|||
// if Zero offset, just copy any CLOSED polygons to m_p and return ...
|
||||
if (NEAR_ZERO(delta)) {
|
||||
m_destPolys.reserve(m_polyNodes.ChildCount());
|
||||
for (int i = 0; i < m_polyNodes.ChildCount(); i++) {
|
||||
for (int i = 0; i < m_polyNodes.ChildCount(); ++i) {
|
||||
PolyNode &node = *m_polyNodes.Childs[i];
|
||||
if (node.m_endtype == etClosedPolygon)
|
||||
m_destPolys.push_back(node.Contour);
|
||||
m_destPolys.emplace_back(node.Contour);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
@ -3793,7 +3793,7 @@ void ClipperOffset::DoOffset(double delta) {
|
|||
m_sin = -m_sin;
|
||||
|
||||
m_destPolys.reserve(m_polyNodes.ChildCount() * 2);
|
||||
for (int i = 0; i < m_polyNodes.ChildCount(); i++) {
|
||||
for (int i = 0; i < m_polyNodes.ChildCount(); ++i) {
|
||||
PolyNode &node = *m_polyNodes.Childs[i];
|
||||
m_srcPoly = node.Contour;
|
||||
|
||||
|
@ -3807,8 +3807,8 @@ void ClipperOffset::DoOffset(double delta) {
|
|||
if (node.m_jointype == jtRound) {
|
||||
double X = 1.0, Y = 0.0;
|
||||
for (cInt j = 1; j <= steps; j++) {
|
||||
m_destPoly.push_back(IntPoint(Round(m_srcPoly[0].X + X * delta),
|
||||
Round(m_srcPoly[0].Y + Y * delta)));
|
||||
m_destPoly.emplace_back(Round(m_srcPoly[0].X + X * delta),
|
||||
Round(m_srcPoly[0].Y + Y * delta));
|
||||
double X2 = X;
|
||||
X = X * m_cos - m_sin * Y;
|
||||
Y = X2 * m_sin + Y * m_cos;
|
||||
|
@ -3816,8 +3816,8 @@ void ClipperOffset::DoOffset(double delta) {
|
|||
} else {
|
||||
double X = -1.0, Y = -1.0;
|
||||
for (int j = 0; j < 4; ++j) {
|
||||
m_destPoly.push_back(IntPoint(Round(m_srcPoly[0].X + X * delta),
|
||||
Round(m_srcPoly[0].Y + Y * delta)));
|
||||
m_destPoly.emplace_back(Round(m_srcPoly[0].X + X * delta),
|
||||
Round(m_srcPoly[0].Y + Y * delta));
|
||||
if (X < 0)
|
||||
X = 1;
|
||||
else if (Y < 0)
|
||||
|
@ -3826,58 +3826,57 @@ void ClipperOffset::DoOffset(double delta) {
|
|||
X = -1;
|
||||
}
|
||||
}
|
||||
m_destPolys.push_back(m_destPoly);
|
||||
m_destPolys.emplace_back(m_destPoly);
|
||||
continue;
|
||||
}
|
||||
// build m_normals ...
|
||||
m_normals.clear();
|
||||
m_normals.reserve(len);
|
||||
for (int j = 0; j < len - 1; ++j)
|
||||
m_normals.push_back(GetUnitNormal(m_srcPoly[j], m_srcPoly[j + 1]));
|
||||
m_normals.emplace_back(GetUnitNormal(m_srcPoly[j], m_srcPoly[j + 1]));
|
||||
if (node.m_endtype == etClosedLine || node.m_endtype == etClosedPolygon)
|
||||
m_normals.push_back(GetUnitNormal(m_srcPoly[len - 1], m_srcPoly[0]));
|
||||
m_normals.emplace_back(GetUnitNormal(m_srcPoly[len - 1], m_srcPoly[0]));
|
||||
else
|
||||
m_normals.push_back(DoublePoint(m_normals[len - 2]));
|
||||
m_normals.emplace_back(m_normals[len - 2]);
|
||||
|
||||
if (node.m_endtype == etClosedPolygon) {
|
||||
int k = len - 1;
|
||||
for (int j = 0; j < len; ++j)
|
||||
OffsetPoint(j, k, node.m_jointype);
|
||||
m_destPolys.push_back(m_destPoly);
|
||||
m_destPolys.emplace_back(m_destPoly);
|
||||
} else if (node.m_endtype == etClosedLine) {
|
||||
int k = len - 1;
|
||||
for (int j = 0; j < len; ++j)
|
||||
OffsetPoint(j, k, node.m_jointype);
|
||||
m_destPolys.push_back(m_destPoly);
|
||||
m_destPolys.emplace_back(m_destPoly);
|
||||
m_destPoly.clear();
|
||||
// re-build m_normals ...
|
||||
DoublePoint n = m_normals[len - 1];
|
||||
for (int j = len - 1; j > 0; j--)
|
||||
m_normals[j] = DoublePoint(-m_normals[j - 1].X, -m_normals[j - 1].Y);
|
||||
m_normals[0] = DoublePoint(-n.X, -n.Y);
|
||||
m_normals[j].reset(-m_normals[j - 1].X, -m_normals[j - 1].Y);
|
||||
m_normals[0].reset(-n.X, -n.Y);
|
||||
k = 0;
|
||||
for (int j = len - 1; j >= 0; j--)
|
||||
OffsetPoint(j, k, node.m_jointype);
|
||||
m_destPolys.push_back(m_destPoly);
|
||||
m_destPolys.emplace_back(m_destPoly);
|
||||
} else {
|
||||
int k = 0;
|
||||
for (int j = 1; j < len - 1; ++j)
|
||||
OffsetPoint(j, k, node.m_jointype);
|
||||
|
||||
IntPoint pt1;
|
||||
if (node.m_endtype == etOpenButt) {
|
||||
int j = len - 1;
|
||||
pt1 = IntPoint((cInt)Round(m_srcPoly[j].X + m_normals[j].X * delta),
|
||||
(cInt)Round(m_srcPoly[j].Y + m_normals[j].Y * delta));
|
||||
m_destPoly.push_back(pt1);
|
||||
pt1 = IntPoint((cInt)Round(m_srcPoly[j].X - m_normals[j].X * delta),
|
||||
(cInt)Round(m_srcPoly[j].Y - m_normals[j].Y * delta));
|
||||
m_destPoly.push_back(pt1);
|
||||
m_destPoly.emplace_back(
|
||||
(cInt)Round(m_srcPoly[j].X + m_normals[j].X * delta),
|
||||
(cInt)Round(m_srcPoly[j].Y + m_normals[j].Y * delta));
|
||||
m_destPoly.emplace_back(
|
||||
(cInt)Round(m_srcPoly[j].X - m_normals[j].X * delta),
|
||||
(cInt)Round(m_srcPoly[j].Y - m_normals[j].Y * delta));
|
||||
} else {
|
||||
int j = len - 1;
|
||||
k = len - 2;
|
||||
m_sinA = 0;
|
||||
m_normals[j] = DoublePoint(-m_normals[j].X, -m_normals[j].Y);
|
||||
m_normals[j].reset(-m_normals[j].X, -m_normals[j].Y);
|
||||
if (node.m_endtype == etOpenSquare)
|
||||
DoSquare(j, k);
|
||||
else
|
||||
|
@ -3886,20 +3885,20 @@ void ClipperOffset::DoOffset(double delta) {
|
|||
|
||||
// re-build m_normals ...
|
||||
for (int j = len - 1; j > 0; j--)
|
||||
m_normals[j] = DoublePoint(-m_normals[j - 1].X, -m_normals[j - 1].Y);
|
||||
m_normals[0] = DoublePoint(-m_normals[1].X, -m_normals[1].Y);
|
||||
m_normals[j].reset(-m_normals[j - 1].X, -m_normals[j - 1].Y);
|
||||
m_normals[0].reset(-m_normals[1].X, -m_normals[1].Y);
|
||||
|
||||
k = len - 1;
|
||||
for (int j = k - 1; j > 0; --j)
|
||||
OffsetPoint(j, k, node.m_jointype);
|
||||
|
||||
if (node.m_endtype == etOpenButt) {
|
||||
pt1 = IntPoint((cInt)Round(m_srcPoly[0].X - m_normals[0].X * delta),
|
||||
(cInt)Round(m_srcPoly[0].Y - m_normals[0].Y * delta));
|
||||
m_destPoly.push_back(pt1);
|
||||
pt1 = IntPoint((cInt)Round(m_srcPoly[0].X + m_normals[0].X * delta),
|
||||
(cInt)Round(m_srcPoly[0].Y + m_normals[0].Y * delta));
|
||||
m_destPoly.push_back(pt1);
|
||||
m_destPoly.emplace_back(
|
||||
(cInt)Round(m_srcPoly[0].X - m_normals[0].X * delta),
|
||||
(cInt)Round(m_srcPoly[0].Y - m_normals[0].Y * delta));
|
||||
m_destPoly.emplace_back(
|
||||
(cInt)Round(m_srcPoly[0].X + m_normals[0].X * delta),
|
||||
(cInt)Round(m_srcPoly[0].Y + m_normals[0].Y * delta));
|
||||
} else {
|
||||
k = 1;
|
||||
m_sinA = 0;
|
||||
|
@ -3908,7 +3907,7 @@ void ClipperOffset::DoOffset(double delta) {
|
|||
else
|
||||
DoRound(0, 1);
|
||||
}
|
||||
m_destPolys.push_back(m_destPoly);
|
||||
m_destPolys.emplace_back(m_destPoly);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3923,9 +3922,8 @@ void ClipperOffset::OffsetPoint(int j, int &k, JoinType jointype) {
|
|||
(m_normals[k].X * m_normals[j].X + m_normals[j].Y * m_normals[k].Y);
|
||||
if (cosA > 0) // angle => 0 degrees
|
||||
{
|
||||
m_destPoly.push_back(
|
||||
IntPoint(Round(m_srcPoly[j].X + m_normals[k].X * m_delta),
|
||||
Round(m_srcPoly[j].Y + m_normals[k].Y * m_delta)));
|
||||
m_destPoly.emplace_back(Round(m_srcPoly[j].X + m_normals[k].X * m_delta),
|
||||
Round(m_srcPoly[j].Y + m_normals[k].Y * m_delta));
|
||||
return;
|
||||
}
|
||||
// else angle => 180 degrees
|
||||
|
@ -3935,13 +3933,11 @@ void ClipperOffset::OffsetPoint(int j, int &k, JoinType jointype) {
|
|||
m_sinA = -1.0;
|
||||
|
||||
if (m_sinA * m_delta < 0) {
|
||||
m_destPoly.push_back(
|
||||
IntPoint(Round(m_srcPoly[j].X + m_normals[k].X * m_delta),
|
||||
Round(m_srcPoly[j].Y + m_normals[k].Y * m_delta)));
|
||||
m_destPoly.push_back(m_srcPoly[j]);
|
||||
m_destPoly.push_back(
|
||||
IntPoint(Round(m_srcPoly[j].X + m_normals[j].X * m_delta),
|
||||
Round(m_srcPoly[j].Y + m_normals[j].Y * m_delta)));
|
||||
m_destPoly.emplace_back(Round(m_srcPoly[j].X + m_normals[k].X * m_delta),
|
||||
Round(m_srcPoly[j].Y + m_normals[k].Y * m_delta));
|
||||
m_destPoly.emplace_back(m_srcPoly[j]);
|
||||
m_destPoly.emplace_back(Round(m_srcPoly[j].X + m_normals[j].X * m_delta),
|
||||
Round(m_srcPoly[j].Y + m_normals[j].Y * m_delta));
|
||||
} else
|
||||
switch (jointype) {
|
||||
case jtMiter: {
|
||||
|
@ -3968,22 +3964,20 @@ void ClipperOffset::DoSquare(int j, int k) {
|
|||
double dx = std::tan(std::atan2(m_sinA, m_normals[k].X * m_normals[j].X +
|
||||
m_normals[k].Y * m_normals[j].Y) /
|
||||
4);
|
||||
m_destPoly.push_back(IntPoint(
|
||||
m_destPoly.emplace_back(
|
||||
Round(m_srcPoly[j].X + m_delta * (m_normals[k].X - m_normals[k].Y * dx)),
|
||||
Round(m_srcPoly[j].Y +
|
||||
m_delta * (m_normals[k].Y + m_normals[k].X * dx))));
|
||||
m_destPoly.push_back(IntPoint(
|
||||
Round(m_srcPoly[j].Y + m_delta * (m_normals[k].Y + m_normals[k].X * dx)));
|
||||
m_destPoly.emplace_back(
|
||||
Round(m_srcPoly[j].X + m_delta * (m_normals[j].X + m_normals[j].Y * dx)),
|
||||
Round(m_srcPoly[j].Y +
|
||||
m_delta * (m_normals[j].Y - m_normals[j].X * dx))));
|
||||
Round(m_srcPoly[j].Y + m_delta * (m_normals[j].Y - m_normals[j].X * dx)));
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
void ClipperOffset::DoMiter(int j, int k, double r) {
|
||||
double q = m_delta / r;
|
||||
m_destPoly.push_back(
|
||||
IntPoint(Round(m_srcPoly[j].X + (m_normals[k].X + m_normals[j].X) * q),
|
||||
Round(m_srcPoly[j].Y + (m_normals[k].Y + m_normals[j].Y) * q)));
|
||||
m_destPoly.emplace_back(
|
||||
Round(m_srcPoly[j].X + (m_normals[k].X + m_normals[j].X) * q),
|
||||
Round(m_srcPoly[j].Y + (m_normals[k].Y + m_normals[j].Y) * q));
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
|
@ -3994,15 +3988,14 @@ void ClipperOffset::DoRound(int j, int k) {
|
|||
|
||||
double X = m_normals[k].X, Y = m_normals[k].Y, X2;
|
||||
for (int i = 0; i < steps; ++i) {
|
||||
m_destPoly.push_back(IntPoint(Round(m_srcPoly[j].X + X * m_delta),
|
||||
Round(m_srcPoly[j].Y + Y * m_delta)));
|
||||
m_destPoly.emplace_back(Round(m_srcPoly[j].X + X * m_delta),
|
||||
Round(m_srcPoly[j].Y + Y * m_delta));
|
||||
X2 = X;
|
||||
X = X * m_cos - m_sin * Y;
|
||||
Y = X2 * m_sin + Y * m_cos;
|
||||
}
|
||||
m_destPoly.push_back(
|
||||
IntPoint(Round(m_srcPoly[j].X + m_normals[j].X * m_delta),
|
||||
Round(m_srcPoly[j].Y + m_normals[j].Y * m_delta)));
|
||||
m_destPoly.emplace_back(Round(m_srcPoly[j].X + m_normals[j].X * m_delta),
|
||||
Round(m_srcPoly[j].Y + m_normals[j].Y * m_delta));
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
@ -4142,7 +4135,7 @@ bool SlopesNearCollinear(const IntPoint &pt1, const IntPoint &pt2,
|
|||
}
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
bool PointsAreClose(IntPoint pt1, IntPoint pt2, double distSqrd) {
|
||||
bool PointsAreClose(IntPoint &pt1, IntPoint &pt2, double distSqrd) {
|
||||
double Dx = (double)pt1.X - pt2.X;
|
||||
double dy = (double)pt1.Y - pt2.Y;
|
||||
return ((Dx * Dx) + (dy * dy) <= distSqrd);
|
||||
|
@ -4237,16 +4230,16 @@ void Minkowski(const Path &poly, const Path &path, Paths &solution, bool isSum,
|
|||
Path p;
|
||||
p.reserve(polyCnt);
|
||||
for (size_t j = 0; j < poly.size(); ++j)
|
||||
p.push_back(IntPoint(path[i].X + poly[j].X, path[i].Y + poly[j].Y));
|
||||
pp.push_back(p);
|
||||
p.emplace_back(path[i].X + poly[j].X, path[i].Y + poly[j].Y);
|
||||
pp << std::move(p);
|
||||
}
|
||||
else
|
||||
for (size_t i = 0; i < pathCnt; ++i) {
|
||||
Path p;
|
||||
p.reserve(polyCnt);
|
||||
for (size_t j = 0; j < poly.size(); ++j)
|
||||
p.push_back(IntPoint(path[i].X - poly[j].X, path[i].Y - poly[j].Y));
|
||||
pp.push_back(p);
|
||||
p.emplace_back(path[i].X - poly[j].X, path[i].Y - poly[j].Y);
|
||||
pp << std::move(p);
|
||||
}
|
||||
|
||||
solution.clear();
|
||||
|
@ -4255,13 +4248,13 @@ void Minkowski(const Path &poly, const Path &path, Paths &solution, bool isSum,
|
|||
for (size_t j = 0; j < polyCnt; ++j) {
|
||||
Path quad;
|
||||
quad.reserve(4);
|
||||
quad.push_back(pp[i % pathCnt][j % polyCnt]);
|
||||
quad.push_back(pp[(i + 1) % pathCnt][j % polyCnt]);
|
||||
quad.push_back(pp[(i + 1) % pathCnt][(j + 1) % polyCnt]);
|
||||
quad.push_back(pp[i % pathCnt][(j + 1) % polyCnt]);
|
||||
quad.emplace_back(pp[i % pathCnt][j % polyCnt]);
|
||||
quad.emplace_back(pp[(i + 1) % pathCnt][j % polyCnt]);
|
||||
quad.emplace_back(pp[(i + 1) % pathCnt][(j + 1) % polyCnt]);
|
||||
quad.emplace_back(pp[i % pathCnt][(j + 1) % polyCnt]);
|
||||
if (!Orientation(quad))
|
||||
ReversePath(quad);
|
||||
solution.push_back(quad);
|
||||
solution << std::move(quad);
|
||||
}
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
|
@ -4275,11 +4268,11 @@ void MinkowskiSum(const Path &pattern, const Path &path, Paths &solution,
|
|||
}
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
void TranslatePath(const Path &input, Path &output, const IntPoint delta) {
|
||||
void TranslatePath(const Path &input, Path &output, const IntPoint &delta) {
|
||||
// precondition: input != output
|
||||
output.resize(input.size());
|
||||
for (size_t i = 0; i < input.size(); ++i)
|
||||
output[i] = IntPoint(input[i].X + delta.X, input[i].Y + delta.Y);
|
||||
output[i].reset(input[i].X + delta.X, input[i].Y + delta.Y);
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
|
@ -4319,7 +4312,7 @@ void AddPolyNodeToPaths(const PolyNode &polynode, NodeType nodetype,
|
|||
return;
|
||||
|
||||
if (!polynode.Contour.empty() && match)
|
||||
paths.push_back(polynode.Contour);
|
||||
paths.emplace_back(polynode.Contour);
|
||||
for (int i = 0; i < polynode.ChildCount(); ++i)
|
||||
AddPolyNodeToPaths(*polynode.Childs[i], nodetype, paths);
|
||||
}
|
||||
|
@ -4345,7 +4338,7 @@ void OpenPathsFromPolyTree(PolyTree &polytree, Paths &paths) {
|
|||
// Open paths are top level only, so ...
|
||||
for (int i = 0; i < polytree.ChildCount(); ++i)
|
||||
if (polytree.Childs[i]->IsOpen())
|
||||
paths.push_back(polytree.Childs[i]->Contour);
|
||||
paths.emplace_back(polytree.Childs[i]->Contour);
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
|
@ -4359,7 +4352,7 @@ std::ostream &operator<<(std::ostream &s, const Path &p) {
|
|||
if (p.empty())
|
||||
return s;
|
||||
Path::size_type last = p.size() - 1;
|
||||
for (Path::size_type i = 0; i < last; i++)
|
||||
for (Path::size_type i = 0; i < last; ++i)
|
||||
s << "(" << p[i].X << "," << p[i].Y << "), ";
|
||||
s << "(" << p[last].X << "," << p[last].Y << ")\n";
|
||||
return s;
|
||||
|
@ -4367,7 +4360,7 @@ std::ostream &operator<<(std::ostream &s, const Path &p) {
|
|||
//------------------------------------------------------------------------------
|
||||
|
||||
std::ostream &operator<<(std::ostream &s, const Paths &p) {
|
||||
for (Paths::size_type i = 0; i < p.size(); i++)
|
||||
for (Paths::size_type i = 0; i < p.size(); ++i)
|
||||
s << p[i];
|
||||
s << "\n";
|
||||
return s;
|
||||
|
|
|
@ -97,8 +97,8 @@ void ocr(std::vector<cv::String> &cv_all_img_names) {
|
|||
<< cv_all_img_names[i] << std::endl;
|
||||
continue;
|
||||
}
|
||||
img_list.push_back(img);
|
||||
img_names.push_back(cv_all_img_names[i]);
|
||||
img_list.emplace_back(std::move(img));
|
||||
img_names.emplace_back(cv_all_img_names[i]);
|
||||
}
|
||||
|
||||
std::vector<std::vector<OCRPredictResult>> ocr_results =
|
||||
|
@ -126,7 +126,7 @@ void structure(std::vector<cv::String> &cv_all_img_names) {
|
|||
engine.reset_timer();
|
||||
}
|
||||
|
||||
for (int i = 0; i < cv_all_img_names.size(); i++) {
|
||||
for (int i = 0; i < cv_all_img_names.size(); ++i) {
|
||||
std::cout << "predict img: " << cv_all_img_names[i] << std::endl;
|
||||
cv::Mat img = cv::imread(cv_all_img_names[i], cv::IMREAD_COLOR);
|
||||
if (!img.data) {
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
|
||||
namespace PaddleOCR {
|
||||
|
||||
void Classifier::Run(std::vector<cv::Mat> img_list,
|
||||
void Classifier::Run(const std::vector<cv::Mat> &img_list,
|
||||
std::vector<int> &cls_labels,
|
||||
std::vector<float> &cls_scores,
|
||||
std::vector<double> ×) {
|
||||
|
@ -43,14 +43,14 @@ void Classifier::Run(std::vector<cv::Mat> img_list,
|
|||
this->resize_op_.Run(srcimg, resize_img, this->use_tensorrt_,
|
||||
cls_image_shape);
|
||||
|
||||
this->normalize_op_.Run(&resize_img, this->mean_, this->scale_,
|
||||
this->normalize_op_.Run(resize_img, this->mean_, this->scale_,
|
||||
this->is_scale_);
|
||||
if (resize_img.cols < cls_image_shape[2]) {
|
||||
cv::copyMakeBorder(resize_img, resize_img, 0, 0, 0,
|
||||
cls_image_shape[2] - resize_img.cols,
|
||||
cv::BORDER_CONSTANT, cv::Scalar(0, 0, 0));
|
||||
}
|
||||
norm_img_batch.push_back(resize_img);
|
||||
norm_img_batch.emplace_back(std::move(resize_img));
|
||||
}
|
||||
std::vector<float> input(batch_num * cls_image_shape[0] *
|
||||
cls_image_shape[1] * cls_image_shape[2],
|
||||
|
@ -96,9 +96,9 @@ void Classifier::Run(std::vector<cv::Mat> img_list,
|
|||
auto postprocess_end = std::chrono::steady_clock::now();
|
||||
postprocess_diff += postprocess_end - postprocess_start;
|
||||
}
|
||||
times.push_back(double(preprocess_diff.count() * 1000));
|
||||
times.push_back(double(inference_diff.count() * 1000));
|
||||
times.push_back(double(postprocess_diff.count() * 1000));
|
||||
times.emplace_back(preprocess_diff.count() * 1000);
|
||||
times.emplace_back(inference_diff.count() * 1000);
|
||||
times.emplace_back(postprocess_diff.count() * 1000);
|
||||
}
|
||||
|
||||
void Classifier::LoadModel(const std::string &model_dir) {
|
||||
|
|
|
@ -63,7 +63,7 @@ void DBDetector::LoadModel(const std::string &model_dir) {
|
|||
this->predictor_ = paddle_infer::CreatePredictor(config);
|
||||
}
|
||||
|
||||
void DBDetector::Run(cv::Mat &img,
|
||||
void DBDetector::Run(const cv::Mat &img,
|
||||
std::vector<std::vector<std::vector<int>>> &boxes,
|
||||
std::vector<double> ×) {
|
||||
float ratio_h{};
|
||||
|
@ -78,11 +78,11 @@ void DBDetector::Run(cv::Mat &img,
|
|||
this->limit_side_len_, ratio_h, ratio_w,
|
||||
this->use_tensorrt_);
|
||||
|
||||
this->normalize_op_.Run(&resize_img, this->mean_, this->scale_,
|
||||
this->normalize_op_.Run(resize_img, this->mean_, this->scale_,
|
||||
this->is_scale_);
|
||||
|
||||
std::vector<float> input(1 * 3 * resize_img.rows * resize_img.cols, 0.0f);
|
||||
this->permute_op_.Run(&resize_img, input.data());
|
||||
this->permute_op_.Run(resize_img, input.data());
|
||||
auto preprocess_end = std::chrono::steady_clock::now();
|
||||
|
||||
// Inference.
|
||||
|
@ -113,7 +113,7 @@ void DBDetector::Run(cv::Mat &img,
|
|||
std::vector<float> pred(n, 0.0);
|
||||
std::vector<unsigned char> cbuf(n, ' ');
|
||||
|
||||
for (int i = 0; i < n; i++) {
|
||||
for (int i = 0; i < n; ++i) {
|
||||
pred[i] = float(out_data[i]);
|
||||
cbuf[i] = (unsigned char)((out_data[i]) * 255);
|
||||
}
|
||||
|
@ -131,21 +131,21 @@ void DBDetector::Run(cv::Mat &img,
|
|||
cv::dilate(bit_map, bit_map, dila_ele);
|
||||
}
|
||||
|
||||
boxes = post_processor_.BoxesFromBitmap(
|
||||
boxes = std::move(post_processor_.BoxesFromBitmap(
|
||||
pred_map, bit_map, this->det_db_box_thresh_, this->det_db_unclip_ratio_,
|
||||
this->det_db_score_mode_);
|
||||
this->det_db_score_mode_));
|
||||
|
||||
boxes = post_processor_.FilterTagDetRes(boxes, ratio_h, ratio_w, srcimg);
|
||||
post_processor_.FilterTagDetRes(boxes, ratio_h, ratio_w, srcimg);
|
||||
auto postprocess_end = std::chrono::steady_clock::now();
|
||||
|
||||
std::chrono::duration<float> preprocess_diff =
|
||||
preprocess_end - preprocess_start;
|
||||
times.push_back(double(preprocess_diff.count() * 1000));
|
||||
times.emplace_back(preprocess_diff.count() * 1000);
|
||||
std::chrono::duration<float> inference_diff = inference_end - inference_start;
|
||||
times.push_back(double(inference_diff.count() * 1000));
|
||||
times.emplace_back(inference_diff.count() * 1000);
|
||||
std::chrono::duration<float> postprocess_diff =
|
||||
postprocess_end - postprocess_start;
|
||||
times.push_back(double(postprocess_diff.count() * 1000));
|
||||
times.emplace_back(postprocess_diff.count() * 1000);
|
||||
}
|
||||
|
||||
} // namespace PaddleOCR
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
|
||||
namespace PaddleOCR {
|
||||
|
||||
void CRNNRecognizer::Run(std::vector<cv::Mat> img_list,
|
||||
void CRNNRecognizer::Run(const std::vector<cv::Mat> &img_list,
|
||||
std::vector<std::string> &rec_texts,
|
||||
std::vector<float> &rec_text_scores,
|
||||
std::vector<double> ×) {
|
||||
|
@ -29,10 +29,10 @@ void CRNNRecognizer::Run(std::vector<cv::Mat> img_list,
|
|||
|
||||
int img_num = img_list.size();
|
||||
std::vector<float> width_list;
|
||||
for (int i = 0; i < img_num; i++) {
|
||||
width_list.push_back(float(img_list[i].cols) / img_list[i].rows);
|
||||
for (int i = 0; i < img_num; ++i) {
|
||||
width_list.emplace_back(float(img_list[i].cols) / img_list[i].rows);
|
||||
}
|
||||
std::vector<int> indices = Utility::argsort(width_list);
|
||||
std::vector<int> indices = std::move(Utility::argsort(width_list));
|
||||
|
||||
for (int beg_img_no = 0; beg_img_no < img_num;
|
||||
beg_img_no += this->rec_batch_num_) {
|
||||
|
@ -57,10 +57,10 @@ void CRNNRecognizer::Run(std::vector<cv::Mat> img_list,
|
|||
cv::Mat resize_img;
|
||||
this->resize_op_.Run(srcimg, resize_img, max_wh_ratio,
|
||||
this->use_tensorrt_, this->rec_image_shape_);
|
||||
this->normalize_op_.Run(&resize_img, this->mean_, this->scale_,
|
||||
this->normalize_op_.Run(resize_img, this->mean_, this->scale_,
|
||||
this->is_scale_);
|
||||
norm_img_batch.push_back(resize_img);
|
||||
batch_width = std::max(resize_img.cols, batch_width);
|
||||
norm_img_batch.emplace_back(std::move(resize_img));
|
||||
}
|
||||
|
||||
std::vector<float> input(batch_num * 3 * imgH * batch_width, 0.0f);
|
||||
|
@ -118,15 +118,15 @@ void CRNNRecognizer::Run(std::vector<cv::Mat> img_list,
|
|||
if (std::isnan(score)) {
|
||||
continue;
|
||||
}
|
||||
rec_texts[indices[beg_img_no + m]] = str_res;
|
||||
rec_texts[indices[beg_img_no + m]] = std::move(str_res);
|
||||
rec_text_scores[indices[beg_img_no + m]] = score;
|
||||
}
|
||||
auto postprocess_end = std::chrono::steady_clock::now();
|
||||
postprocess_diff += postprocess_end - postprocess_start;
|
||||
}
|
||||
times.push_back(double(preprocess_diff.count() * 1000));
|
||||
times.push_back(double(inference_diff.count() * 1000));
|
||||
times.push_back(double(postprocess_diff.count() * 1000));
|
||||
times.emplace_back(preprocess_diff.count() * 1000);
|
||||
times.emplace_back(inference_diff.count() * 1000);
|
||||
times.emplace_back(postprocess_diff.count() * 1000);
|
||||
}
|
||||
|
||||
void CRNNRecognizer::LoadModel(const std::string &model_dir) {
|
||||
|
|
|
@ -45,7 +45,7 @@ PPOCR::PPOCR() {
|
|||
}
|
||||
|
||||
std::vector<std::vector<OCRPredictResult>>
|
||||
PPOCR::ocr(std::vector<cv::Mat> img_list, bool det, bool rec, bool cls) {
|
||||
PPOCR::ocr(const std::vector<cv::Mat> &img_list, bool det, bool rec, bool cls) {
|
||||
std::vector<std::vector<OCRPredictResult>> ocr_results;
|
||||
|
||||
if (!det) {
|
||||
|
@ -53,7 +53,7 @@ PPOCR::ocr(std::vector<cv::Mat> img_list, bool det, bool rec, bool cls) {
|
|||
ocr_result.resize(img_list.size());
|
||||
if (cls && this->classifier_) {
|
||||
this->cls(img_list, ocr_result);
|
||||
for (int i = 0; i < img_list.size(); i++) {
|
||||
for (int i = 0; i < img_list.size(); ++i) {
|
||||
if (ocr_result[i].cls_label % 2 == 1 &&
|
||||
ocr_result[i].cls_score > this->classifier_->cls_thresh) {
|
||||
cv::rotate(img_list[i], img_list[i], 1);
|
||||
|
@ -64,21 +64,19 @@ PPOCR::ocr(std::vector<cv::Mat> img_list, bool det, bool rec, bool cls) {
|
|||
this->rec(img_list, ocr_result);
|
||||
}
|
||||
for (int i = 0; i < ocr_result.size(); ++i) {
|
||||
std::vector<OCRPredictResult> ocr_result_tmp;
|
||||
ocr_result_tmp.push_back(ocr_result[i]);
|
||||
ocr_results.push_back(ocr_result_tmp);
|
||||
ocr_results.emplace_back(1, std::move(ocr_result[i]));
|
||||
}
|
||||
} else {
|
||||
for (int i = 0; i < img_list.size(); ++i) {
|
||||
std::vector<OCRPredictResult> ocr_result =
|
||||
this->ocr(img_list[i], true, rec, cls);
|
||||
ocr_results.push_back(ocr_result);
|
||||
ocr_results.emplace_back(std::move(ocr_result));
|
||||
}
|
||||
}
|
||||
return ocr_results;
|
||||
}
|
||||
|
||||
std::vector<OCRPredictResult> PPOCR::ocr(cv::Mat img, bool det, bool rec,
|
||||
std::vector<OCRPredictResult> PPOCR::ocr(const cv::Mat &img, bool det, bool rec,
|
||||
bool cls) {
|
||||
|
||||
std::vector<OCRPredictResult> ocr_result;
|
||||
|
@ -87,14 +85,13 @@ std::vector<OCRPredictResult> PPOCR::ocr(cv::Mat img, bool det, bool rec,
|
|||
// crop image
|
||||
std::vector<cv::Mat> img_list;
|
||||
for (int j = 0; j < ocr_result.size(); j++) {
|
||||
cv::Mat crop_img;
|
||||
crop_img = Utility::GetRotateCropImage(img, ocr_result[j].box);
|
||||
img_list.push_back(crop_img);
|
||||
cv::Mat crop_img = Utility::GetRotateCropImage(img, ocr_result[j].box);
|
||||
img_list.emplace_back(std::move(crop_img));
|
||||
}
|
||||
// cls
|
||||
if (cls && this->classifier_) {
|
||||
this->cls(img_list, ocr_result);
|
||||
for (int i = 0; i < img_list.size(); i++) {
|
||||
for (int i = 0; i < img_list.size(); ++i) {
|
||||
if (ocr_result[i].cls_label % 2 == 1 &&
|
||||
ocr_result[i].cls_score > this->classifier_->cls_thresh) {
|
||||
cv::rotate(img_list[i], img_list[i], 1);
|
||||
|
@ -108,16 +105,17 @@ std::vector<OCRPredictResult> PPOCR::ocr(cv::Mat img, bool det, bool rec,
|
|||
return ocr_result;
|
||||
}
|
||||
|
||||
void PPOCR::det(cv::Mat img, std::vector<OCRPredictResult> &ocr_results) {
|
||||
void PPOCR::det(const cv::Mat &img,
|
||||
std::vector<OCRPredictResult> &ocr_results) {
|
||||
std::vector<std::vector<std::vector<int>>> boxes;
|
||||
std::vector<double> det_times;
|
||||
|
||||
this->detector_->Run(img, boxes, det_times);
|
||||
|
||||
for (int i = 0; i < boxes.size(); i++) {
|
||||
for (int i = 0; i < boxes.size(); ++i) {
|
||||
OCRPredictResult res;
|
||||
res.box = boxes[i];
|
||||
ocr_results.push_back(res);
|
||||
res.box = std::move(boxes[i]);
|
||||
ocr_results.emplace_back(std::move(res));
|
||||
}
|
||||
// sort boex from top to bottom, from left to right
|
||||
Utility::sorted_boxes(ocr_results);
|
||||
|
@ -126,15 +124,15 @@ void PPOCR::det(cv::Mat img, std::vector<OCRPredictResult> &ocr_results) {
|
|||
this->time_info_det[2] += det_times[2];
|
||||
}
|
||||
|
||||
void PPOCR::rec(std::vector<cv::Mat> img_list,
|
||||
void PPOCR::rec(const std::vector<cv::Mat> &img_list,
|
||||
std::vector<OCRPredictResult> &ocr_results) {
|
||||
std::vector<std::string> rec_texts(img_list.size(), "");
|
||||
std::vector<std::string> rec_texts(img_list.size(), std::string());
|
||||
std::vector<float> rec_text_scores(img_list.size(), 0);
|
||||
std::vector<double> rec_times;
|
||||
this->recognizer_->Run(img_list, rec_texts, rec_text_scores, rec_times);
|
||||
// output rec results
|
||||
for (int i = 0; i < rec_texts.size(); i++) {
|
||||
ocr_results[i].text = rec_texts[i];
|
||||
for (int i = 0; i < rec_texts.size(); ++i) {
|
||||
ocr_results[i].text = std::move(rec_texts[i]);
|
||||
ocr_results[i].score = rec_text_scores[i];
|
||||
}
|
||||
this->time_info_rec[0] += rec_times[0];
|
||||
|
@ -142,14 +140,14 @@ void PPOCR::rec(std::vector<cv::Mat> img_list,
|
|||
this->time_info_rec[2] += rec_times[2];
|
||||
}
|
||||
|
||||
void PPOCR::cls(std::vector<cv::Mat> img_list,
|
||||
void PPOCR::cls(const std::vector<cv::Mat> &img_list,
|
||||
std::vector<OCRPredictResult> &ocr_results) {
|
||||
std::vector<int> cls_labels(img_list.size(), 0);
|
||||
std::vector<float> cls_scores(img_list.size(), 0);
|
||||
std::vector<double> cls_times;
|
||||
this->classifier_->Run(img_list, cls_labels, cls_scores, cls_times);
|
||||
// output cls results
|
||||
for (int i = 0; i < cls_labels.size(); i++) {
|
||||
for (int i = 0; i < cls_labels.size(); ++i) {
|
||||
ocr_results[i].cls_label = cls_labels[i];
|
||||
ocr_results[i].cls_score = cls_scores[i];
|
||||
}
|
||||
|
|
|
@ -37,7 +37,8 @@ PaddleStructure::PaddleStructure() {
|
|||
}
|
||||
|
||||
std::vector<StructurePredictResult>
|
||||
PaddleStructure::structure(cv::Mat srcimg, bool layout, bool table, bool ocr) {
|
||||
PaddleStructure::structure(const cv::Mat &srcimg, bool layout, bool table,
|
||||
bool ocr) {
|
||||
cv::Mat img;
|
||||
srcimg.copyTo(img);
|
||||
|
||||
|
@ -48,19 +49,20 @@ PaddleStructure::structure(cv::Mat srcimg, bool layout, bool table, bool ocr) {
|
|||
} else {
|
||||
StructurePredictResult res;
|
||||
res.type = "table";
|
||||
res.box = std::vector<float>(4, 0.0);
|
||||
res.box.resize(4, 0.0);
|
||||
res.box[2] = img.cols;
|
||||
res.box[3] = img.rows;
|
||||
structure_results.push_back(res);
|
||||
structure_results.emplace_back(std::move(res));
|
||||
}
|
||||
cv::Mat roi_img;
|
||||
for (int i = 0; i < structure_results.size(); i++) {
|
||||
for (int i = 0; i < structure_results.size(); ++i) {
|
||||
// crop image
|
||||
roi_img = Utility::crop_image(img, structure_results[i].box);
|
||||
roi_img = std::move(Utility::crop_image(img, structure_results[i].box));
|
||||
if (structure_results[i].type == "table" && table) {
|
||||
this->table(roi_img, structure_results[i]);
|
||||
} else if (ocr) {
|
||||
structure_results[i].text_res = this->ocr(roi_img, true, true, false);
|
||||
structure_results[i].text_res =
|
||||
std::move(this->ocr(roi_img, true, true, false));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -68,7 +70,7 @@ PaddleStructure::structure(cv::Mat srcimg, bool layout, bool table, bool ocr) {
|
|||
}
|
||||
|
||||
void PaddleStructure::layout(
|
||||
cv::Mat img, std::vector<StructurePredictResult> &structure_result) {
|
||||
const cv::Mat &img, std::vector<StructurePredictResult> &structure_result) {
|
||||
std::vector<double> layout_times;
|
||||
this->layout_model_->Run(img, structure_result, layout_times);
|
||||
|
||||
|
@ -77,15 +79,14 @@ void PaddleStructure::layout(
|
|||
this->time_info_layout[2] += layout_times[2];
|
||||
}
|
||||
|
||||
void PaddleStructure::table(cv::Mat img,
|
||||
void PaddleStructure::table(const cv::Mat &img,
|
||||
StructurePredictResult &structure_result) {
|
||||
// predict structure
|
||||
std::vector<std::vector<std::string>> structure_html_tags;
|
||||
std::vector<float> structure_scores(1, 0);
|
||||
std::vector<std::vector<std::vector<int>>> structure_boxes;
|
||||
std::vector<double> structure_times;
|
||||
std::vector<cv::Mat> img_list;
|
||||
img_list.push_back(img);
|
||||
std::vector<cv::Mat> img_list(1, img);
|
||||
|
||||
this->table_model_->Run(img_list, structure_html_tags, structure_scores,
|
||||
structure_boxes, structure_times);
|
||||
|
@ -98,45 +99,44 @@ void PaddleStructure::table(cv::Mat img,
|
|||
std::string html;
|
||||
int expand_pixel = 3;
|
||||
|
||||
for (int i = 0; i < img_list.size(); i++) {
|
||||
for (int i = 0; i < img_list.size(); ++i) {
|
||||
// det
|
||||
this->det(img_list[i], ocr_result);
|
||||
// crop image
|
||||
std::vector<cv::Mat> rec_img_list;
|
||||
std::vector<int> ocr_box;
|
||||
for (int j = 0; j < ocr_result.size(); j++) {
|
||||
ocr_box = Utility::xyxyxyxy2xyxy(ocr_result[j].box);
|
||||
ocr_box = std::move(Utility::xyxyxyxy2xyxy(ocr_result[j].box));
|
||||
ocr_box[0] = std::max(0, ocr_box[0] - expand_pixel);
|
||||
ocr_box[1] = std::max(0, ocr_box[1] - expand_pixel),
|
||||
ocr_box[2] = std::min(img_list[i].cols, ocr_box[2] + expand_pixel);
|
||||
ocr_box[3] = std::min(img_list[i].rows, ocr_box[3] + expand_pixel);
|
||||
|
||||
cv::Mat crop_img = Utility::crop_image(img_list[i], ocr_box);
|
||||
rec_img_list.push_back(crop_img);
|
||||
rec_img_list.emplace_back(std::move(crop_img));
|
||||
}
|
||||
// rec
|
||||
this->rec(rec_img_list, ocr_result);
|
||||
// rebuild table
|
||||
html = this->rebuild_table(structure_html_tags[i], structure_boxes[i],
|
||||
ocr_result);
|
||||
structure_result.html = html;
|
||||
structure_result.cell_box = structure_boxes[i];
|
||||
structure_result.html = std::move(this->rebuild_table(
|
||||
structure_html_tags[i], structure_boxes[i], ocr_result));
|
||||
structure_result.cell_box = std::move(structure_boxes[i]);
|
||||
structure_result.html_score = structure_scores[i];
|
||||
}
|
||||
}
|
||||
|
||||
std::string
|
||||
PaddleStructure::rebuild_table(std::vector<std::string> structure_html_tags,
|
||||
std::vector<std::vector<int>> structure_boxes,
|
||||
std::vector<OCRPredictResult> &ocr_result) {
|
||||
std::string PaddleStructure::rebuild_table(
|
||||
const std::vector<std::string> &structure_html_tags,
|
||||
const std::vector<std::vector<int>> &structure_boxes,
|
||||
std::vector<OCRPredictResult> &ocr_result) {
|
||||
// match text in same cell
|
||||
std::vector<std::vector<std::string>> matched(structure_boxes.size(),
|
||||
std::vector<std::string>());
|
||||
|
||||
std::vector<int> ocr_box;
|
||||
std::vector<int> structure_box;
|
||||
for (int i = 0; i < ocr_result.size(); i++) {
|
||||
ocr_box = Utility::xyxyxyxy2xyxy(ocr_result[i].box);
|
||||
for (int i = 0; i < ocr_result.size(); ++i) {
|
||||
ocr_box = std::move(Utility::xyxyxyxy2xyxy(ocr_result[i].box));
|
||||
ocr_box[0] -= 1;
|
||||
ocr_box[1] -= 1;
|
||||
ocr_box[2] += 1;
|
||||
|
@ -145,7 +145,7 @@ PaddleStructure::rebuild_table(std::vector<std::string> structure_html_tags,
|
|||
std::vector<float>(3, 100000.0));
|
||||
for (int j = 0; j < structure_boxes.size(); j++) {
|
||||
if (structure_boxes[i].size() == 8) {
|
||||
structure_box = Utility::xyxyxyxy2xyxy(structure_boxes[j]);
|
||||
structure_box = std::move(Utility::xyxyxyxy2xyxy(structure_boxes[j]));
|
||||
} else {
|
||||
structure_box = structure_boxes[j];
|
||||
}
|
||||
|
@ -156,13 +156,13 @@ PaddleStructure::rebuild_table(std::vector<std::string> structure_html_tags,
|
|||
// find min dis idx
|
||||
std::sort(dis_list.begin(), dis_list.end(),
|
||||
PaddleStructure::comparison_dis);
|
||||
matched[dis_list[0][2]].push_back(ocr_result[i].text);
|
||||
matched[dis_list[0][2]].emplace_back(ocr_result[i].text);
|
||||
}
|
||||
|
||||
// get pred html
|
||||
std::string html_str = "";
|
||||
int td_tag_idx = 0;
|
||||
for (int i = 0; i < structure_html_tags.size(); i++) {
|
||||
for (int i = 0; i < structure_html_tags.size(); ++i) {
|
||||
if (structure_html_tags[i].find("</td>") != std::string::npos) {
|
||||
if (structure_html_tags[i].find("<td></td>") != std::string::npos) {
|
||||
html_str += "<td>";
|
||||
|
@ -216,7 +216,8 @@ PaddleStructure::rebuild_table(std::vector<std::string> structure_html_tags,
|
|||
return html_str;
|
||||
}
|
||||
|
||||
float PaddleStructure::dis(std::vector<int> &box1, std::vector<int> &box2) {
|
||||
float PaddleStructure::dis(const std::vector<int> &box1,
|
||||
const std::vector<int> &box2) {
|
||||
int x1_1 = box1[0];
|
||||
int y1_1 = box1[1];
|
||||
int x2_1 = box1[2];
|
||||
|
|
|
@ -21,7 +21,7 @@ void DBPostProcessor::GetContourArea(const std::vector<std::vector<float>> &box,
|
|||
int pts_num = 4;
|
||||
float area = 0.0f;
|
||||
float dist = 0.0f;
|
||||
for (int i = 0; i < pts_num; i++) {
|
||||
for (int i = 0; i < pts_num; ++i) {
|
||||
area += box[i][0] * box[(i + 1) % pts_num][1] -
|
||||
box[i][1] * box[(i + 1) % pts_num][0];
|
||||
dist += sqrtf((box[i][0] - box[(i + 1) % pts_num][0]) *
|
||||
|
@ -34,18 +34,19 @@ void DBPostProcessor::GetContourArea(const std::vector<std::vector<float>> &box,
|
|||
distance = area * unclip_ratio / dist;
|
||||
}
|
||||
|
||||
cv::RotatedRect DBPostProcessor::UnClip(std::vector<std::vector<float>> box,
|
||||
const float &unclip_ratio) {
|
||||
cv::RotatedRect
|
||||
DBPostProcessor::UnClip(const std::vector<std::vector<float>> &box,
|
||||
const float &unclip_ratio) {
|
||||
float distance = 1.0;
|
||||
|
||||
GetContourArea(box, unclip_ratio, distance);
|
||||
|
||||
ClipperLib::ClipperOffset offset;
|
||||
ClipperLib::Path p;
|
||||
p << ClipperLib::IntPoint(int(box[0][0]), int(box[0][1]))
|
||||
<< ClipperLib::IntPoint(int(box[1][0]), int(box[1][1]))
|
||||
<< ClipperLib::IntPoint(int(box[2][0]), int(box[2][1]))
|
||||
<< ClipperLib::IntPoint(int(box[3][0]), int(box[3][1]));
|
||||
p.emplace_back(int(box[0][0]), int(box[0][1]));
|
||||
p.emplace_back(int(box[1][0]), int(box[1][1]));
|
||||
p.emplace_back(int(box[2][0]), int(box[2][1]));
|
||||
p.emplace_back(int(box[3][0]), int(box[3][1]));
|
||||
offset.AddPath(p, ClipperLib::jtRound, ClipperLib::etClosedPolygon);
|
||||
|
||||
ClipperLib::Paths soln;
|
||||
|
@ -53,7 +54,7 @@ cv::RotatedRect DBPostProcessor::UnClip(std::vector<std::vector<float>> box,
|
|||
std::vector<cv::Point2f> points;
|
||||
|
||||
for (int j = 0; j < soln.size(); j++) {
|
||||
for (int i = 0; i < soln[soln.size() - 1].size(); i++) {
|
||||
for (int i = 0; i < soln[soln.size() - 1].size(); ++i) {
|
||||
points.emplace_back(soln[j][i].X, soln[j][i].Y);
|
||||
}
|
||||
}
|
||||
|
@ -66,7 +67,7 @@ cv::RotatedRect DBPostProcessor::UnClip(std::vector<std::vector<float>> box,
|
|||
return res;
|
||||
}
|
||||
|
||||
float **DBPostProcessor::Mat2Vec(cv::Mat mat) {
|
||||
float **DBPostProcessor::Mat2Vec(const cv::Mat &mat) {
|
||||
auto **array = new float *[mat.rows];
|
||||
for (int i = 0; i < mat.rows; ++i)
|
||||
array[i] = new float[mat.cols];
|
||||
|
@ -79,8 +80,8 @@ float **DBPostProcessor::Mat2Vec(cv::Mat mat) {
|
|||
return array;
|
||||
}
|
||||
|
||||
std::vector<std::vector<int>>
|
||||
DBPostProcessor::OrderPointsClockwise(std::vector<std::vector<int>> pts) {
|
||||
std::vector<std::vector<int>> DBPostProcessor::OrderPointsClockwise(
|
||||
const std::vector<std::vector<int>> &pts) {
|
||||
std::vector<std::vector<int>> box = pts;
|
||||
std::sort(box.begin(), box.end(), XsortInt);
|
||||
|
||||
|
@ -98,34 +99,36 @@ DBPostProcessor::OrderPointsClockwise(std::vector<std::vector<int>> pts) {
|
|||
return rect;
|
||||
}
|
||||
|
||||
std::vector<std::vector<float>> DBPostProcessor::Mat2Vector(cv::Mat mat) {
|
||||
std::vector<std::vector<float>>
|
||||
DBPostProcessor::Mat2Vector(const cv::Mat &mat) {
|
||||
std::vector<std::vector<float>> img_vec;
|
||||
std::vector<float> tmp;
|
||||
|
||||
for (int i = 0; i < mat.rows; ++i) {
|
||||
tmp.clear();
|
||||
std::vector<float> tmp;
|
||||
for (int j = 0; j < mat.cols; ++j) {
|
||||
tmp.push_back(mat.at<float>(i, j));
|
||||
tmp.emplace_back(mat.at<float>(i, j));
|
||||
}
|
||||
img_vec.push_back(tmp);
|
||||
img_vec.emplace_back(std::move(tmp));
|
||||
}
|
||||
return img_vec;
|
||||
}
|
||||
|
||||
bool DBPostProcessor::XsortFp32(std::vector<float> a, std::vector<float> b) {
|
||||
bool DBPostProcessor::XsortFp32(const std::vector<float> &a,
|
||||
const std::vector<float> &b) {
|
||||
if (a[0] != b[0])
|
||||
return a[0] < b[0];
|
||||
return false;
|
||||
}
|
||||
|
||||
bool DBPostProcessor::XsortInt(std::vector<int> a, std::vector<int> b) {
|
||||
bool DBPostProcessor::XsortInt(const std::vector<int> &a,
|
||||
const std::vector<int> &b) {
|
||||
if (a[0] != b[0])
|
||||
return a[0] < b[0];
|
||||
return false;
|
||||
}
|
||||
|
||||
std::vector<std::vector<float>>
|
||||
DBPostProcessor::GetMiniBoxes(cv::RotatedRect box, float &ssid) {
|
||||
DBPostProcessor::GetMiniBoxes(const cv::RotatedRect &box, float &ssid) {
|
||||
ssid = std::max(box.size.width, box.size.height);
|
||||
|
||||
cv::Mat points;
|
||||
|
@ -159,15 +162,15 @@ DBPostProcessor::GetMiniBoxes(cv::RotatedRect box, float &ssid) {
|
|||
return array;
|
||||
}
|
||||
|
||||
float DBPostProcessor::PolygonScoreAcc(std::vector<cv::Point> contour,
|
||||
cv::Mat pred) {
|
||||
float DBPostProcessor::PolygonScoreAcc(const std::vector<cv::Point> &contour,
|
||||
const cv::Mat &pred) {
|
||||
int width = pred.cols;
|
||||
int height = pred.rows;
|
||||
std::vector<float> box_x;
|
||||
std::vector<float> box_y;
|
||||
for (int i = 0; i < contour.size(); ++i) {
|
||||
box_x.push_back(contour[i].x);
|
||||
box_y.push_back(contour[i].y);
|
||||
box_x.emplace_back(contour[i].x);
|
||||
box_y.emplace_back(contour[i].y);
|
||||
}
|
||||
|
||||
int xmin =
|
||||
|
@ -205,9 +208,9 @@ float DBPostProcessor::PolygonScoreAcc(std::vector<cv::Point> contour,
|
|||
return score;
|
||||
}
|
||||
|
||||
float DBPostProcessor::BoxScoreFast(std::vector<std::vector<float>> box_array,
|
||||
cv::Mat pred) {
|
||||
auto array = box_array;
|
||||
float DBPostProcessor::BoxScoreFast(
|
||||
const std::vector<std::vector<float>> &box_array, const cv::Mat &pred) {
|
||||
const auto &array = box_array;
|
||||
int width = pred.cols;
|
||||
int height = pred.rows;
|
||||
|
||||
|
@ -244,7 +247,7 @@ float DBPostProcessor::BoxScoreFast(std::vector<std::vector<float>> box_array,
|
|||
}
|
||||
|
||||
std::vector<std::vector<std::vector<int>>> DBPostProcessor::BoxesFromBitmap(
|
||||
const cv::Mat pred, const cv::Mat bitmap, const float &box_thresh,
|
||||
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) {
|
||||
const int min_size = 3;
|
||||
const int max_candidates = 1000;
|
||||
|
@ -312,17 +315,17 @@ std::vector<std::vector<std::vector<int>>> DBPostProcessor::BoxesFromBitmap(
|
|||
int(clampf(roundf(cliparray[num_pt][1] /
|
||||
float(height) * float(dest_height)),
|
||||
0, float(dest_height)))};
|
||||
intcliparray.push_back(a);
|
||||
intcliparray.emplace_back(std::move(a));
|
||||
}
|
||||
boxes.push_back(intcliparray);
|
||||
boxes.emplace_back(std::move(intcliparray));
|
||||
|
||||
} // end for
|
||||
return boxes;
|
||||
}
|
||||
|
||||
std::vector<std::vector<std::vector<int>>> DBPostProcessor::FilterTagDetRes(
|
||||
std::vector<std::vector<std::vector<int>>> boxes, float ratio_h,
|
||||
float ratio_w, cv::Mat srcimg) {
|
||||
void DBPostProcessor::FilterTagDetRes(
|
||||
std::vector<std::vector<std::vector<int>>> &boxes, float ratio_h,
|
||||
float ratio_w, const cv::Mat &srcimg) {
|
||||
int oriimg_h = srcimg.rows;
|
||||
int oriimg_w = srcimg.cols;
|
||||
|
||||
|
@ -346,16 +349,16 @@ std::vector<std::vector<std::vector<int>>> DBPostProcessor::FilterTagDetRes(
|
|||
pow(boxes[n][0][1] - boxes[n][3][1], 2)));
|
||||
if (rect_width <= 4 || rect_height <= 4)
|
||||
continue;
|
||||
root_points.push_back(boxes[n]);
|
||||
root_points.emplace_back(boxes[n]);
|
||||
}
|
||||
return root_points;
|
||||
boxes = std::move(root_points);
|
||||
}
|
||||
|
||||
void TablePostProcessor::init(std::string label_path,
|
||||
void TablePostProcessor::init(const std::string &label_path,
|
||||
bool merge_no_span_structure) {
|
||||
this->label_list_ = Utility::ReadDict(label_path);
|
||||
if (merge_no_span_structure) {
|
||||
this->label_list_.push_back("<td></td>");
|
||||
this->label_list_.emplace_back("<td></td>");
|
||||
std::vector<std::string>::iterator it;
|
||||
for (it = this->label_list_.begin(); it != this->label_list_.end();) {
|
||||
if (*it == "<td>") {
|
||||
|
@ -366,17 +369,18 @@ void TablePostProcessor::init(std::string label_path,
|
|||
}
|
||||
}
|
||||
// add_special_char
|
||||
this->label_list_.insert(this->label_list_.begin(), this->beg);
|
||||
this->label_list_.push_back(this->end);
|
||||
this->label_list_.emplace(this->label_list_.begin(), this->beg);
|
||||
this->label_list_.emplace_back(this->end);
|
||||
}
|
||||
|
||||
void TablePostProcessor::Run(
|
||||
std::vector<float> &loc_preds, std::vector<float> &structure_probs,
|
||||
std::vector<float> &rec_scores, std::vector<int> &loc_preds_shape,
|
||||
std::vector<int> &structure_probs_shape,
|
||||
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,
|
||||
std::vector<int> &width_list, std::vector<int> &height_list) {
|
||||
const std::vector<int> &width_list, const std::vector<int> &height_list) {
|
||||
for (int batch_idx = 0; batch_idx < structure_probs_shape[0]; batch_idx++) {
|
||||
// image tags and boxs
|
||||
std::vector<std::string> rec_html_tags;
|
||||
|
@ -410,7 +414,7 @@ void TablePostProcessor::Run(
|
|||
}
|
||||
count += 1;
|
||||
score += char_score;
|
||||
rec_html_tags.push_back(html_tag);
|
||||
rec_html_tags.emplace_back(html_tag);
|
||||
|
||||
// box
|
||||
if (html_tag == "<td>" || html_tag == "<td" || html_tag == "<td></td>") {
|
||||
|
@ -424,22 +428,22 @@ void TablePostProcessor::Run(
|
|||
} else {
|
||||
point = int(point * height_list[batch_idx]);
|
||||
}
|
||||
rec_box.push_back(point);
|
||||
rec_box.emplace_back(point);
|
||||
}
|
||||
rec_boxes.push_back(rec_box);
|
||||
rec_boxes.emplace_back(std::move(rec_box));
|
||||
}
|
||||
}
|
||||
score /= count;
|
||||
if (std::isnan(score) || rec_boxes.size() == 0) {
|
||||
score = -1;
|
||||
}
|
||||
rec_scores.push_back(score);
|
||||
rec_boxes_batch.push_back(rec_boxes);
|
||||
rec_html_tag_batch.push_back(rec_html_tags);
|
||||
rec_scores.emplace_back(score);
|
||||
rec_boxes_batch.emplace_back(std::move(rec_boxes));
|
||||
rec_html_tag_batch.emplace_back(std::move(rec_html_tags));
|
||||
}
|
||||
}
|
||||
|
||||
void PicodetPostProcessor::init(std::string label_path,
|
||||
void PicodetPostProcessor::init(const std::string &label_path,
|
||||
const double score_threshold,
|
||||
const double nms_threshold,
|
||||
const std::vector<int> &fpn_stride) {
|
||||
|
@ -451,9 +455,10 @@ void PicodetPostProcessor::init(std::string label_path,
|
|||
}
|
||||
|
||||
void PicodetPostProcessor::Run(std::vector<StructurePredictResult> &results,
|
||||
std::vector<std::vector<float>> outs,
|
||||
std::vector<int> ori_shape,
|
||||
std::vector<int> resize_shape, int reg_max) {
|
||||
const std::vector<std::vector<float>> &outs,
|
||||
const std::vector<int> &ori_shape,
|
||||
const std::vector<int> &resize_shape,
|
||||
int reg_max) {
|
||||
int in_h = resize_shape[0];
|
||||
int in_w = resize_shape[1];
|
||||
float scale_factor_h = resize_shape[0] / float(ori_shape[0]);
|
||||
|
@ -478,49 +483,49 @@ void PicodetPostProcessor::Run(std::vector<StructurePredictResult> &results,
|
|||
if (score > this->score_threshold_) {
|
||||
int row = idx / feature_w;
|
||||
int col = idx % feature_w;
|
||||
std::vector<float> bbox_pred(
|
||||
outs[i + this->fpn_stride_.size()].begin() + idx * 4 * reg_max,
|
||||
outs[i + this->fpn_stride_.size()].begin() +
|
||||
(idx + 1) * 4 * reg_max);
|
||||
bbox_results[cur_label].push_back(
|
||||
std::vector<float>::const_iterator itemp =
|
||||
outs[i + this->fpn_stride_.size()].begin() + idx * 4 * reg_max;
|
||||
std::vector<float> bbox_pred(itemp, itemp + 4 * reg_max);
|
||||
bbox_results[cur_label].emplace_back(std::move(
|
||||
this->disPred2Bbox(bbox_pred, cur_label, score, col, row,
|
||||
this->fpn_stride_[i], resize_shape, reg_max));
|
||||
this->fpn_stride_[i], resize_shape, reg_max)));
|
||||
}
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < bbox_results.size(); i++) {
|
||||
#if 0
|
||||
for (int i = 0; i < bbox_results.size(); ++i) {
|
||||
bool flag = bbox_results[i].size() <= 0;
|
||||
}
|
||||
for (int i = 0; i < bbox_results.size(); i++) {
|
||||
bool flag = bbox_results[i].size() <= 0;
|
||||
#endif
|
||||
for (int i = 0; i < bbox_results.size(); ++i) {
|
||||
// bool flag = bbox_results[i].size() <= 0;
|
||||
if (bbox_results[i].size() <= 0) {
|
||||
continue;
|
||||
}
|
||||
this->nms(bbox_results[i], this->nms_threshold_);
|
||||
for (auto box : bbox_results[i]) {
|
||||
for (auto &box : bbox_results[i]) {
|
||||
box.box[0] = box.box[0] / scale_factor_w;
|
||||
box.box[2] = box.box[2] / scale_factor_w;
|
||||
box.box[1] = box.box[1] / scale_factor_h;
|
||||
box.box[3] = box.box[3] / scale_factor_h;
|
||||
results.push_back(box);
|
||||
results.emplace_back(std::move(box));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
StructurePredictResult
|
||||
PicodetPostProcessor::disPred2Bbox(std::vector<float> bbox_pred, int label,
|
||||
float score, int x, int y, int stride,
|
||||
std::vector<int> im_shape, int reg_max) {
|
||||
StructurePredictResult PicodetPostProcessor::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) {
|
||||
float ct_x = (x + 0.5) * stride;
|
||||
float ct_y = (y + 0.5) * stride;
|
||||
std::vector<float> dis_pred;
|
||||
dis_pred.resize(4);
|
||||
for (int i = 0; i < 4; i++) {
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
float dis = 0;
|
||||
std::vector<float> bbox_pred_i(bbox_pred.begin() + i * reg_max,
|
||||
bbox_pred.begin() + (i + 1) * reg_max);
|
||||
std::vector<float> dis_after_sm =
|
||||
Utility::activation_function_softmax(bbox_pred_i);
|
||||
std::vector<float>::const_iterator itemp = bbox_pred.begin() + i * reg_max;
|
||||
std::vector<float> bbox_pred_i(itemp, itemp + reg_max);
|
||||
std::vector<float> dis_after_sm(
|
||||
std::move(Utility::activation_function_softmax(bbox_pred_i)));
|
||||
for (int j = 0; j < reg_max; j++) {
|
||||
dis += j * dis_after_sm[j];
|
||||
}
|
||||
|
@ -566,10 +571,10 @@ void PicodetPostProcessor::nms(std::vector<StructurePredictResult> &input_boxes,
|
|||
std::vector<StructurePredictResult> input_boxes_nms;
|
||||
for (int i = 0; i < input_boxes.size(); ++i) {
|
||||
if (picked[i] == 1) {
|
||||
input_boxes_nms.push_back(input_boxes[i]);
|
||||
input_boxes_nms.emplace_back(input_boxes[i]);
|
||||
}
|
||||
}
|
||||
input_boxes = input_boxes_nms;
|
||||
input_boxes = std::move(input_boxes_nms);
|
||||
}
|
||||
|
||||
} // namespace PaddleOCR
|
||||
|
|
|
@ -16,16 +16,16 @@
|
|||
|
||||
namespace PaddleOCR {
|
||||
|
||||
void Permute::Run(const cv::Mat *im, float *data) {
|
||||
int rh = im->rows;
|
||||
int rw = im->cols;
|
||||
int rc = im->channels();
|
||||
void Permute::Run(const cv::Mat &im, float *data) {
|
||||
int rh = im.rows;
|
||||
int rw = im.cols;
|
||||
int rc = im.channels();
|
||||
for (int i = 0; i < rc; ++i) {
|
||||
cv::extractChannel(*im, cv::Mat(rh, rw, CV_32FC1, data + i * rh * rw), i);
|
||||
cv::extractChannel(im, cv::Mat(rh, rw, CV_32FC1, data + i * rh * rw), i);
|
||||
}
|
||||
}
|
||||
|
||||
void PermuteBatch::Run(const std::vector<cv::Mat> imgs, float *data) {
|
||||
void PermuteBatch::Run(const std::vector<cv::Mat> &imgs, float *data) {
|
||||
for (int j = 0; j < imgs.size(); j++) {
|
||||
int rh = imgs[j].rows;
|
||||
int rw = imgs[j].cols;
|
||||
|
@ -37,24 +37,24 @@ void PermuteBatch::Run(const std::vector<cv::Mat> imgs, float *data) {
|
|||
}
|
||||
}
|
||||
|
||||
void Normalize::Run(cv::Mat *im, const std::vector<float> &mean,
|
||||
void Normalize::Run(cv::Mat &im, const std::vector<float> &mean,
|
||||
const std::vector<float> &scale, const bool is_scale) {
|
||||
double e = 1.0;
|
||||
if (is_scale) {
|
||||
e /= 255.0;
|
||||
}
|
||||
(*im).convertTo(*im, CV_32FC3, e);
|
||||
im.convertTo(im, CV_32FC3, e);
|
||||
std::vector<cv::Mat> bgr_channels(3);
|
||||
cv::split(*im, bgr_channels);
|
||||
for (auto i = 0; i < bgr_channels.size(); i++) {
|
||||
cv::split(im, bgr_channels);
|
||||
for (auto i = 0; i < bgr_channels.size(); ++i) {
|
||||
bgr_channels[i].convertTo(bgr_channels[i], CV_32FC1, 1.0 * scale[i],
|
||||
(0.0 - mean[i]) * scale[i]);
|
||||
}
|
||||
cv::merge(bgr_channels, *im);
|
||||
cv::merge(bgr_channels, im);
|
||||
}
|
||||
|
||||
void ResizeImgType0::Run(const cv::Mat &img, cv::Mat &resize_img,
|
||||
std::string limit_type, int limit_side_len,
|
||||
const std::string &limit_type, int limit_side_len,
|
||||
float &ratio_h, float &ratio_w, bool use_tensorrt) {
|
||||
int w = img.cols;
|
||||
int h = img.rows;
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
|
||||
namespace PaddleOCR {
|
||||
|
||||
void StructureLayoutRecognizer::Run(cv::Mat img,
|
||||
void StructureLayoutRecognizer::Run(const cv::Mat &img,
|
||||
std::vector<StructurePredictResult> &result,
|
||||
std::vector<double> ×) {
|
||||
std::chrono::duration<float> preprocess_diff =
|
||||
|
@ -33,11 +33,11 @@ void StructureLayoutRecognizer::Run(cv::Mat img,
|
|||
img.copyTo(srcimg);
|
||||
cv::Mat resize_img;
|
||||
this->resize_op_.Run(srcimg, resize_img, 800, 608);
|
||||
this->normalize_op_.Run(&resize_img, this->mean_, this->scale_,
|
||||
this->normalize_op_.Run(resize_img, this->mean_, this->scale_,
|
||||
this->is_scale_);
|
||||
|
||||
std::vector<float> input(1 * 3 * resize_img.rows * resize_img.cols, 0.0f);
|
||||
this->permute_op_.Run(&resize_img, input.data());
|
||||
this->permute_op_.Run(resize_img, input.data());
|
||||
auto preprocess_end = std::chrono::steady_clock::now();
|
||||
preprocess_diff += preprocess_end - preprocess_start;
|
||||
|
||||
|
@ -59,12 +59,12 @@ void StructureLayoutRecognizer::Run(cv::Mat img,
|
|||
std::vector<int> output_shape = output_tensor->shape();
|
||||
int out_num = std::accumulate(output_shape.begin(), output_shape.end(), 1,
|
||||
std::multiplies<int>());
|
||||
output_shape_list.push_back(output_shape);
|
||||
output_shape_list.emplace_back(std::move(output_shape));
|
||||
|
||||
std::vector<float> out_data;
|
||||
out_data.resize(out_num);
|
||||
output_tensor->CopyToCpu(out_data.data());
|
||||
out_tensor_list.push_back(out_data);
|
||||
out_tensor_list.emplace_back(std::move(out_data));
|
||||
}
|
||||
auto inference_end = std::chrono::steady_clock::now();
|
||||
inference_diff += inference_end - inference_start;
|
||||
|
@ -74,8 +74,8 @@ void StructureLayoutRecognizer::Run(cv::Mat img,
|
|||
|
||||
std::vector<int> bbox_num;
|
||||
int reg_max = 0;
|
||||
for (int i = 0; i < out_tensor_list.size(); i++) {
|
||||
if (i == this->post_processor_.fpn_stride_.size()) {
|
||||
for (int i = 0; i < out_tensor_list.size(); ++i) {
|
||||
if (i == this->post_processor_.fpn_stride_size()) {
|
||||
reg_max = output_shape_list[i][2] / 4;
|
||||
break;
|
||||
}
|
||||
|
@ -84,13 +84,13 @@ void StructureLayoutRecognizer::Run(cv::Mat img,
|
|||
std::vector<int> resize_shape = {resize_img.rows, resize_img.cols};
|
||||
this->post_processor_.Run(result, out_tensor_list, ori_shape, resize_shape,
|
||||
reg_max);
|
||||
bbox_num.push_back(result.size());
|
||||
bbox_num.emplace_back(result.size());
|
||||
|
||||
auto postprocess_end = std::chrono::steady_clock::now();
|
||||
postprocess_diff += postprocess_end - postprocess_start;
|
||||
times.push_back(double(preprocess_diff.count() * 1000));
|
||||
times.push_back(double(inference_diff.count() * 1000));
|
||||
times.push_back(double(postprocess_diff.count() * 1000));
|
||||
times.emplace_back(preprocess_diff.count() * 1000);
|
||||
times.emplace_back(inference_diff.count() * 1000);
|
||||
times.emplace_back(postprocess_diff.count() * 1000);
|
||||
}
|
||||
|
||||
void StructureLayoutRecognizer::LoadModel(const std::string &model_dir) {
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
namespace PaddleOCR {
|
||||
|
||||
void StructureTableRecognizer::Run(
|
||||
std::vector<cv::Mat> img_list,
|
||||
const std::vector<cv::Mat> &img_list,
|
||||
std::vector<std::vector<std::string>> &structure_html_tags,
|
||||
std::vector<float> &structure_scores,
|
||||
std::vector<std::vector<std::vector<int>>> &structure_boxes,
|
||||
|
@ -45,12 +45,12 @@ void StructureTableRecognizer::Run(
|
|||
cv::Mat resize_img;
|
||||
cv::Mat pad_img;
|
||||
this->resize_op_.Run(srcimg, resize_img, this->table_max_len_);
|
||||
this->normalize_op_.Run(&resize_img, this->mean_, this->scale_,
|
||||
this->normalize_op_.Run(resize_img, this->mean_, this->scale_,
|
||||
this->is_scale_);
|
||||
this->pad_op_.Run(resize_img, pad_img, this->table_max_len_);
|
||||
norm_img_batch.push_back(pad_img);
|
||||
width_list.push_back(srcimg.cols);
|
||||
height_list.push_back(srcimg.rows);
|
||||
norm_img_batch.emplace_back(std::move(pad_img));
|
||||
width_list.emplace_back(srcimg.cols);
|
||||
height_list.emplace_back(srcimg.rows);
|
||||
}
|
||||
|
||||
std::vector<float> input(
|
||||
|
@ -96,24 +96,24 @@ void StructureTableRecognizer::Run(
|
|||
width_list, height_list);
|
||||
for (int m = 0; m < predict_shape0[0]; m++) {
|
||||
|
||||
structure_html_tag_batch[m].insert(structure_html_tag_batch[m].begin(),
|
||||
"<table>");
|
||||
structure_html_tag_batch[m].insert(structure_html_tag_batch[m].begin(),
|
||||
"<body>");
|
||||
structure_html_tag_batch[m].insert(structure_html_tag_batch[m].begin(),
|
||||
"<html>");
|
||||
structure_html_tag_batch[m].push_back("</table>");
|
||||
structure_html_tag_batch[m].push_back("</body>");
|
||||
structure_html_tag_batch[m].push_back("</html>");
|
||||
structure_html_tags.push_back(structure_html_tag_batch[m]);
|
||||
structure_scores.push_back(structure_score_batch[m]);
|
||||
structure_boxes.push_back(structure_boxes_batch[m]);
|
||||
structure_html_tag_batch[m].emplace(structure_html_tag_batch[m].begin(),
|
||||
"<table>");
|
||||
structure_html_tag_batch[m].emplace(structure_html_tag_batch[m].begin(),
|
||||
"<body>");
|
||||
structure_html_tag_batch[m].emplace(structure_html_tag_batch[m].begin(),
|
||||
"<html>");
|
||||
structure_html_tag_batch[m].emplace_back("</table>");
|
||||
structure_html_tag_batch[m].emplace_back("</body>");
|
||||
structure_html_tag_batch[m].emplace_back("</html>");
|
||||
structure_html_tags.emplace_back(std::move(structure_html_tag_batch[m]));
|
||||
structure_scores.emplace_back(structure_score_batch[m]);
|
||||
structure_boxes.emplace_back(std::move(structure_boxes_batch[m]));
|
||||
}
|
||||
auto postprocess_end = std::chrono::steady_clock::now();
|
||||
postprocess_diff += postprocess_end - postprocess_start;
|
||||
times.push_back(double(preprocess_diff.count() * 1000));
|
||||
times.push_back(double(inference_diff.count() * 1000));
|
||||
times.push_back(double(postprocess_diff.count() * 1000));
|
||||
times.emplace_back(preprocess_diff.count() * 1000);
|
||||
times.emplace_back(inference_diff.count() * 1000);
|
||||
times.emplace_back(postprocess_diff.count() * 1000);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -28,12 +28,14 @@
|
|||
namespace PaddleOCR {
|
||||
|
||||
std::vector<std::string> Utility::ReadDict(const std::string &path) {
|
||||
std::ifstream in(path);
|
||||
std::string line;
|
||||
std::vector<std::string> m_vec;
|
||||
std::ifstream in(path);
|
||||
if (in) {
|
||||
while (getline(in, line)) {
|
||||
m_vec.push_back(line);
|
||||
for (;;) {
|
||||
std::string line;
|
||||
if (!getline(in, line))
|
||||
break;
|
||||
m_vec.emplace_back(std::move(line));
|
||||
}
|
||||
} else {
|
||||
std::cout << "no such label file: " << path << ", exit the program..."
|
||||
|
@ -48,9 +50,9 @@ void Utility::VisualizeBboxes(const cv::Mat &srcimg,
|
|||
const std::string &save_path) {
|
||||
cv::Mat img_vis;
|
||||
srcimg.copyTo(img_vis);
|
||||
for (int n = 0; n < ocr_result.size(); n++) {
|
||||
for (int n = 0; n < ocr_result.size(); ++n) {
|
||||
cv::Point rook_points[4];
|
||||
for (int m = 0; m < ocr_result[n].box.size(); m++) {
|
||||
for (int m = 0; m < ocr_result[n].box.size(); ++m) {
|
||||
rook_points[m] =
|
||||
cv::Point(int(ocr_result[n].box[m][0]), int(ocr_result[n].box[m][1]));
|
||||
}
|
||||
|
@ -71,7 +73,7 @@ void Utility::VisualizeBboxes(const cv::Mat &srcimg,
|
|||
cv::Mat img_vis;
|
||||
srcimg.copyTo(img_vis);
|
||||
img_vis = crop_image(img_vis, structure_result.box);
|
||||
for (int n = 0; n < structure_result.cell_box.size(); n++) {
|
||||
for (int n = 0; n < structure_result.cell_box.size(); ++n) {
|
||||
if (structure_result.cell_box[n].size() == 8) {
|
||||
cv::Point rook_points[4];
|
||||
for (int m = 0; m < structure_result.cell_box[n].size(); m += 2) {
|
||||
|
@ -83,11 +85,11 @@ void Utility::VisualizeBboxes(const cv::Mat &srcimg,
|
|||
int npt[] = {4};
|
||||
cv::polylines(img_vis, ppt, npt, 1, 1, CV_RGB(0, 255, 0), 2, 8, 0);
|
||||
} else if (structure_result.cell_box[n].size() == 4) {
|
||||
cv::Point rook_points[2];
|
||||
rook_points[0] = cv::Point(int(structure_result.cell_box[n][0]),
|
||||
int(structure_result.cell_box[n][1]));
|
||||
rook_points[1] = cv::Point(int(structure_result.cell_box[n][2]),
|
||||
int(structure_result.cell_box[n][3]));
|
||||
cv::Point rook_points[2] = {
|
||||
cv::Point(int(structure_result.cell_box[n][0]),
|
||||
int(structure_result.cell_box[n][1])),
|
||||
cv::Point(int(structure_result.cell_box[n][2]),
|
||||
int(structure_result.cell_box[n][3]))};
|
||||
cv::rectangle(img_vis, rook_points[0], rook_points[1], CV_RGB(0, 255, 0),
|
||||
2, 8, 0);
|
||||
}
|
||||
|
@ -108,7 +110,7 @@ void Utility::GetAllFiles(const char *dir_name,
|
|||
stat(dir_name, &s);
|
||||
if (!S_ISDIR(s.st_mode)) {
|
||||
std::cout << "dir_name is not a valid directory !" << std::endl;
|
||||
all_inputs.push_back(dir_name);
|
||||
all_inputs.emplace_back(dir_name);
|
||||
return;
|
||||
} else {
|
||||
struct dirent *filename; // return value for readdir()
|
||||
|
@ -124,14 +126,14 @@ void Utility::GetAllFiles(const char *dir_name,
|
|||
strcmp(filename->d_name, "..") == 0)
|
||||
continue;
|
||||
// img_dir + std::string("/") + all_inputs[0];
|
||||
all_inputs.push_back(dir_name + std::string("/") +
|
||||
std::string(filename->d_name));
|
||||
all_inputs.emplace_back(dir_name + std::string("/") +
|
||||
std::string(filename->d_name));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cv::Mat Utility::GetRotateCropImage(const cv::Mat &srcimage,
|
||||
std::vector<std::vector<int>> box) {
|
||||
const std::vector<std::vector<int>> &box) {
|
||||
cv::Mat image;
|
||||
srcimage.copyTo(image);
|
||||
std::vector<std::vector<int>> points = box;
|
||||
|
@ -146,7 +148,7 @@ cv::Mat Utility::GetRotateCropImage(const cv::Mat &srcimage,
|
|||
cv::Mat img_crop;
|
||||
image(cv::Rect(left, top, right - left, bottom - top)).copyTo(img_crop);
|
||||
|
||||
for (int i = 0; i < points.size(); i++) {
|
||||
for (int i = 0; i < points.size(); ++i) {
|
||||
points[i][0] -= left;
|
||||
points[i][1] -= top;
|
||||
}
|
||||
|
@ -176,7 +178,7 @@ cv::Mat Utility::GetRotateCropImage(const cv::Mat &srcimage,
|
|||
cv::BORDER_REPLICATE);
|
||||
|
||||
if (float(dst_img.rows) >= float(dst_img.cols) * 1.5) {
|
||||
cv::Mat srcCopy = cv::Mat(dst_img.rows, dst_img.cols, dst_img.depth());
|
||||
cv::Mat srcCopy(dst_img.rows, dst_img.cols, dst_img.depth());
|
||||
cv::transpose(dst_img, srcCopy);
|
||||
cv::flip(srcCopy, srcCopy, 0);
|
||||
return srcCopy;
|
||||
|
@ -186,9 +188,8 @@ cv::Mat Utility::GetRotateCropImage(const cv::Mat &srcimage,
|
|||
}
|
||||
|
||||
std::vector<int> Utility::argsort(const std::vector<float> &array) {
|
||||
const int array_len(array.size());
|
||||
std::vector<int> array_index(array_len, 0);
|
||||
for (int i = 0; i < array_len; ++i)
|
||||
std::vector<int> array_index(array.size(), 0);
|
||||
for (int i = 0; i < array.size(); ++i)
|
||||
array_index[i] = i;
|
||||
|
||||
std::sort(
|
||||
|
@ -244,18 +245,20 @@ bool Utility::PathExists(const std::string &path) {
|
|||
}
|
||||
|
||||
void Utility::CreateDir(const std::string &path) {
|
||||
#ifdef _WIN32
|
||||
#ifdef _MSC_VER
|
||||
_mkdir(path.c_str());
|
||||
#elif defined __MINGW32__
|
||||
mkdir(path.c_str());
|
||||
#else
|
||||
mkdir(path.c_str(), 0777);
|
||||
#endif // !_WIN32
|
||||
}
|
||||
|
||||
void Utility::print_result(const std::vector<OCRPredictResult> &ocr_result) {
|
||||
for (int i = 0; i < ocr_result.size(); i++) {
|
||||
for (int i = 0; i < ocr_result.size(); ++i) {
|
||||
std::cout << i << "\t";
|
||||
// det
|
||||
std::vector<std::vector<int>> boxes = ocr_result[i].box;
|
||||
const std::vector<std::vector<int>> &boxes = ocr_result[i].box;
|
||||
if (boxes.size() > 0) {
|
||||
std::cout << "det boxes: [";
|
||||
for (int n = 0; n < boxes.size(); n++) {
|
||||
|
@ -282,13 +285,12 @@ void Utility::print_result(const std::vector<OCRPredictResult> &ocr_result) {
|
|||
}
|
||||
|
||||
cv::Mat Utility::crop_image(cv::Mat &img, const std::vector<int> &box) {
|
||||
cv::Mat crop_im;
|
||||
cv::Mat crop_im = cv::Mat::zeros(box[3] - box[1], box[2] - box[0], 16);
|
||||
int crop_x1 = std::max(0, box[0]);
|
||||
int crop_y1 = std::max(0, box[1]);
|
||||
int crop_x2 = std::min(img.cols - 1, box[2] - 1);
|
||||
int crop_y2 = std::min(img.rows - 1, box[3] - 1);
|
||||
|
||||
crop_im = cv::Mat::zeros(box[3] - box[1], box[2] - box[0], 16);
|
||||
cv::Mat crop_im_window =
|
||||
crop_im(cv::Range(crop_y1 - box[1], crop_y2 + 1 - box[1]),
|
||||
cv::Range(crop_x1 - box[0], crop_x2 + 1 - box[0]));
|
||||
|
@ -307,7 +309,7 @@ cv::Mat Utility::crop_image(cv::Mat &img, const std::vector<float> &box) {
|
|||
void Utility::sorted_boxes(std::vector<OCRPredictResult> &ocr_result) {
|
||||
std::sort(ocr_result.begin(), ocr_result.end(), Utility::comparison_box);
|
||||
if (ocr_result.size() > 0) {
|
||||
for (int i = 0; i < ocr_result.size() - 1; i++) {
|
||||
for (int i = 0; i < ocr_result.size() - 1; ++i) {
|
||||
for (int j = i; j >= 0; j--) {
|
||||
if (abs(ocr_result[j + 1].box[0][1] - ocr_result[j].box[0][1]) < 10 &&
|
||||
(ocr_result[j + 1].box[0][0] < ocr_result[j].box[0][0])) {
|
||||
|
@ -318,7 +320,8 @@ void Utility::sorted_boxes(std::vector<OCRPredictResult> &ocr_result) {
|
|||
}
|
||||
}
|
||||
|
||||
std::vector<int> Utility::xyxyxyxy2xyxy(std::vector<std::vector<int>> &box) {
|
||||
std::vector<int>
|
||||
Utility::xyxyxyxy2xyxy(const std::vector<std::vector<int>> &box) {
|
||||
int x_collect[4] = {box[0][0], box[1][0], box[2][0], box[3][0]};
|
||||
int y_collect[4] = {box[0][1], box[1][1], box[2][1], box[3][1]};
|
||||
int left = int(*std::min_element(x_collect, x_collect + 4));
|
||||
|
@ -333,7 +336,7 @@ std::vector<int> Utility::xyxyxyxy2xyxy(std::vector<std::vector<int>> &box) {
|
|||
return box1;
|
||||
}
|
||||
|
||||
std::vector<int> Utility::xyxyxyxy2xyxy(std::vector<int> &box) {
|
||||
std::vector<int> Utility::xyxyxyxy2xyxy(const std::vector<int> &box) {
|
||||
int x_collect[4] = {box[0], box[2], box[4], box[6]};
|
||||
int y_collect[4] = {box[1], box[3], box[5], box[7]};
|
||||
int left = int(*std::min_element(x_collect, x_collect + 4));
|
||||
|
|
Loading…
Reference in New Issue