@@ -11,9 +11,9 @@ namespace st_morphology {
11
11
TEST (ximgproc_SparseTableMorph, compare_with_original_erode)
12
12
{
13
13
// preparation
14
- int kRadius = 100 ;
15
- Size sz (200 , 150 );
16
- // Size sz = szVGA;
14
+ int kRadius = 10 ;
15
+ // Size sz(200, 150);
16
+ Size sz = szVGA;
17
17
int type = CV_8UC3;
18
18
19
19
int kSize = kRadius * 2 + 1 ;
@@ -68,5 +68,165 @@ TEST(ximgproc_SparseTableMorph, compare_with_original_erode)
68
68
CV_Assert (max == 0 );
69
69
}
70
70
71
+
72
+ std::tuple<std::vector<std::vector<Mat>>, std::vector<Rect>> genPow2RectsToCoverKernel_dev (InputArray _kernel)
73
+ {
74
+ CV_Assert (_kernel.type () == CV_8UC1);
75
+
76
+ Mat kernel = _kernel.getMat ();
77
+
78
+ // generate log2 table
79
+ int len = max (kernel.rows , kernel.cols ) + 1 ;
80
+ std::vector<int > log2 (len);
81
+ for (int i = 2 ; i < len; i++) log2[i] = log2[i >> 1 ] + 1 ;
82
+
83
+ // generate sparse table for the kernel
84
+ std::vector<std::vector<Mat>> st (log2[kernel.rows ] + 1 , std::vector<Mat>(log2[kernel.cols ] + 1 ));
85
+ st[0 ][0 ] = kernel;
86
+ for (int colDepth = 1 ; colDepth <= log2[kernel.cols ]; colDepth++)
87
+ {
88
+ int rowStep = 0 ;
89
+ int rowSkip = 0 ;
90
+ int rowLim = kernel.rows - rowSkip;
91
+
92
+ int colStep = 1 << (colDepth - 1 );
93
+ int colSkip = (1 << colDepth) - 1 ;
94
+ int colLim = kernel.cols - colSkip;
95
+
96
+ st[0 ][colDepth] = Mat::zeros (kernel.rows , kernel.cols , kernel.type ());
97
+ uchar* ptr1 = st[0 ][colDepth - 1 ].ptr ();
98
+ uchar* ptr2 = st[0 ][colDepth - 1 ].ptr (rowStep, colStep);
99
+ uchar* dst = st[0 ][colDepth].ptr ();
100
+ for (int row = 0 ; row < rowLim; row++)
101
+ {
102
+ for (int col = 0 ; col < colLim; col++)
103
+ {
104
+ *dst++ = *ptr1++ & *ptr2++;
105
+ }
106
+ ptr1 += colSkip;
107
+ ptr2 += colSkip;
108
+ dst += colSkip;
109
+ }
110
+ }
111
+ for (int rowDepth = 1 ; rowDepth <= log2[kernel.rows ]; rowDepth++)
112
+ {
113
+ int rowStep = 1 << (rowDepth - 1 );
114
+ int rowSkip = (1 << rowDepth) - 1 ;
115
+ int rowLim = kernel.rows - rowSkip;
116
+ for (int colDepth = 0 ; colDepth <= log2[kernel.cols ]; colDepth++)
117
+ {
118
+ int colStep = 0 ;
119
+ int colSkip = (1 << colDepth) - 1 ;
120
+ int colLim = kernel.cols - colSkip;
121
+
122
+ st[rowDepth][colDepth] = Mat::zeros (kernel.rows , kernel.cols , kernel.type ());
123
+ uchar* ptr1 = st[rowDepth - 1 ][colDepth].ptr ();
124
+ uchar* ptr2 = st[rowDepth - 1 ][colDepth].ptr (rowStep, colStep);
125
+ uchar* dst = st[rowDepth][colDepth].ptr ();
126
+ for (int row = 0 ; row < rowLim; row++)
127
+ {
128
+ for (int col = 0 ; col < colLim; col++)
129
+ {
130
+ *dst++ = *ptr1++ & *ptr2++;
131
+ }
132
+ ptr1 += colSkip;
133
+ ptr2 += colSkip;
134
+ dst += colSkip;
135
+ }
136
+ }
137
+ }
138
+
139
+ // find pow2 rectangles
140
+ std::vector<Rect> p2Rects;
141
+ for (int rowDepth = 0 ; rowDepth <= log2[kernel.rows ]; rowDepth++)
142
+ {
143
+ int rowSkip = (1 << rowDepth) - 1 ;
144
+ int rowLim = kernel.rows - rowSkip;
145
+ for (int colDepth = 0 ; colDepth <= log2[kernel.cols ]; colDepth++)
146
+ {
147
+ int colSkip = (1 << colDepth) - 1 ;
148
+ int colLim = kernel.cols - colSkip;
149
+
150
+ uchar* ptr = st[rowDepth][colDepth].ptr ();
151
+ for (int row = 0 ; row < rowLim; row++)
152
+ {
153
+ for (int col = 0 ; col < colLim; col++, ptr++)
154
+ {
155
+ if (ptr[0 ] == 0 ) continue ;
156
+
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 ;
177
+
178
+ p2Rects.emplace_back (col, row, colDepth, rowDepth);
179
+ }
180
+ ptr += colSkip;
181
+ }
182
+ }
183
+ }
184
+
185
+ return { st, p2Rects };
186
+ }
187
+ TEST (develop, POW2RECT_COVERING)
188
+ {
189
+ int kSize = 11 ;
190
+ Size kernelSize (kSize , kSize );
191
+ Mat kernel = getStructuringElement (MorphShapes::MORPH_ELLIPSE, kernelSize);
192
+
193
+ 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
+
197
+ // visualize
198
+ Mat concatSt;
199
+ std::vector<Mat> hconMat (st.size (), Mat ());
200
+ 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
+ imshow (" result" , concatSt);
203
+
204
+ int rate = 40 ;
205
+ resize (kernel * 255 , kernel, Size (), rate, rate, InterpolationFlags::INTER_NEAREST);
206
+ cvtColor (kernel, kernel, cv::COLOR_GRAY2BGR);
207
+ Scalar color[20 ]{
208
+ Scalar (83 , 89 , 73 ), Scalar (49 , 238 , 73 ), Scalar (220 , 192 , 189 ), Scalar (174 , 207 , 34 ), Scalar (144 , 169 , 187 ),
209
+ Scalar (137 , 94 , 76 ), Scalar (42 , 11 , 215 ), Scalar (113 , 11 , 204 ), Scalar (71 , 124 , 8 ), Scalar (192 , 38 , 8 ),
210
+ Scalar (82 , 201 , 8 ), Scalar (70 , 7 , 112 ), Scalar (166 , 219 , 201 ), Scalar (154 , 173 , 0 ), Scalar (132 , 127 , 139 ),
211
+ Scalar (154 , 1 , 68 ), Scalar (231 , 131 , 56 ), Scalar (206 , 238 , 136 ), Scalar (188 , 78 , 173 ), Scalar (27 , 178 , 206 )
212
+ };
213
+ for (int i = 0 ; i < rects.size (); i++)
214
+ {
215
+ Rect rect = rects[i];
216
+ Point lt ((rect.x ) * rate + i, (rect.y ) * rate + i);
217
+ Point lb ((rect.x ) * rate + i, (rect.y + (1 << rect.height )) * rate - 15 + i);
218
+ Point rb ((rect.x + (1 << rect.width )) * rate - 15 + i, (rect.y + (1 << rect.height )) * rate - 15 + i);
219
+ Point rt ((rect.x + (1 << rect.width )) * rate - 15 + i, (rect.y ) * rate + i);
220
+ cv::line (kernel, lt, lb, color[i], 2 );
221
+ cv::line (kernel, lb, rb, color[i], 2 );
222
+ cv::line (kernel, rb, rt, color[i], 2 );
223
+ cv::line (kernel, rt, lt, color[i], 2 );
224
+ }
225
+ imshow (" kernel" , kernel);
226
+
227
+ waitKey ();
228
+ destroyAllWindows ();
229
+ }
230
+
71
231
} //
72
232
} // opencv_test
0 commit comments