Skip to content

Commit c35d1cd

Browse files
committed
関連の競プロ問題や質問掲示板、論文を調査
1 parent 6f815a0 commit c35d1cd

File tree

1 file changed

+68
-27
lines changed

1 file changed

+68
-27
lines changed

modules/ximgproc/src/sparse_table_morphology.cpp

Lines changed: 68 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,39 @@ static inline Point normalizeAnchor(Point anchor, Size ksize)
5555
return anchor;
5656
}
5757

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)
5991
{
6092
std::vector<Rect> rects;
6193
Mat kernel = _kernel.getMat();
@@ -87,26 +119,19 @@ static std::vector<Rect> GetCoveringRectangles(InputArray _kernel)
87119
return rects;
88120
}
89121

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)
91132
{
92-
Col, Row
93-
};
133+
// todo: implement the reference paper 2-approximation algorithm
94134

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-
{
110135
std::vector<StStep> ans;
111136
std::vector<std::vector<bool>> visitedMap(sparseMatMap.size(), std::vector<bool>(sparseMatMap[0].size(), false));
112137
visitedMap[0][0] = true;
@@ -138,7 +163,7 @@ std::vector<StStep> makePlan(std::vector<std::vector<bool>> sparseMatMap)
138163
return ans;
139164
}
140165

141-
void MakeMinStMat(InputArray src, OutputArray dst, int rowStep, int colStep)
166+
static void makeMinStMat(InputArray src, OutputArray dst, int rowStep, int colStep)
142167
{
143168
CV_Assert(rowStep * colStep == 0); // one of "rowStep" or "colStep" is required to be 0.
144169

@@ -171,21 +196,37 @@ void MakeMinStMat(InputArray src, OutputArray dst, int rowStep, int colStep)
171196
dstPtr += borderSkipStep;
172197
}
173198
}
174-
void MakeMaxStMat(InputArray src, OutputArray dst, int rowStep, int colStep)
199+
static void makeMaxStMat(InputArray src, OutputArray dst, int rowStep, int colStep)
175200
{
176201
CV_Assert(rowStep * colStep == 0); // one of "rowStep" or "colStep" is required to be 0.
177202

178203
Mat src_ = src.getMat();
179204
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+
180209
uchar* srcPtr1 = src_.ptr<uchar>(0, 0);
181210
uchar* srcPtr2 = src_.ptr<uchar>(rowStep, colStep);
182211
uchar* dstPtr = dst_.ptr<uchar>(0, 0);
183-
for (int row = 0; row < src.rows(); row++)
212+
for (int row = 0; row < rowLim; row++)
184213
{
185-
for (int col = 0; col < src.cols(); col++)
214+
for (int colCh = 0; colCh < colChLim; colCh++)
186215
{
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+
}
188226
}
227+
srcPtr1 += borderSkipStep;
228+
srcPtr2 += borderSkipStep;
229+
dstPtr += borderSkipStep;
189230
}
190231
}
191232

@@ -230,7 +271,7 @@ void erode(InputArray _src, OutputArray _dst, InputArray _kernel,
230271
cv::copyMakeBorder(src, expandedSrc, anchor.y, kernel.cols - 1 - anchor.y, anchor.x, kernel.rows - 1 - anchor.x, borderType, bV);
231272

232273
// generating a set of rectangles that covers whole kernel
233-
std::vector<Rect> rects = GetCoveringRectangles(kernel);
274+
std::vector<Rect> rects = getCoveringRectangles(kernel);
234275

235276
// log2 table construction
236277
int len = max(kernel.rows, kernel.cols) + 1;
@@ -272,11 +313,11 @@ void erode(InputArray _src, OutputArray _dst, InputArray _kernel,
272313
{
273314
case Dim::Col:
274315
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);
276317
break;
277318
case Dim::Row:
278319
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);
280321
break;
281322
}
282323
}

0 commit comments

Comments
 (0)