@@ -68,7 +68,8 @@ TEST(ximgproc_SparseTableMorph, compare_with_original_erode)
68
68
CV_Assert (max == 0 );
69
69
}
70
70
71
-
71
+ // this method may be applied for the covering polygon problem with rectangle.
72
+ // https://www.sciencedirect.com/science/article/pii/S0019995884800121
72
73
std::tuple<std::vector<std::vector<Mat>>, std::vector<Rect>> genPow2RectsToCoverKernel_dev (InputArray _kernel)
73
74
{
74
75
CV_Assert (_kernel.type () == CV_8UC1);
@@ -152,28 +153,18 @@ std::tuple<std::vector<std::vector<Mat>>, std::vector<Rect>> genPow2RectsToCover
152
153
{
153
154
for (int col = 0 ; col < colLim; col++, ptr++)
154
155
{
156
+ // ignore black cell
155
157
if (ptr[0 ] == 0 ) continue ;
156
158
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 ;
177
168
178
169
p2Rects.emplace_back (col, row, colDepth, rowDepth);
179
170
}
@@ -188,19 +179,45 @@ TEST(develop, POW2RECT_COVERING)
188
179
{
189
180
int kSize = 11 ;
190
181
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);
192
194
193
195
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);
196
196
197
- // visualize
197
+ // visualize sparse table
198
+ std::vector<std::vector<Mat>> st = std::get<0 >(ret);
199
+ int cellSize = 10 ;
198
200
Mat concatSt;
199
201
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
+ }
200
216
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);
202
217
imshow (" result" , concatSt);
203
218
219
+ // visualize rectangles on kernel
220
+ std::vector<Rect> rects = std::get<1 >(ret);
204
221
int rate = 40 ;
205
222
resize (kernel * 255 , kernel, Size (), rate, rate, InterpolationFlags::INTER_NEAREST);
206
223
cvtColor (kernel, kernel, cv::COLOR_GRAY2BGR);
0 commit comments