Skip to content

Commit 32f11f4

Browse files
committed
2冪長方形分割の修正
1 parent db3d66e commit 32f11f4

File tree

2 files changed

+53
-46
lines changed

2 files changed

+53
-46
lines changed

modules/ximgproc/src/sparse_table_morphology.cpp

Lines changed: 10 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -161,28 +161,18 @@ std::vector<Rect> genPow2RectsToCoverKernel(InputArray _kernel)
161161
{
162162
for (int col = 0; col < colLim; col++, ptr++)
163163
{
164+
// ignore black cell
164165
if (ptr[0] == 0) continue;
165166

166-
if (0 < row && ptr[-1] == 1
167-
&& row < rowLim - 1 && ptr[1] == 1
168-
&& 0 < col && ptr[-1] == 1
169-
&& col < colLim - 1 && ptr[1] == 1) continue;
170-
171-
if (rowDepth < log2[kernel.rows] &&
172-
(st[rowDepth + 1][colDepth].ptr(row, col)[0] == 1 ||
173-
(row > (1 << rowDepth) - 1 &&
174-
st[rowDepth + 1][colDepth].ptr(row - (1 << (rowDepth)), col)[0] == 1
175-
)
176-
)
177-
) continue;
178-
179-
if (colDepth < log2[kernel.cols] &&
180-
(st[rowDepth][colDepth + 1].ptr(row, col)[0] == 1 ||
181-
(col > (1 << colDepth) - 1 &&
182-
st[rowDepth][colDepth + 1].ptr(row, col - (1 << (colDepth)))[0] == 1
183-
)
184-
)
185-
) continue;
167+
// ignore if both sides are white by each axis
168+
if (col > 0 && ptr[-1] == 1 && col < colLim && ptr[1] == 1) continue;
169+
if (row > 0 && ptr[-kernel.cols] && row < rowLim && ptr[kernel.cols] == 1) continue;
170+
171+
// ignore one of neighbor block is white; will be alive in deeper table
172+
if (col + (1 << colDepth) <= colLim && ptr[1 << colDepth] == 1) continue;
173+
if (col - (1 << colDepth) >= 0 && ptr[-(1 << colDepth)] == 1) continue;
174+
if (row + (1 << rowDepth) <= rowLim && ptr[(1 << rowDepth) * kernel.cols] == 1) continue;
175+
if (row - (1 << rowDepth) >= 0 && ptr[-(1 << rowDepth) * kernel.cols] == 1) continue;
186176

187177
p2Rects.emplace_back(col, row, colDepth, rowDepth);
188178
}

modules/ximgproc/test/test_sparse_table_morphology.cpp

Lines changed: 43 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,8 @@ TEST(ximgproc_SparseTableMorph, compare_with_original_erode)
6868
CV_Assert(max == 0);
6969
}
7070

71-
71+
// this method may be applied for the covering polygon problem with rectangle.
72+
// https://www.sciencedirect.com/science/article/pii/S0019995884800121
7273
std::tuple<std::vector<std::vector<Mat>>, std::vector<Rect>> genPow2RectsToCoverKernel_dev(InputArray _kernel)
7374
{
7475
CV_Assert(_kernel.type() == CV_8UC1);
@@ -152,28 +153,18 @@ std::tuple<std::vector<std::vector<Mat>>, std::vector<Rect>> genPow2RectsToCover
152153
{
153154
for (int col = 0; col < colLim; col++, ptr++)
154155
{
156+
// ignore black cell
155157
if (ptr[0] == 0) continue;
156158

157-
if (0 < row && ptr[-1] == 1
158-
&& row < rowLim - 1 && ptr[1] == 1
159-
&& 0 < col && ptr[-1] == 1
160-
&& col < colLim - 1 && ptr[1] == 1) continue;
161-
162-
if (rowDepth < log2[kernel.rows] &&
163-
(st[rowDepth + 1][colDepth].ptr(row, col)[0] == 1 ||
164-
(row > (1 << rowDepth) - 1 &&
165-
st[rowDepth + 1][colDepth].ptr(row - (1 << (rowDepth)), col)[0] == 1
166-
)
167-
)
168-
) continue;
169-
170-
if (colDepth < log2[kernel.cols] &&
171-
(st[rowDepth][colDepth + 1].ptr(row, col)[0] == 1 ||
172-
(col > (1 << colDepth) - 1 &&
173-
st[rowDepth][colDepth + 1].ptr(row, col - (1 << (colDepth)))[0] == 1
174-
)
175-
)
176-
) continue;
159+
// ignore if both sides are white by each axis
160+
if (col > 0 && ptr[-1] == 1 && col < colLim && ptr[1] == 1) continue;
161+
if (row > 0 && ptr[-kernel.cols] && row < rowLim && ptr[kernel.cols] == 1) continue;
162+
163+
// ignore one of neighbor block is white; will be alive in deeper table
164+
if (col + (1 << colDepth) <= colLim && ptr[1 << colDepth] == 1) continue;
165+
if (col - (1 << colDepth) >= 0 && ptr[-(1 << colDepth)] == 1) continue;
166+
if (row + (1 << rowDepth) <= rowLim && ptr[(1 << rowDepth) * kernel.cols] == 1) continue;
167+
if (row - (1 << rowDepth) >= 0 && ptr[-(1 << rowDepth) * kernel.cols] == 1) continue;
177168

178169
p2Rects.emplace_back(col, row, colDepth, rowDepth);
179170
}
@@ -188,19 +179,45 @@ TEST(develop, POW2RECT_COVERING)
188179
{
189180
int kSize = 11;
190181
Size kernelSize(kSize, kSize);
191-
Mat kernel = getStructuringElement(MorphShapes::MORPH_ELLIPSE, kernelSize);
182+
//Mat kernel = getStructuringElement(MorphShapes::MORPH_ELLIPSE, kernelSize);
183+
uchar ary[] {
184+
0, 1, 0, 1, 0, 1, 0, 1,
185+
1, 1, 0, 1, 1, 1, 1, 1,
186+
1, 0, 0, 1, 0, 1, 0, 1,
187+
0, 0, 1, 1, 1, 1, 1, 1,
188+
0, 1, 0, 1, 0, 1, 1, 1,
189+
1, 1, 1, 1, 1, 1, 1, 1,
190+
0, 1, 0, 1, 0, 1, 0, 1,
191+
1, 1, 1, 1, 1, 1, 1, 1,
192+
};
193+
Mat kernel(8, 8, CV_8UC1, ary);
192194

193195
std::tuple<std::vector<std::vector<Mat>>, std::vector<Rect>> ret = genPow2RectsToCoverKernel_dev(kernel);
194-
std::vector<std::vector<Mat>> st = std::get<0>(ret);
195-
std::vector<Rect> rects = std::get<1>(ret);
196196

197-
// visualize
197+
// visualize sparse table
198+
std::vector<std::vector<Mat>> st = std::get<0>(ret);
199+
int cellSize = 10;
198200
Mat concatSt;
199201
std::vector<Mat> hconMat(st.size(), Mat());
202+
for (int row = 0; row < st.size(); row++) for (int col = 0; col < st[row].size(); col++)
203+
{
204+
Mat t = st[row][col];
205+
Mat x = Mat::zeros(t.rows * cellSize, t.cols * cellSize, CV_8UC3);
206+
uchar* pCell = t.ptr();
207+
for (int r = 0; r < t.rows; r++) for (int c = 0; c < t.cols; c++, pCell++)
208+
{
209+
if (*pCell == 1) cv::rectangle(x, Rect(c * cellSize, r * cellSize, cellSize, cellSize), Scalar(255, 255, 255), -1);
210+
}
211+
for (int r = 1; r < t.rows; r++) cv::line(x, Point(0, r * cellSize), Point(x.cols, r * cellSize), Scalar(50, 50, 50), 1);
212+
for (int c = 1; c < t.cols; c++) cv::line(x, Point(c * cellSize, 0), Point(c * cellSize, x.rows), Scalar(50, 50, 50), 1);
213+
cv::copyMakeBorder(x, x, 0, 2, 0, 2, BorderTypes::BORDER_CONSTANT, Scalar(200, 200, 200));
214+
st[row][col] = x;
215+
}
200216
for (int row = 0; row < st.size(); row++) hconcat(st[row], hconMat[row]); vconcat(hconMat, concatSt);
201-
resize(concatSt *255, concatSt, Size(), 10, 10, InterpolationFlags::INTER_NEAREST);
202217
imshow("result", concatSt);
203218

219+
// visualize rectangles on kernel
220+
std::vector<Rect> rects = std::get<1>(ret);
204221
int rate = 40;
205222
resize(kernel * 255, kernel, Size(), rate, rate, InterpolationFlags::INTER_NEAREST);
206223
cvtColor(kernel, kernel, cv::COLOR_GRAY2BGR);

0 commit comments

Comments
 (0)