1 // Copyright (C) 2011 Davis E. King (davis@dlib.net) 2 // License: Boost Software License See LICENSE.txt for the full license. 3 4 5 #include <sstream> 6 #include <string> 7 #include <cstdlib> 8 #include <ctime> 9 #include "dlib/image_processing.h" 10 11 #include "dlib/test/tester.h" 12 13 #include "dlib/image_transforms.h" 14 #include "dlib/pixel.h" 15 #include "dlib/array2d.h" 16 #include "dlib/array.h" 17 18 // ---------------------------------------------------------------------------------------- 19 20 namespace 21 { 22 23 using namespace test; 24 using namespace dlib; 25 using namespace std; 26 27 using dlib::array; 28 29 // Declare the logger we will use in this test. The name of the tester 30 // should start with "test." 31 logger dlog("test.scan_image"); 32 33 // ---------------------------------------------------------------------------------------- 34 35 template <typename image_type1, typename image_type2> sum_filter_i(const image_type1 & img,image_type2 & out,const rectangle & rect)36 void sum_filter_i ( 37 const image_type1& img, 38 image_type2& out, 39 const rectangle& rect 40 ) 41 { 42 typedef typename image_type1::type pixel_type; 43 typedef typename promote<pixel_type>::type ptype; 44 integral_image_generic<ptype> iimg; 45 iimg.load(img); 46 for (long r = 0; r < img.nr(); ++r) 47 { 48 for (long c = 0; c < img.nc(); ++c) 49 { 50 const rectangle temp = translate_rect(rect, point(c,r)).intersect(get_rect(iimg)); 51 if (temp.is_empty() == false) 52 out[r][c] += iimg.get_sum_of_area(temp); 53 } 54 } 55 56 } 57 58 // ---------------------------------------------------------------------------------------- 59 60 template < 61 typename image_array_type 62 > scan_image_i(std::vector<std::pair<double,point>> & dets,const image_array_type & images,const std::vector<std::pair<unsigned int,rectangle>> & rects,const double thresh,const unsigned long max_dets)63 void scan_image_i ( 64 std::vector<std::pair<double, point> >& dets, 65 const image_array_type& images, 66 const std::vector<std::pair<unsigned int, rectangle> >& rects, 67 const double thresh, 68 const unsigned long max_dets 69 ) 70 { 71 typedef typename image_array_type::type::type pixel_type; 72 typedef typename promote<pixel_type>::type ptype; 73 array<integral_image_generic<ptype> > iimg; 74 iimg.set_max_size(images.size()); 75 iimg.set_size(images.size()); 76 77 for (unsigned long i = 0; i < iimg.size(); ++i) 78 iimg[i].load(images[i]); 79 80 81 dets.clear(); 82 83 84 for (long r = 0; r < images[0].nr(); ++r) 85 { 86 for (long c = 0; c < images[0].nc(); ++c) 87 { 88 ptype temp = 0; 89 for (unsigned long i = 0; i < rects.size(); ++i) 90 { 91 rectangle rtemp = translate_rect(rects[i].second,point(c,r)).intersect(get_rect(images[0])); 92 if (rtemp.is_empty() == false) 93 temp += iimg[rects[i].first].get_sum_of_area(rtemp); 94 } 95 if (temp > thresh) 96 { 97 dets.push_back(std::make_pair(temp, point(c,r))); 98 99 if (dets.size() >= max_dets) 100 return; 101 102 } 103 } 104 } 105 } 106 107 // ---------------------------------------------------------------------------------------- 108 109 template < 110 typename image_array_type 111 > scan_image_old(std::vector<std::pair<double,point>> & dets,const image_array_type & images,const std::vector<std::pair<unsigned int,rectangle>> & rects,const double thresh,const unsigned long max_dets)112 void scan_image_old ( 113 std::vector<std::pair<double, point> >& dets, 114 const image_array_type& images, 115 const std::vector<std::pair<unsigned int, rectangle> >& rects, 116 const double thresh, 117 const unsigned long max_dets 118 ) 119 { 120 dets.clear(); 121 if (max_dets == 0) 122 return; 123 124 typedef typename image_array_type::type::type pixel_type; 125 typedef typename promote<pixel_type>::type ptype; 126 127 std::vector<std::vector<ptype> > column_sums(rects.size()); 128 for (unsigned long i = 0; i < column_sums.size(); ++i) 129 { 130 const typename image_array_type::type& img = images[rects[i].first]; 131 column_sums[i].resize(img.nc() + rects[i].second.width(),0); 132 133 const long top = -1 + rects[i].second.top(); 134 const long bottom = -1 + rects[i].second.bottom(); 135 long left = rects[i].second.left()-1; 136 137 // initialize column_sums[i] at row -1 138 for (unsigned long j = 0; j < column_sums[i].size(); ++j) 139 { 140 rectangle strip(left,top,left,bottom); 141 strip = strip.intersect(get_rect(img)); 142 if (!strip.is_empty()) 143 { 144 column_sums[i][j] = sum(matrix_cast<ptype>(subm(mat(img),strip))); 145 } 146 147 ++left; 148 } 149 } 150 151 152 const rectangle area = get_rect(images[0]); 153 154 for (long r = 0; r < images[0].nr(); ++r) 155 { 156 // set to sum at point(-1,r). i.e. should be equal to sum_of_rects_in_images(images, rects, point(-1,r)) 157 // We compute it's value in the next loop. 158 ptype cur_sum = 0; 159 160 // Update the first part of column_sums since we only work on the c+width part of column_sums 161 // in the main loop. 162 for (unsigned long i = 0; i < rects.size(); ++i) 163 { 164 const typename image_array_type::type& img = images[rects[i].first]; 165 const long top = r + rects[i].second.top() - 1; 166 const long bottom = r + rects[i].second.bottom(); 167 const long width = rects[i].second.width(); 168 for (long k = 0; k < width; ++k) 169 { 170 const long right = k-width + rects[i].second.right(); 171 172 const ptype br_corner = area.contains(right,bottom) ? img[bottom][right] : 0; 173 const ptype tr_corner = area.contains(right,top) ? img[top][right] : 0; 174 // update the sum in this column now that we are on the next row 175 column_sums[i][k] = column_sums[i][k] + br_corner - tr_corner; 176 cur_sum += column_sums[i][k]; 177 } 178 } 179 180 for (long c = 0; c < images[0].nc(); ++c) 181 { 182 for (unsigned long i = 0; i < rects.size(); ++i) 183 { 184 const typename image_array_type::type& img = images[rects[i].first]; 185 const long top = r + rects[i].second.top() - 1; 186 const long bottom = r + rects[i].second.bottom(); 187 const long right = c + rects[i].second.right(); 188 const long width = rects[i].second.width(); 189 190 const ptype br_corner = area.contains(right,bottom) ? img[bottom][right] : 0; 191 const ptype tr_corner = area.contains(right,top) ? img[top][right] : 0; 192 // update the sum in this column now that we are on the next row 193 column_sums[i][c+width] = column_sums[i][c+width] + br_corner - tr_corner; 194 195 196 // add in the new right side of the rect and subtract the old right side. 197 cur_sum = cur_sum + column_sums[i][c+width] - column_sums[i][c]; 198 199 } 200 201 if (cur_sum > thresh) 202 { 203 dets.push_back(std::make_pair(cur_sum, point(c,r))); 204 205 if (dets.size() >= max_dets) 206 return; 207 } 208 } 209 } 210 } 211 212 // ---------------------------------------------------------------------------------------- 213 run_test1()214 void run_test1() 215 { 216 dlog << LINFO << "run_test1()"; 217 218 print_spinner(); 219 array2d<unsigned char> img, temp_img; 220 img.set_size(600,600); 221 assign_all_pixels(img,0); 222 rectangle rect = centered_rect(10,10,5,5); 223 dlog << LTRACE << "expected: 10,10"; 224 fill_rect(img, rect, 255); 225 226 227 array<array2d<unsigned char> > images; 228 std::vector<std::pair<unsigned int, rectangle> > rects; 229 for (int i = 0; i < 10; ++i) 230 { 231 assign_image(temp_img, img); 232 images.push_back(temp_img); 233 rects.push_back(make_pair(i,centered_rect(0,0,5,5))); 234 } 235 236 std::vector<std::pair<double, point> > dets, dets2, dets3; 237 238 239 dlog << LTRACE << "best score: "<< sum_of_rects_in_images(images,rects,point(10,10)); 240 scan_image(dets,images,rects,30000, 100); 241 scan_image_i(dets2,images,rects,30000, 100); 242 scan_image_old(dets3,images,rects,30000, 100); 243 244 245 246 dlog << LTRACE << "dets.size(): "<< dets.size(); 247 dlog << LTRACE << "dets2.size(): "<< dets2.size(); 248 dlog << LTRACE << "dets3.size(): "<< dets3.size(); 249 250 DLIB_TEST(dets.size() == dets2.size()); 251 DLIB_TEST(dets.size() == dets3.size()); 252 253 for (unsigned long i = 0; i < dets.size(); ++i) 254 { 255 //dlog << LTRACE << "dets["<<i<<"]: " << dets[i].second << " -> " << dets[i].first; 256 //dlog << LTRACE << "dets2["<<i<<"]: " << dets2[i].second << " -> " << dets2[i].first; 257 //dlog << LTRACE << "dets3["<<i<<"]: " << dets3[i].second << " -> " << dets3[i].first; 258 259 DLIB_TEST(sum_of_rects_in_images(images, rects, dets[i].second) == dets[i].first); 260 DLIB_TEST(sum_of_rects_in_images(images, rects, dets2[i].second) == dets2[i].first); 261 DLIB_TEST(sum_of_rects_in_images(images, rects, dets3[i].second) == dets3[i].first); 262 } 263 264 265 } 266 267 // ---------------------------------------------------------------------------------------- 268 run_test2()269 void run_test2() 270 { 271 print_spinner(); 272 dlog << LINFO << "run_test2()"; 273 array2d<unsigned char> img, temp_img; 274 img.set_size(600,600); 275 assign_all_pixels(img,0); 276 rectangle rect = centered_rect(10,11,5,6); 277 dlog << LTRACE << "expected: 10,11"; 278 fill_rect(img, rect, 255); 279 280 281 array<array2d<unsigned char> > images; 282 std::vector<std::pair<unsigned int, rectangle> > rects; 283 for (int i = 0; i < 10; ++i) 284 { 285 assign_image(temp_img, img); 286 images.push_back(temp_img); 287 rects.push_back(make_pair(i,centered_rect(0,0,5,5))); 288 rects.push_back(make_pair(i,centered_rect(3,2,5,6))); 289 } 290 291 std::vector<std::pair<double, point> > dets, dets2, dets3; 292 293 294 scan_image(dets,images,rects,30000, 100); 295 scan_image_i(dets2,images,rects,30000, 100); 296 scan_image_old(dets3,images,rects,30000, 100); 297 298 299 300 dlog << LTRACE << "dets.size(): "<< dets.size(); 301 dlog << LTRACE << "dets2.size(): "<< dets2.size(); 302 dlog << LTRACE << "dets3.size(): "<< dets3.size(); 303 304 DLIB_TEST(dets.size() == dets2.size()); 305 DLIB_TEST(dets.size() == dets3.size()); 306 307 for (unsigned long i = 0; i < dets.size(); ++i) 308 { 309 //dlog << LTRACE << "dets["<<i<<"]: " << dets[i].second << " -> " << dets[i].first; 310 //dlog << LTRACE << "dets2["<<i<<"]: " << dets2[i].second << " -> " << dets2[i].first; 311 //dlog << LTRACE << "dets3["<<i<<"]: " << dets3[i].second << " -> " << dets3[i].first; 312 313 DLIB_TEST(sum_of_rects_in_images(images, rects, dets[i].second) == dets[i].first); 314 DLIB_TEST(sum_of_rects_in_images(images, rects, dets2[i].second) == dets2[i].first); 315 DLIB_TEST(sum_of_rects_in_images(images, rects, dets3[i].second) == dets3[i].first); 316 } 317 318 319 } 320 321 // ---------------------------------------------------------------------------------------- 322 323 template <typename pixel_type> run_test3(const double thresh)324 void run_test3(const double thresh) 325 { 326 dlog << LINFO << "running run_test3("<<thresh<<")"; 327 dlib::rand rnd; 328 329 rnd.set_seed("235"); 330 331 array<array2d<pixel_type> > images; 332 images.resize(1); 333 images[0].set_size(200,180); 334 335 for (int iter = 0; iter < 50; ++iter) 336 { 337 print_spinner(); 338 assign_all_pixels(images[0], thresh - 0.0001); 339 340 for (int i = 0; i < 20; ++i) 341 { 342 point p1(rnd.get_random_32bit_number()%images[0].nc(), 343 rnd.get_random_32bit_number()%images[0].nr()); 344 point p2(rnd.get_random_32bit_number()%images[0].nc(), 345 rnd.get_random_32bit_number()%images[0].nr()); 346 347 rectangle rect(p1,p2); 348 fill_rect(images[0], rect, static_cast<pixel_type>(rnd.get_random_double()*10 - 5)); 349 } 350 351 std::vector<std::pair<unsigned int, rectangle> > rects; 352 rects.push_back(make_pair(0,centered_rect(0,0,1+rnd.get_random_32bit_number()%40,1+rnd.get_random_32bit_number()%40))); 353 rects.push_back(make_pair(0,centered_rect(0,0,1+rnd.get_random_32bit_number()%40,1+rnd.get_random_32bit_number()%40))); 354 355 356 357 358 std::vector<std::pair<double, point> > dets, dets2, dets3; 359 scan_image(dets,images,rects,thresh, 100); 360 scan_image_i(dets2,images,rects,thresh, 100); 361 scan_image_old(dets3,images,rects,thresh, 100); 362 363 dlog << LTRACE << "dets.size(): "<< dets.size(); 364 dlog << LTRACE << "dets2.size(): "<< dets2.size(); 365 dlog << LTRACE << "dets3.size(): "<< dets3.size(); 366 367 DLIB_TEST(dets.size() == dets2.size()); 368 DLIB_TEST(dets.size() == dets3.size()); 369 370 for (unsigned long i = 0; i < dets.size(); ++i) 371 { 372 //dlog << LTRACE << "dets["<<i<<"]: " << dets[i].second << " -> " << dets[i].first; 373 //dlog << LTRACE << "dets2["<<i<<"]: " << dets2[i].second << " -> " << dets2[i].first; 374 //dlog << LTRACE << "dets3["<<i<<"]: " << dets3[i].second << " -> " << dets3[i].first; 375 376 DLIB_TEST_MSG(std::abs(sum_of_rects_in_images(images, rects, dets[i].second) - dets[i].first) < 1e-6, 377 "error: "<< sum_of_rects_in_images(images, rects, dets[i].second) - dets[i].first 378 << " dets["<<i<<"].second: " << dets[i].second 379 ); 380 DLIB_TEST_MSG(std::abs(sum_of_rects_in_images(images, rects, dets2[i].second) - dets2[i].first) < 1e-6, 381 sum_of_rects_in_images(images, rects, dets2[i].second) - dets2[i].first 382 ); 383 DLIB_TEST_MSG(std::abs(sum_of_rects_in_images(images, rects, dets3[i].second) - dets3[i].first) < 1e-6, 384 "error: "<< sum_of_rects_in_images(images, rects, dets3[i].second) - dets3[i].first 385 << " dets3["<<i<<"].first: " << dets3[i].first 386 << " dets3["<<i<<"].second: " << dets3[i].second 387 ); 388 } 389 390 } 391 } 392 393 // ---------------------------------------------------------------------------------------- 394 395 template <typename pixel_type> test_sum_filter()396 void test_sum_filter ( 397 ) 398 { 399 dlib::rand rnd; 400 401 for (int k = 0; k < 20; ++k) 402 { 403 print_spinner(); 404 405 array2d<pixel_type> img(1 + rnd.get_random_32bit_number()%100, 406 1 + rnd.get_random_32bit_number()%100); 407 408 for (long r = 0; r < img.nr(); ++r) 409 { 410 for (long c = 0; c < img.nc(); ++c) 411 { 412 img[r][c] = static_cast<pixel_type>(100*(rnd.get_random_double()-0.5)); 413 } 414 } 415 416 array2d<long> test1(img.nr(), img.nc()); 417 array2d<double> test2(img.nr(), img.nc()); 418 array2d<long> test1_i(img.nr(), img.nc()); 419 array2d<double> test2_i(img.nr(), img.nc()); 420 421 assign_all_pixels(test1, 0); 422 assign_all_pixels(test2, 0); 423 assign_all_pixels(test1_i, 0); 424 assign_all_pixels(test2_i, 0); 425 426 for (int i = 0; i < 10; ++i) 427 { 428 const long width = rnd.get_random_32bit_number()%10 + 1; 429 const long height = rnd.get_random_32bit_number()%10 + 1; 430 const point p(rnd.get_random_32bit_number()%img.nc(), 431 rnd.get_random_32bit_number()%img.nr()); 432 433 const rectangle rect = centered_rect(p, width, height); 434 sum_filter(img, test1, rect); 435 sum_filter(img, test2, rect); 436 sum_filter(img, test1_i, rect); 437 sum_filter(img, test2_i, rect); 438 439 DLIB_TEST(mat(test1) == mat(test1_i)); 440 DLIB_TEST(mat(test2) == mat(test2_i)); 441 } 442 } 443 } 444 445 // ---------------------------------------------------------------------------------------- 446 447 template < 448 typename image_type1, 449 typename image_type2 450 > naive_max_filter(const image_type1 & img,image_type2 & out,const long width,const long height,typename image_type1::type thresh)451 void naive_max_filter ( 452 const image_type1& img, 453 image_type2& out, 454 const long width, 455 const long height, 456 typename image_type1::type thresh 457 ) 458 { 459 const rectangle area = get_rect(img); 460 for (long r = 0; r < img.nr(); ++r) 461 { 462 for (long c = 0; c < img.nc(); ++c) 463 { 464 const rectangle win = centered_rect(point(c,r),width,height).intersect(area); 465 out[r][c] += std::max(dlib::max(subm(mat(img),win)), thresh); 466 } 467 } 468 } 469 470 // ---------------------------------------------------------------------------------------- 471 test_max_filter(long rows,long cols,long width,long height,dlib::rand & rnd)472 void test_max_filter(long rows, long cols, long width, long height, dlib::rand& rnd) 473 { 474 array2d<int> img(rows, cols); 475 rectangle rect = centered_rect(0,0, width, height); 476 477 array2d<int> out(img.nr(),img.nc()); 478 assign_all_pixels(out, 0); 479 array2d<int> out2(img.nr(),img.nc()); 480 assign_all_pixels(out2, 0); 481 482 for (long r = 0; r < img.nr(); ++r) 483 { 484 for (long c = 0; c < img.nc(); ++c) 485 { 486 img[r][c] = rnd.get_random_32bit_number(); 487 } 488 } 489 490 const int thresh = rnd.get_random_32bit_number(); 491 492 naive_max_filter(img, out2, rect.width(), rect.height(), thresh); 493 max_filter(img, out, rect.width(), rect.height(), thresh); 494 495 DLIB_TEST_MSG(mat(out) == mat(out2), 496 "rows: "<< rows 497 << "\ncols: "<< rows 498 << "\nwidth: "<< width 499 << "\nheight: "<< height ); 500 } 501 502 // ---------------------------------------------------------------------------------------- 503 test_max_filter()504 void test_max_filter() 505 { 506 dlib::rand rnd; 507 for (int iter = 0; iter < 300; ++iter) 508 { 509 print_spinner(); 510 test_max_filter(0,0,1,1,rnd); 511 test_max_filter(0,0,3,1,rnd); 512 test_max_filter(0,0,3,3,rnd); 513 test_max_filter(0,0,1,3,rnd); 514 test_max_filter(1,1,1,1,rnd); 515 test_max_filter(2,2,1,1,rnd); 516 test_max_filter(3,3,1,1,rnd); 517 test_max_filter(3,3,3,3,rnd); 518 test_max_filter(3,3,2,2,rnd); 519 test_max_filter(3,3,3,5,rnd); 520 test_max_filter(3,3,6,8,rnd); 521 test_max_filter(20,20,901,901,rnd); 522 test_max_filter(5,5,1,5,rnd); 523 test_max_filter(50,50,9,9,rnd); 524 test_max_filter(50,50,9,9,rnd); 525 test_max_filter(50,50,10,10,rnd); 526 test_max_filter(50,50,11,10,rnd); 527 test_max_filter(50,50,10,11,rnd); 528 test_max_filter(50,50,10,21,rnd); 529 test_max_filter(50,50,20,10,rnd); 530 test_max_filter(50,50,20,10,rnd); 531 test_max_filter(50,50,9,9,rnd); 532 test_max_filter(20,20,1,901,rnd); 533 test_max_filter(20,20,3,901,rnd); 534 test_max_filter(20,20,901,1,rnd); 535 } 536 537 for (int iter = 0; iter < 200; ++iter) 538 { 539 print_spinner(); 540 test_max_filter((int)rnd.get_random_8bit_number()%100+1, 541 (int)rnd.get_random_8bit_number()%100+1, 542 (int)rnd.get_random_8bit_number()%150+1, 543 (int)rnd.get_random_8bit_number()%150+1, 544 rnd); 545 } 546 } 547 548 // ---------------------------------------------------------------------------------------- 549 make_images(dlib::rand & rnd,array<array2d<unsigned char>> & images,long num,long nr,long nc)550 void make_images ( 551 dlib::rand& rnd, 552 array<array2d<unsigned char> >& images, 553 long num, 554 long nr, 555 long nc 556 ) 557 { 558 images.resize(num); 559 for (unsigned long i = 0; i < images.size(); ++i) 560 { 561 images[i].set_size(nr,nc); 562 } 563 564 for (unsigned long i = 0; i < images.size(); ++i) 565 { 566 for (long r = 0; r < nr; ++r) 567 { 568 for (long c = 0; c < nc; ++c) 569 { 570 images[i][r][c] = rnd.get_random_8bit_number(); 571 } 572 } 573 } 574 } 575 576 577 template < 578 typename image_array_type 579 > brute_force_scan_image_movable_parts(std::vector<std::pair<double,point>> & dets,const image_array_type & images,const rectangle & window,const std::vector<std::pair<unsigned int,rectangle>> & fixed_rects,const std::vector<std::pair<unsigned int,rectangle>> & movable_rects,const double thresh,const unsigned long)580 void brute_force_scan_image_movable_parts ( 581 std::vector<std::pair<double, point> >& dets, 582 const image_array_type& images, 583 const rectangle& window, 584 const std::vector<std::pair<unsigned int, rectangle> >& fixed_rects, 585 const std::vector<std::pair<unsigned int, rectangle> >& movable_rects, 586 const double thresh, 587 const unsigned long 588 ) 589 { 590 dets.clear(); 591 if (movable_rects.size() == 0 && fixed_rects.size() == 0) 592 return; 593 594 for (long r = 0; r < images[0].nr(); ++r) 595 { 596 for (long c = 0; c < images[0].nc(); ++c) 597 { 598 const point p(c,r); 599 double score = sum_of_rects_in_images_movable_parts(images, 600 window, 601 fixed_rects, 602 movable_rects, 603 p); 604 605 if (score >= thresh) 606 { 607 dets.push_back(make_pair(score,p)); 608 } 609 } 610 } 611 } 612 test_scan_images_movable_parts()613 void test_scan_images_movable_parts() 614 { 615 array<array2d<unsigned char> > images; 616 dlib::rand rnd; 617 for (int iter = 0; iter < 40; ++iter) 618 { 619 print_spinner(); 620 const int num_images = rnd.get_random_32bit_number()%4+1; 621 622 make_images(rnd,images, num_images, 623 rnd.get_random_32bit_number()%50+1, 624 rnd.get_random_32bit_number()%50+1 625 ); 626 627 std::vector<std::pair<double,point> > dets1, dets2; 628 std::vector<std::pair<unsigned int, rectangle> > fixed_rects, movable_rects; 629 630 double total_area = 0; 631 for (unsigned long i = 0; i < images.size(); ++i) 632 { 633 fixed_rects.push_back(make_pair(i, centered_rect( 634 rnd.get_random_32bit_number()%10-5, 635 rnd.get_random_32bit_number()%10-5, 636 rnd.get_random_32bit_number()%10, 637 rnd.get_random_32bit_number()%10 638 ))); 639 640 total_area += fixed_rects.back().second.area(); 641 642 movable_rects.push_back(make_pair(i, centered_rect( 643 0, 644 0, 645 rnd.get_random_32bit_number()%10+1, 646 rnd.get_random_32bit_number()%10+1 647 ))); 648 total_area += movable_rects.back().second.area(); 649 } 650 651 const rectangle window = centered_rect(0,0, 652 rnd.get_random_32bit_number()%15+1, 653 rnd.get_random_32bit_number()%15+1); 654 dlog << LINFO << "window size: "<< window.width() << ", " << window.height(); 655 const double thresh = total_area*130; 656 const unsigned long max_dets = get_rect(images[0]).area(); 657 658 scan_image_movable_parts(dets1,images,window,fixed_rects,movable_rects,thresh, max_dets); 659 brute_force_scan_image_movable_parts(dets2,images,window,fixed_rects,movable_rects,thresh, max_dets); 660 661 dlog << LINFO << "max_possible dets: " << max_dets; 662 dlog << LINFO << "regular dets: " << dets1.size(); 663 dlog << LINFO << "brute force: " << dets2.size(); 664 DLIB_TEST(dets1.size() == dets2.size()); 665 666 array2d<double> check(images[0].nr(), images[0].nc()); 667 assign_all_pixels(check, 1e-300); 668 for (unsigned long i = 0; i < dets1.size(); ++i) 669 { 670 const point p = dets1[i].second; 671 check[p.y()][p.x()] = dets1[i].first; 672 } 673 for (unsigned long i = 0; i < dets2.size(); ++i) 674 { 675 const point p = dets2[i].second; 676 DLIB_TEST(std::abs(check[p.y()][p.x()] - dets2[i].first) < 1e-10); 677 } 678 dlog << LINFO << "=======================\n"; 679 } 680 } 681 682 // ---------------------------------------------------------------------------------------- 683 684 class scan_image_tester : public tester 685 { 686 public: scan_image_tester()687 scan_image_tester ( 688 ) : 689 tester ("test_scan_image", 690 "Runs tests on the scan_image routine.") 691 {} 692 perform_test()693 void perform_test ( 694 ) 695 { 696 test_scan_images_movable_parts(); 697 test_max_filter(); 698 699 run_test1(); 700 run_test2(); 701 run_test3<unsigned char>(1); 702 run_test3<unsigned char>(-1); 703 run_test3<double>(1); 704 run_test3<double>(-1); 705 706 test_sum_filter<unsigned char>(); 707 test_sum_filter<double>(); 708 } 709 } a; 710 711 } 712 713 714