CPP: emplace_back() replaces many push_back()...to improve performance (#14610)

pull/14613/head
nonwill 2025-02-03 19:35:16 +08:00 committed by GitHub
parent 19c58a3974
commit 42a3c77309
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
23 changed files with 426 additions and 403 deletions

View File

@ -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;
}
};
//------------------------------------------------------------------------------

View File

@ -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> &times);
private:

View File

@ -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> &times);
private:

View File

@ -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> &times);
private:

View File

@ -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:

View File

@ -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) {

View File

@ -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;

View File

@ -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 {

View File

@ -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> &times);
private:

View File

@ -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,

View File

@ -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>

View File

@ -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;

View File

@ -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) {

View File

@ -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> &times) {
@ -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) {

View File

@ -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> &times) {
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

View File

@ -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> &times) {
@ -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) {

View File

@ -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];
}

View File

@ -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];

View File

@ -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

View File

@ -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;

View File

@ -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> &times) {
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) {

View File

@ -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);
}
}

View File

@ -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));