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