1 // This is mul/mfpf/tests/test_edge_finder.cxx
2 //=======================================================================
3 //
4 //  Copyright: (C) 2007 The University of Manchester
5 //
6 //=======================================================================
7 #include <iostream>
8 #include <sstream>
9 #include "testlib/testlib_test.h"
10 //:
11 // \file
12 // \author Tim Cootes
13 // \brief test mfpf_edge_finder
14 
15 #ifdef _MSC_VER
16 #  include "vcl_msvc_warnings.h"
17 #endif
18 #include "vsl/vsl_binary_loader.h"
19 #include <mbl/mbl_cloneables_factory.h>
20 #include <mfpf/mfpf_add_all_loaders.h>
21 #include <mfpf/mfpf_edge_finder.h>
22 #include <mfpf/mfpf_edge_finder_builder.h>
23 #include "vgl/vgl_point_2d.h"
24 #include "vgl/vgl_vector_2d.h"
25 #include "vil/vil_bilin_interp.h"
26 
27 //=======================================================================
28 
test_edge_finder_search(mfpf_point_finder_builder & b)29 void test_edge_finder_search(mfpf_point_finder_builder& b)
30 {
31   std::cout<<"Testing building and search."<<std::endl;
32 
33   mfpf_point_finder* pf = b.new_finder();
34 
35   // Create a test image
36   vimt_image_2d_of<float> image(20,10);
37   image.image().fill(0);
38 
39   // Fill half of image
40   for (int y=0;y<10;++y)
41     for (int x=0;x<10;++x)
42       image.image()(x,y)=99;
43 
44   vgl_point_2d<double> p0(9.5,5), p1(7.5,5);
45   vgl_vector_2d<double> u(1,0);
46 
47   b.clear(1);
48   b.add_example(image,p0,u);
49   b.build(*pf);
50 
51   std::cout<<"Built model: "<<pf<<std::endl;
52 
53   vgl_point_2d<double> new_p;
54   vgl_vector_2d<double> new_u;
55 
56   pf->set_search_area(3,0);
57 
58   pf->search(image,p1,u,new_p,new_u);
59   std::cout<<"Found point: "<<new_p<<std::endl;
60 
61   TEST_NEAR("Correct orientation",(new_u-u).length(),0.0,1e-6);
62   TEST_NEAR("Correct location",(new_p-p0).length(),0.0,1e-6);
63 
64   vimt_image_2d_of<double> response;
65   pf->evaluate_region(image,p1,u,response);
66   TEST("Response ni",response.image().ni(),7);
67   TEST("Response nj",response.image().nj(),1);
68   std::cout<<"World2im: "<<response.world2im()<<std::endl;
69 
70   // Check that response has local minima in correct place
71   vgl_point_2d<double> ip = response.world2im()(new_p);
72   TEST("Best pt in image (i)",
73        ip.x()>=0 && ip.x()<response.image().ni(),true);
74   TEST_NEAR("Best pt in image (j)",ip.y(),0,1e-6);
75 
76   double r0 = vil_bilin_interp_safe(response.image(),ip.x(),ip.y());
77   double r1 = vil_bilin_interp_safe(response.image(),ip.x()-1,ip.y());
78   double r2 = vil_bilin_interp_safe(response.image(),ip.x()+1,ip.y());
79   std::cout<<r0<<','<<r1<<','<<r2<<std::endl;
80   TEST("Local minima 1",r0<r1,true);
81   TEST("Local minima 2",r0<r2,true);
82 
83   delete pf;
84 }
85 
test_edge_finder()86 void test_edge_finder()
87 {
88   std::cout << "***********************\n"
89            << " Testing mfpf_edge_finder\n"
90            << "***********************\n";
91 
92   vsl_add_to_binary_loader(mfpf_edge_finder());
93 
94   mfpf_edge_finder_builder edge_builder;
95   test_edge_finder_search(edge_builder);
96 
97   // -------------------------------------------
98   //  Test configuring from stream
99   // -------------------------------------------
100   {
101     mbl_cloneables_factory<mfpf_point_finder_builder>::add(mfpf_edge_finder_builder());
102 
103     std::istringstream ss(
104           "mfpf_edge_finder_builder\n"
105           "{\n"
106           "  search_ni: 17\n"
107           "}\n");
108 
109     std::unique_ptr<mfpf_point_finder_builder>
110             pfb = mfpf_point_finder_builder::create_from_stream(ss);
111 
112     TEST("Correct Builder",pfb->is_a(),"mfpf_edge_finder_builder");
113     if (pfb->is_a()=="mfpf_edge_finder_builder")
114     {
115       auto &a_pfb = static_cast<mfpf_edge_finder_builder&>(*pfb);
116       std::cout<<a_pfb<<std::endl;
117       TEST("search_ni configured",a_pfb.search_ni(),17);
118     }
119   }
120 
121   {
122     // Test builder returns correct type of object
123     mfpf_edge_finder_builder b;
124     mfpf_point_finder* pf = b.new_finder();
125     TEST("Builder: Correct Finder",pf->is_a(),"mfpf_edge_finder");
126     delete pf;
127   }
128 
129   {
130     mfpf_edge_finder edge_finder;
131     edge_finder.set_search_area(13,0);
132 
133     // Test binary load and save
134     mfpf_point_finder * base_ptr = &edge_finder;
135 
136     vsl_b_ofstream bfs_out("test_edge_finder.bvl.tmp");
137     TEST ("Created test_edge_finder.bvl.tmp for writing",
138           (!bfs_out), false);
139     vsl_b_write(bfs_out, edge_finder);
140     vsl_b_write(bfs_out, base_ptr);
141     bfs_out.close();
142 
143     mfpf_edge_finder edge_finder_in;
144     mfpf_point_finder *base_ptr_in = nullptr;
145 
146     vsl_b_ifstream bfs_in("test_edge_finder.bvl.tmp");
147     TEST ("Opened test_edge_finder.bvl.tmp for reading",
148           (!bfs_in), false);
149     vsl_b_read(bfs_in, edge_finder_in);
150     vsl_b_read(bfs_in, base_ptr_in);
151     TEST ("Finished reading file successfully", (!bfs_in), false);
152     bfs_in.close();
153 
154     TEST("Loaded: search_ni",
155          edge_finder_in.search_ni(),edge_finder.search_ni());
156     TEST("Load edge_finder by base ptr (type)",
157          base_ptr_in->is_a()==edge_finder.is_a(),true);
158 
159     delete base_ptr_in;
160   }
161 
162   vsl_delete_all_loaders();
163 }
164 
165 TESTMAIN(test_edge_finder);
166