29TEST_CASE(
"Masking wedges in an image",
"[improc::imageMasks::maskWedge]" )
31 GIVEN(
"a single wedge" )
33 WHEN(
"geometric center, 0-90 degrees" )
36 im.resize( 1024, 1024 );
39 double xcen = 0.5 * ( im.rows() - 1 );
40 double ycen = 0.5 * ( im.cols() - 1 );
44 REQUIRE( im.sum() == 512 * 512 );
46 WHEN(
"geometric center, 90-180 degrees" )
49 im.resize( 1024, 1024 );
52 double xcen = 0.5 * ( im.rows() - 1 );
53 double ycen = 0.5 * ( im.cols() - 1 );
57 REQUIRE( im.sum() == 512 * 512 );
59 WHEN(
"geometric center, 180-270 degrees" )
62 im.resize( 1024, 1024 );
65 double xcen = 0.5 * ( im.rows() - 1 );
66 double ycen = 0.5 * ( im.cols() - 1 );
70 REQUIRE( im.sum() == 512 * 512 );
72 WHEN(
"geometric center, 270-360 degrees" )
75 im.resize( 1024, 1024 );
78 double xcen = 0.5 * ( im.rows() - 1 );
79 double ycen = 0.5 * ( im.cols() - 1 );
83 REQUIRE( im.sum() == 512 * 512 );
85 WHEN(
"geometric center, 45-135 degrees" )
88 im.resize( 1024, 1024 );
91 double xcen = 0.5 * ( im.rows() - 1 );
92 double ycen = 0.5 * ( im.cols() - 1 );
96 REQUIRE( im.sum() == 512 * 512 );
98 WHEN(
"geometric center, 135-225 degrees" )
101 im.resize( 1024, 1024 );
104 double xcen = 0.5 * ( im.rows() - 1 );
105 double ycen = 0.5 * ( im.cols() - 1 );
109 REQUIRE( im.sum() == 512 * 512 );
111 WHEN(
"geometric center, 225-315 degrees" )
114 im.resize( 1024, 1024 );
117 double xcen = 0.5 * ( im.rows() - 1 );
118 double ycen = 0.5 * ( im.cols() - 1 );
122 REQUIRE( im.sum() == 512 * 512 );
124 WHEN(
"geometric center, 315-45 degrees" )
127 im.resize( 1024, 1024 );
130 double xcen = 0.5 * ( im.rows() - 1 );
131 double ycen = 0.5 * ( im.cols() - 1 );
135 REQUIRE( im.sum() == 512 * 512 );
137 WHEN(
"geometric center, 3 wedges of 120 degrees" )
140 im60.resize( 1024, 1024 );
143 double xcen = 0.5 * ( im60.rows() - 1 );
144 double ycen = 0.5 * ( im60.cols() - 1 );
149 im180.resize( 1024, 1024 );
152 xcen = 0.5 * ( im180.rows() - 1 );
153 ycen = 0.5 * ( im180.cols() - 1 );
158 im300.resize( 1024, 1024 );
161 xcen = 0.5 * ( im300.rows() - 1 );
162 ycen = 0.5 * ( im300.cols() - 1 );
166 REQUIRE( im60.sum() + im180.sum() + im300.sum() == 1024 * 1024 );
198TEST_CASE(
"radAngImage produces HCI radius and angle coordinates",
"[improc::imageMasks::radAngImage]" )
205 REQUIRE( angle.rows() == 3 );
206 REQUIRE( angle.cols() == 5 );
207 REQUIRE( radius( 1, 2 ) == Approx( 0.0 ) );
208 REQUIRE( angle( 1, 2 ) == Approx( 0.0 ) );
209 REQUIRE( radius( 2, 2 ) == Approx( 1.0 ) );
210 REQUIRE( angle( 2, 2 ) == Approx( 0.0 ) );
211 REQUIRE( radius( 1, 3 ) == Approx( 1.0 ) );
212 REQUIRE( angle( 1, 3 ) == Approx( 90.0 ) );
213 REQUIRE( radius( 0, 2 ) == Approx( 1.0 ) );
214 REQUIRE( angle( 0, 2 ) == Approx( 180.0 ) );
215 REQUIRE( radius( 1, 1 ) == Approx( 1.0 ) );
216 REQUIRE( angle( 1, 1 ) == Approx( 270.0 ) );
219 REQUIRE( radius( 2, 2 ) == Approx( 2.0 ) );
226TEST_CASE(
"annulusIndices selects bounded and masked HCI regions",
"[improc::imageMasks::annulusIndices]" )
228 using angleT = mx::math::degreesT<double>;
234 const std::vector<size_t> full =
236 REQUIRE( full == std::vector<size_t>{ 6, 7, 8, 11, 13, 16, 17, 18 } );
241 const std::vector<size_t> masked =
243 REQUIRE( masked == std::vector<size_t>{ 7, 8, 11, 13, 16, 17, 18 } );
245 const std::vector<size_t> clipped =
247 REQUIRE( clipped.size() == 25 );
249 const std::vector<size_t> half =
251 REQUIRE_FALSE( half.empty() );
252 REQUIRE( half.size() < clipped.size() );
254 const std::vector<size_t> wrapped =
256 REQUIRE_FALSE( wrapped.empty() );
257 REQUIRE( wrapped.size() < clipped.size() );
264TEST_CASE(
"Annulus coordinate wrappers apply radial pixel buffers",
"[improc::imageMasks][annulusCoords][pixbuf]" )
266 using angleT = mx::math::degreesT<double>;
274 const auto bufferedCoordinates =
277 REQUIRE( coordinates.size() == 12 );
278 REQUIRE( bufferedCoordinates.size() == 24 );
280 const auto hasCoordinate = [](
const std::vector<std::vector<int>> ®ion,
int row,
int column )
281 {
return std::find( region.begin(), region.end(), std::vector<int>{ row, column } ) != region.end(); };
283 REQUIRE_FALSE( hasCoordinate( coordinates, 2, 3 ) );
284 REQUIRE( hasCoordinate( bufferedCoordinates, 2, 3 ) );
285 REQUIRE_FALSE( hasCoordinate( coordinates, 1, 1 ) );
286 REQUIRE( hasCoordinate( bufferedCoordinates, 1, 1 ) );
287 REQUIRE_FALSE( hasCoordinate( bufferedCoordinates, 0, 3 ) );
292 const auto maskedBufferedCoordinates =
294 REQUIRE_FALSE( hasCoordinate( maskedBufferedCoordinates, 2, 3 ) );
297 const auto bufferedIndices =
300 REQUIRE( indices.size() == coordinates.size() );
301 REQUIRE( bufferedIndices.size() == bufferedCoordinates.size() );
302 REQUIRE( std::find( indices.begin(), indices.end(), 23 ) == indices.end() );
303 REQUIRE( std::find( bufferedIndices.begin(), bufferedIndices.end(), 23 ) != bufferedIndices.end() );
304 REQUIRE( std::find( indices.begin(), indices.end(), 8 ) == indices.end() );
305 REQUIRE( std::find( bufferedIndices.begin(), bufferedIndices.end(), 8 ) != bufferedIndices.end() );
312 angleT>( fractionalRadius, fractionalAngle, 4.5, 4.5, 3.0, 3.5, 0.0, 360.0, noMask, 0.5 );
313 REQUIRE( hasCoordinate( fractionalCoordinates, 1, 4 ) );
314 REQUIRE( hasCoordinate( fractionalCoordinates, 8, 4 ) );
317 angleT>( fractionalRadius, fractionalAngle, 4.5, 4.5, 3.0, 3.5, 0.0, 360.0, noMask, 0.5 );
318 REQUIRE( std::find( fractionalIndices.begin(), fractionalIndices.end(), 41 ) != fractionalIndices.end() );
319 REQUIRE( std::find( fractionalIndices.begin(), fractionalIndices.end(), 48 ) != fractionalIndices.end() );
321 const auto emptyBufferedCoordinates =
323 REQUIRE( emptyBufferedCoordinates.empty() );
330TEST_CASE(
"Image regions are cut and inserted by linear index",
"[improc::imageMasks][imageRegion]" )
333 for( Eigen::Index index = 0; index < image.size(); ++index )
335 image( index ) =
static_cast<double>( 10 + index );
337 const std::vector<size_t> indices{ 0, 5, 11 };
341 REQUIRE( cut.rows() == 3 );
342 REQUIRE( cut.cols() == 1 );
343 REQUIRE( cut( 0 ) == Approx( 10 ) );
344 REQUIRE( cut( 1 ) == Approx( 15 ) );
345 REQUIRE( cut( 2 ) == Approx( 21 ) );
348 preallocated.setConstant( -1 );
350 REQUIRE( preallocated.isApprox( cut ) );
353 inserted.setConstant( -1 );
354 auto insertedView = inserted.block( 0, 0, inserted.rows(), 1 );
356 REQUIRE( inserted( 0 ) == Approx( 10 ) );
357 REQUIRE( inserted( 5 ) == Approx( 15 ) );
358 REQUIRE( inserted( 11 ) == Approx( 21 ) );
359 REQUIRE( inserted( 1 ) == Approx( -1 ) );
362 REQUIRE( cut.rows() == 0 );
363 REQUIRE( cut.cols() == 1 );
365 REQUIRE( inserted( 0 ) == Approx( 10 ) );
std::vector< std::vector< int > > annulusCoords(const eigenT1 &rIm, const eigenT2 &qIm, typename angleT::realT xcen, typename angleT::realT ycen, typename angleT::realT min_r, typename angleT::realT max_r, typename angleT::realT min_q, typename angleT::realT max_q, eigenT3 *mask=0, typename angleT::realT pixbuf=0)
Get the array coordinates of an annular region in an image.
std::vector< size_t > annulusIndices(const eigenT1 &rIm, const eigenT2 &qIm, typename angleT::realT xcen, typename angleT::realT ycen, typename angleT::realT min_r, typename angleT::realT max_r, typename angleT::realT min_q, typename angleT::realT max_q, eigenT3 *mask=0, typename angleT::realT pixbuf=0)
Get the vector indices of an annular region in an image.