Skip to content

Commit 36c58b4

Browse files
committed
Add depth function to export and find contour alg
1 parent fddac5c commit 36c58b4

File tree

6 files changed

+254
-22
lines changed

6 files changed

+254
-22
lines changed

PrjBarlib/extra/Barpy.cpp

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
#ifdef _PYD
2-
31
#include "barcodeCreator.h"
42
#include "barImg.h"
53
#include "include_py.h"
4+
#include "../modules/contour.h"
5+
66
#include <pybind11/stl.h>
77
#include <pybind11/operators.h>
88

@@ -115,9 +115,12 @@ PYBIND11_MODULE(libbarpy, m)
115115
;
116116

117117
class_<bc::barline>(m, "Barline")
118+
.def("id", &bc::barline::getId)
119+
.def("parentId", &bc::barline::getParentId)
118120
.def("start", &bc::barline::getStart)
119121
.def("len", &bc::barline::getLength)
120122
.def("end", &bc::barline::getEnd)
123+
.def("depth", &bc::barline::getDeath)
121124
.def("getPoints", &bc::barline::getPoints, (arg("skipChildPoints") = false))
122125
.def("getMatrixSize", &bc::barline::getPointsSize)
123126
.def("getMatrixValue", &bc::barline::getPoint)
@@ -196,31 +199,38 @@ PYBIND11_MODULE(libbarpy, m)
196199
;
197200
;
198201

202+
class_<bc::Mutator>(m, "PointMutator")
203+
.def(py::init<>())
204+
.def_readwrite("local", &bc::Mutator::local)
205+
.def_readwrite("absolute", &bc::Mutator::global)
206+
.def_readwrite("offset", &bc::Mutator::offset)
207+
.def("convert", &bc::Mutator::convert)
208+
;
209+
;
210+
199211
m.def("create", &bc::BarcodeCreator::pycreate, R"pbdoc(
200212
Create a single barcode
201-
202-
Some other explanation about the add function.
203213
)pbdoc");
204214

205215
m.def("createByMask", &bc::BarcodeCreator::pycreateByMask, R"pbdoc(
206216
Create a single barcode but admit only pixels from mask
207-
208-
Some other explanation about the add function.
209217
)pbdoc");
210218

211219
m.def("createMultiple", &bc::BarcodeCreator::pycreateMultiple, R"pbdoc(
212220
Create multiple barcodes from a single image
213-
214-
Some other explanation about the add function.
215221
)pbdoc");
216222

223+
m.def("find_contour", &bc::findContour, R"pbdoc(
224+
Find contour of a barcode line
225+
)pbdoc");
226+
227+
m.def("convert_las_points_to_dict", &bc::convertLasPointsToDict, R"pbdoc(
228+
Find contour of a barcode line
229+
)pbdoc");
217230

218231
#ifdef VERSION_INFO
219232
m.attr("__version__") = VERSION_INFO;
220233
#else
221234
m.attr("__version__") = "dev";
222235
#endif
223236
}
224-
225-
226-
#endif // _PYD

PrjBarlib/include/barImg.h

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -634,7 +634,6 @@ MEXP namespace bc {
634634

635635
BarNdarray(bn::array& _mat) : mat(_mat), strides(mat.strides())
636636
{
637-
std::puts("DEBUG: BarNdarray ctor");
638637
const auto mtype = mat.dtype();
639638

640639
if (mat.ndim() == 3)
@@ -659,15 +658,6 @@ MEXP namespace bc {
659658
type = BarType::BYTE8_1;
660659
else
661660
throw pybind11::type_error("Unsupported numpy type");
662-
663-
std::cout<< "Size wid: " << mat.shape(1) << std::endl;
664-
std::cout<< "Size hei: " << mat.shape(0) << std::endl;
665-
std::cout<< "The first value: " << get(0,0).getAvgFloat() << std::endl;
666-
}
667-
668-
~BarNdarray()
669-
{
670-
std::puts("DEBUG: BarNdarray ~dtro");
671661
}
672662

673663
int wid() const override

PrjBarlib/include/barline.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -322,6 +322,16 @@ MEXP namespace bc
322322
return m_end > start ? m_end - start : start - m_end;
323323
}
324324

325+
uint getId() const
326+
{
327+
return id;
328+
}
329+
330+
uint getParentId() const
331+
{
332+
return parentId;
333+
}
334+
325335
Barscalar getStart() const
326336
{
327337
return start;

PrjBarlib/modules/contour.cpp

Lines changed: 177 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,177 @@
1+
#include "contour.h"
2+
3+
#include <set>
4+
5+
inline constexpr int poss[16][2] = { {-1, 0}, {-1, -1}, {0, -1}, {1, -1}, {1, 0}, {1, 1}, {0, 1}, {-1, 1},
6+
{-1, 0}, {-1, -1}, {0, -1}, {1, -1}, {1, 0}, {1, 1}, {0, 1}, {-1, 1} };
7+
8+
namespace bc {
9+
10+
11+
class MapContour
12+
{
13+
OutputContour& contur;
14+
ushort accum = 1;
15+
16+
// Map
17+
std::set<unsigned int> points;
18+
19+
// Runtime
20+
enum StartPos : char { LeftMid = 0, LeftTop = 1, TopMid = 2, RigthTop = 3, RigthMid = 4, RigthBottom = 5, BottomMid = 6, LeftBottom = 7 };
21+
22+
public:
23+
MapContour(OutputContour& contur) : contur(contur)
24+
{ }
25+
26+
void set4Directions()
27+
{
28+
accum = 2;
29+
}
30+
31+
void set8Directions()
32+
{
33+
accum = 1;
34+
}
35+
36+
auto make_point(point p) const
37+
{
38+
return py::make_tuple(xm.convert(p.x), ym.convert(p.y));
39+
}
40+
41+
Mutator xm, ym;
42+
void run(int startX, int startY, Mutator xm, Mutator ym, const bool aproxim = false)
43+
{
44+
if (points.empty())
45+
return;
46+
47+
this->xm = xm;
48+
this->ym = ym;
49+
50+
StartPos dirct = RigthMid;
51+
const bc::point startPoint(startX, startY);
52+
bc::point cur(startPoint);
53+
54+
while (true)
55+
{
56+
ushort start = (dirct + 6) % 8; // Safe minus 2
57+
const ushort end = start + 7;
58+
// Check
59+
// 1 2 3
60+
// 0 X 4
61+
// 6 5
62+
63+
for (; start < end; start += accum)
64+
{
65+
const int* off = poss[start];
66+
const bc::point newPoint(cur.x + off[0], cur.y + off[1]);
67+
68+
if (this->exists(newPoint))
69+
{
70+
// Update dir
71+
const StartPos newDirection = (StartPos)(start % 8);
72+
73+
// In case of approximation
74+
// put only if direction has changed
75+
if (!aproxim || dirct != newDirection)
76+
{
77+
contur.append(make_point(cur));
78+
}
79+
80+
dirct = newDirection;
81+
cur = newPoint;
82+
if (cur == startPoint)
83+
{
84+
auto firstAddedPoint = contur[0].cast<py::tuple>();
85+
if (firstAddedPoint[0].cast<double>() != startPoint.x || firstAddedPoint[1].cast<double>() != startPoint.y)
86+
{
87+
contur.append(make_point(startPoint));
88+
}
89+
return;
90+
}
91+
92+
break;
93+
}
94+
}
95+
96+
// --------
97+
// not found assert
98+
assert(start < end);
99+
if (start >= end)
100+
return;
101+
}
102+
}
103+
104+
void set(const bc::barvalue& p) { points.insert(p.getIndex()); }
105+
void set(int x, int y) { points.insert(bc::barvalue::getStatInd(x, y)); }
106+
107+
private:
108+
109+
bool exists(bc::point p)
110+
{
111+
return points.contains(bc::barvalue::getStatInd(p.x, p.y));
112+
}
113+
};
114+
115+
116+
OutputContour findContour(const bc::barline& line, Mutator mx, Mutator my, bool aproximate)
117+
{
118+
OutputContour contour;
119+
120+
int stX = 99999999;
121+
int stY = 0;
122+
123+
MapContour dictPoints(contour);
124+
dictPoints.set8Directions();
125+
126+
const auto& points = line.matr;
127+
for (auto& p : points)
128+
{
129+
dictPoints.set(p);
130+
dictPoints.set(p.x, p.y + 1);
131+
dictPoints.set(p.x + 1, p.y);
132+
dictPoints.set(p.x + 1, p.y + 1);
133+
const int x = p.getX();
134+
const int y = p.getY();
135+
if (x < stX)
136+
{
137+
stX = x;
138+
stY = y;
139+
}
140+
}
141+
dictPoints.run(stX, stY, mx, my, aproximate);
142+
143+
return contour;
144+
}
145+
146+
template<class T>
147+
py::dict convertLasPointsToDictInner(const bn::array& x, const bn::array& y, const bn::array& z)
148+
{
149+
py::dict output;
150+
for (size_t i = 0, total = x.shape()[0]; i < total; i++)
151+
{
152+
T xv = *reinterpret_cast<const T*>(x.data(i));
153+
T yv = *reinterpret_cast<const T*>(y.data(i));
154+
T zv = *reinterpret_cast<const T*>(z.data(i));
155+
output[py::make_tuple(xv,yv)] = zv;
156+
}
157+
158+
return output;
159+
}
160+
py::dict convertLasPointsToDict(const bn::array& x, const bn::array& y, const bn::array& z)
161+
{
162+
auto mtype = z.dtype();
163+
if (mtype.is(pybind11::dtype::of<float>()))
164+
return convertLasPointsToDictInner<float>(x, y, z);
165+
else if (mtype.is(pybind11::dtype::of<double>()))
166+
return convertLasPointsToDictInner<double>(x, y, z);
167+
else if (mtype.is(pybind11::dtype::of<int8_t>()))
168+
return convertLasPointsToDictInner<int8_t>(x, y, z);
169+
else if (mtype.is(pybind11::dtype::of<int32_t>()))
170+
return convertLasPointsToDictInner<int32_t>(x, y, z);
171+
else if (mtype.is(pybind11::dtype::of<int64_t>()))
172+
return convertLasPointsToDictInner<int64_t>(x, y, z);
173+
else
174+
throw pybind11::type_error("Unsupported data type");
175+
}
176+
177+
}

PrjBarlib/modules/contour.h

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
#pragma once
2+
#include "barline.h"
3+
#include "../extra/include_py.h"
4+
5+
6+
namespace bc
7+
{
8+
struct ContourPoint
9+
{
10+
double x;
11+
double y;
12+
13+
bool operator==(ContourPoint rhs) const
14+
{
15+
return x == rhs.x && y == rhs.y;
16+
}
17+
18+
bool operator!=(ContourPoint rhs) const
19+
{
20+
return !operator==(rhs);
21+
}
22+
};
23+
24+
// #ifdef INCLUDE_PY
25+
using OutputContour = py::list;
26+
// #else
27+
// using OutputContour = std::vector<ContourPoint>;
28+
// #endif
29+
30+
struct Mutator
31+
{
32+
double local;
33+
double global;
34+
double offset;
35+
36+
constexpr double convert(double value) const
37+
{
38+
return (offset + value * local) * global;
39+
}
40+
};
41+
42+
OutputContour findContour(const bc::barline& line, Mutator x, Mutator y, bool aproximate);
43+
py::dict convertLasPointsToDict(const bn::array& x, const bn::array& y, const bn::array& z);
44+
}

PrjBarlib/premake5.lua

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,8 @@ project "Barlib"
155155
"source/barcodeCreator.cpp",
156156
"source/component.cpp",
157157
"source/hole.cpp",
158-
"extra/Barpy.cpp"
158+
"extra/Barpy.cpp",
159+
"modules/contour.cpp"
159160
}
160161

161162
-- This part handles additional dependencies

0 commit comments

Comments
 (0)