@@ -55,7 +55,39 @@ static inline Point normalizeAnchor(Point anchor, Size ksize)
55
55
return anchor;
56
56
}
57
57
58
- static std::vector<Rect> GetCoveringRectangles (InputArray _kernel)
58
+ enum Dim
59
+ {
60
+ Col, Row
61
+ };
62
+
63
+ struct StStep
64
+ {
65
+ StStep (int dimR, int dimC, Dim _ax)
66
+ {
67
+ dimRow = dimR;
68
+ dimCol = dimC;
69
+ ax = _ax;
70
+ }
71
+ int dimRow;
72
+ int dimCol;
73
+ Dim ax;
74
+ };
75
+
76
+ /*
77
+ * Find a set of rectangles which coveres the kernel.
78
+ *
79
+ * The exact problem is defined and a not-optimal solution is proposed.
80
+ * https://stackoverflow.com/questions/22769490/finding-the-smallest-set-of-rectangles-that-covers-the-given-rectilinear-simple
81
+ *
82
+ * Similer problem and a link to a paper.
83
+ * https://stackoverflow.com/questions/31150398/maximal-rectangle-set-cover
84
+ *
85
+ * The paper. Names the problem "MISR".
86
+ * https://home.ttic.edu/~cjulia/papers/rectangles-SODA.pdf ... x-approximation?
87
+ * https://home.ttic.edu/~cjulia/papers/MISR.pdf ... (1-e)-approximation?
88
+ *
89
+ */
90
+ static std::vector<Rect> getCoveringRectangles (InputArray _kernel)
59
91
{
60
92
std::vector<Rect> rects;
61
93
Mat kernel = _kernel.getMat ();
@@ -87,26 +119,19 @@ static std::vector<Rect> GetCoveringRectangles(InputArray _kernel)
87
119
return rects;
88
120
}
89
121
90
- enum Dim
122
+ /*
123
+ *
124
+ *
125
+ * AtCoder: https://atcoder.jp/contests/ahc037/tasks/ahc037_a
126
+ *
127
+ * The rectilinear steiner arborescence problem
128
+ * https://link.springer.com/article/10.1007/BF01758762
129
+ *
130
+ */
131
+ static std::vector<StStep> makePlan (std::vector<std::vector<bool >> sparseMatMap)
91
132
{
92
- Col, Row
93
- };
133
+ // todo: implement the reference paper 2-approximation algorithm
94
134
95
- struct StStep
96
- {
97
- StStep (int dimR, int dimC, Dim _ax)
98
- {
99
- dimRow = dimR;
100
- dimCol = dimC;
101
- ax = _ax;
102
- }
103
- int dimRow;
104
- int dimCol;
105
- Dim ax;
106
- };
107
-
108
- std::vector<StStep> makePlan (std::vector<std::vector<bool >> sparseMatMap)
109
- {
110
135
std::vector<StStep> ans;
111
136
std::vector<std::vector<bool >> visitedMap (sparseMatMap.size (), std::vector<bool >(sparseMatMap[0 ].size (), false ));
112
137
visitedMap[0 ][0 ] = true ;
@@ -138,7 +163,7 @@ std::vector<StStep> makePlan(std::vector<std::vector<bool>> sparseMatMap)
138
163
return ans;
139
164
}
140
165
141
- void MakeMinStMat (InputArray src, OutputArray dst, int rowStep, int colStep)
166
+ static void makeMinStMat (InputArray src, OutputArray dst, int rowStep, int colStep)
142
167
{
143
168
CV_Assert (rowStep * colStep == 0 ); // one of "rowStep" or "colStep" is required to be 0.
144
169
@@ -171,21 +196,37 @@ void MakeMinStMat(InputArray src, OutputArray dst, int rowStep, int colStep)
171
196
dstPtr += borderSkipStep;
172
197
}
173
198
}
174
- void MakeMaxStMat (InputArray src, OutputArray dst, int rowStep, int colStep)
199
+ static void makeMaxStMat (InputArray src, OutputArray dst, int rowStep, int colStep)
175
200
{
176
201
CV_Assert (rowStep * colStep == 0 ); // one of "rowStep" or "colStep" is required to be 0.
177
202
178
203
Mat src_ = src.getMat ();
179
204
Mat dst_ = dst.getMat ();
205
+ int rowLim = src.rows () - rowStep;
206
+ int colChLim = (src.cols () - colStep) * src.channels ();
207
+ int borderSkipStep = colStep * src.channels ();
208
+
180
209
uchar* srcPtr1 = src_.ptr <uchar>(0 , 0 );
181
210
uchar* srcPtr2 = src_.ptr <uchar>(rowStep, colStep);
182
211
uchar* dstPtr = dst_.ptr <uchar>(0 , 0 );
183
- for (int row = 0 ; row < src. rows () ; row++)
212
+ for (int row = 0 ; row < rowLim ; row++)
184
213
{
185
- for (int col = 0 ; col < src. cols (); col ++)
214
+ for (int colCh = 0 ; colCh < colChLim; colCh ++)
186
215
{
187
- *dstPtr = max (*srcPtr1, *srcPtr2);
216
+ if (*srcPtr1 > *srcPtr2)
217
+ {
218
+ *dstPtr++ = *srcPtr1++;
219
+ srcPtr2++;
220
+ }
221
+ else
222
+ {
223
+ *dstPtr++ = *srcPtr2++;
224
+ srcPtr1++;
225
+ }
188
226
}
227
+ srcPtr1 += borderSkipStep;
228
+ srcPtr2 += borderSkipStep;
229
+ dstPtr += borderSkipStep;
189
230
}
190
231
}
191
232
@@ -230,7 +271,7 @@ void erode(InputArray _src, OutputArray _dst, InputArray _kernel,
230
271
cv::copyMakeBorder (src, expandedSrc, anchor.y , kernel.cols - 1 - anchor.y , anchor.x , kernel.rows - 1 - anchor.x , borderType, bV);
231
272
232
273
// generating a set of rectangles that covers whole kernel
233
- std::vector<Rect> rects = GetCoveringRectangles (kernel);
274
+ std::vector<Rect> rects = getCoveringRectangles (kernel);
234
275
235
276
// log2 table construction
236
277
int len = max (kernel.rows , kernel.cols ) + 1 ;
@@ -272,11 +313,11 @@ void erode(InputArray _src, OutputArray _dst, InputArray _kernel,
272
313
{
273
314
case Dim::Col:
274
315
st[step.dimRow ][step.dimCol + 1 ] = new Mat (expandedSrc.rows , expandedSrc.cols , expandedSrc.type ());
275
- MakeMinStMat (*st[step.dimRow ][step.dimCol ], *st[step.dimRow ][step.dimCol + 1 ], 0 , 1 << step.dimCol );
316
+ makeMinStMat (*st[step.dimRow ][step.dimCol ], *st[step.dimRow ][step.dimCol + 1 ], 0 , 1 << step.dimCol );
276
317
break ;
277
318
case Dim::Row:
278
319
st[step.dimRow + 1 ][step.dimCol ] = new Mat (expandedSrc.rows , expandedSrc.cols , expandedSrc.type ());
279
- MakeMinStMat (*st[step.dimRow ][step.dimCol ], *st[step.dimRow + 1 ][step.dimCol ], 1 << step.dimRow , 0 );
320
+ makeMinStMat (*st[step.dimRow ][step.dimCol ], *st[step.dimRow + 1 ][step.dimCol ], 1 << step.dimRow , 0 );
280
321
break ;
281
322
}
282
323
}
0 commit comments