1 // This is brl/bbas/bgui/bgui_image_tableau.cxx
2 #include <iostream>
3 #include <cmath>
4 #include <cstdio>
5 #include "bgui_image_tableau.h"
6 //:
7 // \file
8 // \author J.L. Mundy
9 // \brief See bgui_image_tableau.h for a description of this file.
10
11 #ifdef _MSC_VER
12 # include "vcl_msvc_warnings.h"
13 #endif
14 #include "vgui/vgui_event.h"
15 #include "vgui/vgui.h"
16 #include "vgui/vgui_adaptor.h"
17 #include "vgui/vgui_utils.h"
18 #include "vgui/vgui_projection_inspector.h"
19 #include "vil1/vil1_image.h"
20 #include "vil1/vil1_rgba.h"
21 #include "vil/vil_image_view.h"
22 #include "vgui/vgui_range_map_params.h"
23
24
25 //-----------------------------------------------------------------------------
26 //: The constructor takes a snapshot of the current viewport and scissor areas.
27 // The destructor restores that state.
28 //--------------------------------------------------------------------------------
29
bgui_image_tableau()30 bgui_image_tableau::bgui_image_tableau()
31 {
32 handle_motion_ = true; locked_ = false; show_path_=false;
33 mouse_message_ = false;
34 tt_ = new vgui_text_tableau();
35 }
36
bgui_image_tableau(vil_image_resource_sptr const & img,vgui_range_map_params_sptr const & rmp)37 bgui_image_tableau::bgui_image_tableau(vil_image_resource_sptr const & img,
38 vgui_range_map_params_sptr const& rmp)
39 : base(img, rmp) { handle_motion_ = true; locked_ = false; show_path_=false;
40 mouse_message_ = false;
41 capture_mouse_ = false;
42 tt_ = new vgui_text_tableau();}
43
bgui_image_tableau(vil_image_view_base const & img,vgui_range_map_params_sptr const & rmp)44 bgui_image_tableau::bgui_image_tableau(vil_image_view_base const & img,
45 vgui_range_map_params_sptr const& rmp)
46 : base(img, rmp) { handle_motion_ = true; locked_ = false; show_path_=false;
47 mouse_message_ = false;
48 capture_mouse_ = false;
49 tt_ = new vgui_text_tableau();}
50
bgui_image_tableau(vil1_image const & img,vgui_range_map_params_sptr const & rmp)51 bgui_image_tableau::bgui_image_tableau(vil1_image const & img,
52 vgui_range_map_params_sptr const& rmp)
53 : base(img, rmp) { handle_motion_ = true; locked_ = false; show_path_=false;
54 mouse_message_ = false;
55 capture_mouse_ = false;
56 tt_ = new vgui_text_tableau();}
57
bgui_image_tableau(char const * f,vgui_range_map_params_sptr const & rmp)58 bgui_image_tableau::bgui_image_tableau(char const *f,
59 vgui_range_map_params_sptr const& rmp)
60 : base(f, rmp) { handle_motion_ = true; locked_ = false; show_path_=false;
61 mouse_message_ = false;
62 capture_mouse_ = false;
63 tt_ = new vgui_text_tableau();}
64
65 //--------------------------------------------------------------------------------
66
get_image() const67 vil1_image bgui_image_tableau::get_image() const
68 {
69 return base::get_image();
70 }
71
get_image_resource() const72 vil_image_resource_sptr bgui_image_tableau::get_image_resource() const
73 {
74 return base::get_image_resource();
75 }
76
get_pixel_info_from_frame_buffer(const int x,const int y,vgui_event const & e,char * msg)77 void bgui_image_tableau::get_pixel_info_from_frame_buffer(const int x, const int y, vgui_event const &e, char* msg)
78 {
79 // It's easier to get the buffer in vil1_rgba format and then convert to
80 // RGB, because that avoids alignment problems with glReadPixels.
81 vgui_utils::set_glPixelZoom(1,1);
82 glPixelTransferi(GL_MAP_COLOR,0);
83 glPixelTransferi(GL_RED_SCALE,1); glPixelTransferi(GL_RED_BIAS,0);
84 glPixelTransferi(GL_GREEN_SCALE,1); glPixelTransferi(GL_GREEN_BIAS,0);
85 glPixelTransferi(GL_BLUE_SCALE,1); glPixelTransferi(GL_BLUE_BIAS,0);
86
87 glPixelStorei(GL_PACK_ALIGNMENT,1); // byte alignment.
88 glPixelStorei(GL_PACK_ROW_LENGTH,0); // use default value (the arg to pixel routine).
89 glPixelStorei(GL_PACK_SKIP_PIXELS,0); //
90 glPixelStorei(GL_PACK_SKIP_ROWS,0); //
91 double scale = vgui_adaptor::current->get_scale_factor();
92 vil1_rgba<GLubyte> pixel;
93 glReadPixels(e.wx*scale, e.wy*scale, // Physical pixel location
94 1, 1, // height and width (only one pixel)
95 GL_RGBA, // format
96 GL_UNSIGNED_BYTE, // type
97 &pixel);
98 std::sprintf(msg, "(%d, %d) (ubyte)[ R=%d,G=%d,B=%d]", x, y,
99 pixel.r, pixel.g, pixel.b);
100 }
101
102 void bgui_image_tableau::
get_pixel_info_from_image(const int x,const int y,vgui_event const & e,char * msg)103 get_pixel_info_from_image(const int x, const int y,
104 vgui_event const &e, char* msg)
105 {
106 //only implemented for vil image resource and common vil types
107 //(I don't like macros)
108 vil_image_resource_sptr r = this->get_image_resource();
109 if (!r) {
110 if (!this->get_image())
111 {
112 std::sprintf(msg, "(%d, %d) ?", x, y);
113 return;
114 }
115 else
116 {
117 this->get_pixel_info_from_frame_buffer(x, y, e, msg);
118 return;
119 }
120 }
121 //At this point, we have a vil_image and can proceed with the cases.
122 unsigned w = r->ni(), h = r->nj(), n_p = r->nplanes();
123 if (x<0||x>=int(w)||y<0||y>=int(h))
124 {
125 std::sprintf(msg, "(%d, %d) ?", 0, 0);
126 return;
127 }
128 //note: will treat RGBA as a four plane type
129 vil_pixel_format type = vil_pixel_format_component_format(r->pixel_format());
130
131 switch (type )
132 {
133 case VIL_PIXEL_FORMAT_BOOL:
134 {
135 vil_image_view<bool> v = r->get_view();
136 if (!v)
137 std::sprintf(msg, "Pixel Not Available");
138 else
139 std::sprintf(msg, "(%d, %d) (bool) %d", x, y, v(x,y));
140 return;
141 }
142 case VIL_PIXEL_FORMAT_BYTE:
143 {
144 if (n_p==1)
145 {
146 vil_image_view<vxl_byte> v = r->get_view(x,1,y,1);
147 if (!v)
148 std::sprintf(msg, "Pixel Not Available");
149 else
150 std::sprintf(msg, "(%d, %d) (ubyte) %d", x, y, v(0,0));
151 return;
152 }
153 else if (n_p==3)
154 {
155 vil_image_view<vxl_byte > v = r->get_view(x,1,y,1);
156 if (!v)
157 std::sprintf(msg, "Pixel Not Available");
158 else
159 std::sprintf(msg, "(%d, %d) (ubyte)[ R=%d,G=%d,B=%d]", x, y,
160 v(0,0,0), v(0,0,1), v(0,0,2) );
161 return;
162 }
163 else if (n_p==4) {
164 vil_image_view<vxl_byte > v = r->get_view(x,1,y,1);
165 if (!v)
166 std::sprintf(msg, "Pixel Not Available");
167 else//as a default, just display first three bands as RGB
168 std::sprintf(msg, "(%d, %d) (ubyte)[ R=%d,G=%d,B=%d, X=%d]", x, y,
169 v(0,0,0), v(0,0,1), v(0,0,2), v(0,0,3));
170 return;
171 }
172 return;
173 }
174 case VIL_PIXEL_FORMAT_SBYTE:
175 {
176 if (n_p==1)
177 {
178 vil_image_view<vxl_sbyte> v = r->get_view(x,1,y,1);
179 if (!v)
180 std::sprintf(msg, "Pixel Not Available");
181 else
182 std::sprintf(msg, "(%d, %d) (sbyte) %d", x, y, v(0,0));
183 return;
184 }
185 else if (n_p==3)
186 {
187 vil_image_view<vil_rgb<vxl_sbyte> > v = r->get_view(x,1,y,1);
188 if (!v)
189 std::sprintf(msg, "Pixel Not Available");
190 else
191 std::sprintf(msg, "(%d, %d) (sbyte)[ R=%d,G=%d,B=%d]", x, y,
192 v(0,0).R(), v(0,0).G(),v(0,0).B() );
193 return;
194 }
195 else if (n_p==4) {
196 vil_image_view<vxl_byte > v = r->get_view(x,1,y,1);
197 if (!v)
198 std::sprintf(msg, "Pixel Not Available");
199 else//as a default, just display first three bands as RGB
200 std::sprintf(msg, "(%d, %d) (sbyte)[ R=%d,G=%d,B=%d,X=%d]", x, y,
201 v(0,0,0), v(0,0,1), v(0,0,2), v(0,0,3));
202 return;
203 }
204 return;
205 }
206 case VIL_PIXEL_FORMAT_UINT_16:
207 {
208 if (n_p==1)
209 {
210 vil_image_view<vxl_uint_16> v = r->get_view(x,1,y,1);
211 if (!v)
212 std::sprintf(msg, "Pixel Not Available");
213 else
214 std::sprintf(msg, "(%d, %d) (uint16) %d", x, y, v(0,0));
215 return;
216 }
217 else if (n_p==3)
218 {
219 vil_image_view<vil_rgb<vxl_uint_16> > v = r->get_view(x,1,y,1);
220 if (!v)
221 std::sprintf(msg, "Pixel Not Available");
222 else
223 std::sprintf(msg, "(%d, %d) (uint16)[ R=%d,G=%d,B=%d]", x, y,
224 v(0,0).R(), v(0,0).G(),v(0,0).B() );
225 }
226 else if (n_p==4)
227 {
228 vil_image_view<vil_rgba<vxl_uint_16> > v = r->get_view(x,1,y,1);
229 if (!v) {
230 std::sprintf(msg, "Pixel Not Available");
231 return;
232 }
233 else
234 {
235 int band_map = 0;
236 if (rmp_)
237 band_map = rmp_->band_map_;
238 switch (band_map)
239 {
240 case vgui_range_map_params::RGB_m :
241 std::sprintf(msg, "(%d, %d) (RGB:uint16)[ R=%d,G=%d,B=%d,I=%d]",
242 x, y, v(0,0).R(), v(0,0).G(),v(0,0).B(),v(0,0).A() );
243 break;
244 case vgui_range_map_params::XRG_m :
245 std::sprintf(msg, "(%d, %d) (IRG:uint16)[ R=%d,G=%d,B=%d,I=%d]",
246 x, y, v(0,0).R(), v(0,0).G(),v(0,0).B(),v(0,0).A() );
247 break;
248 case vgui_range_map_params::RXB_m :
249 std::sprintf(msg, "(%d, %d) (RIB:uint16)[ R=%d,G=%d,B=%d,I=%d]",
250 x, y, v(0,0).R(), v(0,0).G(),v(0,0).B(),v(0,0).A() );
251 break;
252 case vgui_range_map_params::RGX_m :
253 std::sprintf(msg, "(%d, %d) (RGI:uint16)[ R=%d,G=%d,B=%d,I=%d]",
254 x, y, v(0,0).R(), v(0,0).G(),v(0,0).B(),v(0,0).A() );
255 break;
256 default:
257 std::sprintf(msg, "Pixel Not Available");
258 return;
259 }
260 }
261 }
262 }
263 case VIL_PIXEL_FORMAT_INT_16: {
264 if (n_p==1)
265 {
266 vil_image_view<vxl_int_16> v = r->get_view(x,1,y,1);
267 if (!v)
268 std::sprintf(msg, "Pixel Not Available");
269 else
270 std::sprintf(msg, "(%d, %d) (int16) %d", x, y, v(0,0));
271 return;
272 }
273 else if (n_p==3)
274 {
275 vil_image_view<vil_rgb<vxl_int_16> > v = r->get_view(x,1,y,1);
276 if (!v)
277 std::sprintf(msg, "Pixel Not Available");
278 else
279 std::sprintf(msg, "(%d, %d) (int16)[ R=%d,G=%d,B=%d]", x, y,
280 v(0,0).R(), v(0,0).G(),v(0,0).B() );
281 return;
282 }
283 return;
284 }
285 case VIL_PIXEL_FORMAT_UINT_32: {
286 if (n_p==1)
287 {
288 vil_image_view<vxl_uint_32> v = r->get_view(x,1,y,1);
289 if (!v)
290 std::sprintf(msg, "Pixel Not Available");
291 else
292 std::sprintf(msg, "(%d, %d) (uint32) %d", x, y, v(0,0));
293 return;
294 }
295 else if (n_p==3)
296 {
297 vil_image_view<vil_rgb<vxl_uint_32> > v = r->get_view(x,1,y,1);
298 if (!v)
299 std::sprintf(msg, "Pixel Not Available");
300 else
301 std::sprintf(msg, "(%d, %d) (uint32)[ R=%d,G=%d,B=%d]", x, y,
302 v(0,0).R(), v(0,0).G(),v(0,0).B() );
303 return;
304 }
305 return;
306 }
307 case VIL_PIXEL_FORMAT_FLOAT: {
308 vil_image_view<float> v = r->get_view(x,1,y,1);
309 if (!v)
310 std::sprintf(msg, "Pixel Not Available");
311 else if (n_p == 1)
312 std::sprintf(msg, "(%d, %d) (float) %f", x, y, v(0,0));
313 else if (n_p ==3)
314 std::sprintf(msg, "(%d, %d) (float)[ R=%6.3f,G=%6.3f,B=%6.3f]", x, y,
315 v(0,0,0), v(0,0,1), v(0,0,2) );
316 return;
317 }
318 case VIL_PIXEL_FORMAT_DOUBLE: {
319 vil_image_view<double> v = r->get_view(x,1,y,1);
320 if (!v)
321 std::sprintf(msg, "Pixel Not Available");
322 else
323 std::sprintf(msg, "(%d, %d) (double) %g", x, y, v(0,0));
324 return;
325 }
326 case VIL_PIXEL_FORMAT_RGB_BYTE: {
327 vil_image_view<vil_rgb<vxl_byte> > v = r->get_view(x,1,y,1);
328 if (!v)
329 std::sprintf(msg, "Pixel Not Available");
330 else
331 std::sprintf(msg, "(%d, %d) (ubyte)[ R=%d,G=%d,B=%d]", x, y,
332 v(0,0).R(), v(0,0).G(),v(0,0).B() );
333 return;
334 }
335 case VIL_PIXEL_FORMAT_RGB_UINT_16: {
336 vil_image_view<vil_rgb<vxl_uint_16> > v = r->get_view(x,1,y,1);
337 if (!v)
338 std::sprintf(msg, "Pixel Not Available");
339 else
340 std::sprintf(msg, "(%d, %d) (uint16)[ R=%d,G=%d,B=%d]", x, y,
341 v(0,0).R(), v(0,0).G(),v(0,0).B() );
342 return;
343 }
344 #if 0
345 case VIL_PIXEL_FORMAT_UINT_32:
346 case VIL_PIXEL_FORMAT_INT_32:
347 case VIL_PIXEL_FORMAT_RGB_SBYTE:
348 case VIL_PIXEL_FORMAT_RGB_INT_16:
349 case VIL_PIXEL_FORMAT_RGB_UINT_32:
350 case VIL_PIXEL_FORMAT_RGB_INT_32:
351 case VIL_PIXEL_FORMAT_RGB_FLOAT:
352 case VIL_PIXEL_FORMAT_RGB_DOUBLE:
353 case VIL_PIXEL_FORMAT_RGBA_UINT_32:
354 case VIL_PIXEL_FORMAT_RGBA_INT_32:
355 case VIL_PIXEL_FORMAT_RGBA_UINT_16:
356 case VIL_PIXEL_FORMAT_RGBA_INT_16:
357 case VIL_PIXEL_FORMAT_RGBA_BYTE:
358 case VIL_PIXEL_FORMAT_RGBA_SBYTE:
359 case VIL_PIXEL_FORMAT_RGBA_FLOAT:
360 case VIL_PIXEL_FORMAT_RGBA_DOUBLE:
361 case VIL_PIXEL_FORMAT_COMPLEX_FLOAT:
362 case VIL_PIXEL_FORMAT_COMPLEX_DOUBLE:
363 #endif
364 default:
365 std::sprintf(msg, "Pixel Not Available");
366 }
367 }
368
369 double bgui_image_tableau::
get_pixel_value(const unsigned c,const unsigned r)370 get_pixel_value(const unsigned c, const unsigned r)
371 {
372 vil_image_resource_sptr rs = this->get_image_resource();
373 if (!rs)
374 return 0;
375 if (c>=rs->ni()||r>=rs->nj())
376 return 0;
377 unsigned n_p = rs->nplanes();
378 vil_pixel_format type = rs->pixel_format();
379 switch (type )
380 {
381 case VIL_PIXEL_FORMAT_BOOL: {
382 vil_image_view<bool> v = rs->get_view();
383 if (!v)
384 return 0;
385 else
386 return static_cast<double>(v(0,0));
387 }
388 case VIL_PIXEL_FORMAT_BYTE: {
389 vil_image_view<vxl_byte> v = rs->get_view(c,1,r,1);
390 if (!v)
391 return 0;
392 if (n_p==1)
393 return static_cast<double>(v(0,0));
394 else if (n_p==3)
395 return static_cast<double>(v(0,0,0)+v(0,0,1)+v(0,0,2))/3;
396 }
397 case VIL_PIXEL_FORMAT_SBYTE: {
398 vil_image_view<vxl_sbyte> v = rs->get_view(c,1,r,1);
399 if (!v)
400 return 0;
401 else
402 if (n_p==1)
403 return static_cast<double>(v(0,0));
404 else if (n_p==3)
405 return static_cast<double>(v(0,0,0)+v(0,0,1)+v(0,0,2))/3;
406 }
407 case VIL_PIXEL_FORMAT_UINT_16: {
408 vil_image_view<vxl_uint_16> v = rs->get_view(c,1,r,1);
409 if (!v)
410 return 0;
411 else
412 if (n_p==1)
413 return static_cast<double>(v(0,0));
414 else if (n_p==3)
415 return static_cast<double>(v(0,0,0)+v(0,0,1)+v(0,0,2))/3;
416 else if (n_p==4)
417 return static_cast<double>(v(0,0,0)+v(0,0,1)+v(0,0,2)+v(0,0,3))/4;
418 }
419 case VIL_PIXEL_FORMAT_INT_16: {
420 vil_image_view<vxl_int_16> v = rs->get_view(c,1,r,1);
421 if (!v)
422 return 0;
423 else
424 if (n_p==1)
425 return static_cast<double>(v(0,0));
426 else if (n_p==3)
427 return static_cast<double>(v(0,0,0)+v(0,0,1)+v(0,0,2))/3;
428 }
429 case VIL_PIXEL_FORMAT_FLOAT: {
430 vil_image_view<float> v = rs->get_view(c,1,r,1);
431 if (!v)
432 return 0;
433 else
434 return static_cast<double>(v(0,0));
435 }
436 case VIL_PIXEL_FORMAT_DOUBLE: {
437 vil_image_view<double> v = rs->get_view(c,1,r,1);
438 if (!v)
439 return 0;
440 else
441 return v(0,0);
442 }
443 case VIL_PIXEL_FORMAT_RGB_BYTE: {
444 vil_image_view<vil_rgb<vxl_byte> > v = rs->get_view(c,1,r,1);
445 if (!v)
446 return 0;
447 else
448 return static_cast<double>(v(0,0).R()+v(0,0).G()+v(0,0).B())/3;
449 }
450 case VIL_PIXEL_FORMAT_RGB_UINT_16: {
451 vil_image_view<vil_rgb<vxl_uint_16> > v = rs->get_view(c,1,r,1);
452 if (!v)
453 return 0;
454 else
455 return static_cast<double>(v(0,0).R()+v(0,0).G()+v(0,0).B())/3;
456 }
457 default:
458 return 0;
459 }
460 }
461
462 //: get the pixel value as color
get_color_pixel_value(const unsigned c,const unsigned r)463 std::vector<double> bgui_image_tableau::get_color_pixel_value(const unsigned c, const unsigned r)
464 {
465 vil_image_resource_sptr rs = this->get_image_resource();
466 if (!rs)
467 return std::vector<double>(0);
468 if (c>=rs->ni()||r>=rs->nj())
469 return std::vector<double>(0);
470 unsigned n_p = rs->nplanes();
471 std::vector<double> val(n_p, 0.0);
472 if (n_p==1)
473 {
474 val[0]=this->get_pixel_value(c, r);
475 return val;
476 }
477 //note: will treat RGBA as a four plane type
478 vil_pixel_format type = vil_pixel_format_component_format(rs->pixel_format());
479
480 switch (type )
481 {
482 case VIL_PIXEL_FORMAT_BYTE: {
483 vil_image_view<vxl_byte> v = rs->get_view(c,1,r,1);
484 if (!v)
485 return val;
486 for (unsigned p = 0; p<n_p; ++p)
487 val[p]=static_cast<double>(v(0,0,p));
488 return val;
489 }
490 case VIL_PIXEL_FORMAT_UINT_16: {
491 vil_image_view<vxl_uint_16> v = rs->get_view(c,1,r,1);
492 if (!v)
493 return val;
494 for (unsigned p = 0; p<n_p; ++p)
495 val[p]=static_cast<double>(v(0,0,p));
496 return val;
497 }
498 default:
499 return val;
500 }
501 }
502
image_line(const float col_start,const float row_start,const float col_end,const float row_end,std::vector<double> & line_pos,std::vector<double> & vals)503 void bgui_image_tableau::image_line(const float col_start,
504 const float row_start,
505 const float col_end,
506 const float row_end,
507 std::vector<double>& line_pos,
508 std::vector<double>& vals)
509 {
510 line_pos.clear();vals.clear();
511 vil_image_resource_sptr resc = this->get_image_resource();
512 if(!resc){
513 std::cerr << "null image resoure in image_line" << std::endl;
514 return;
515 }
516 size_t ni = resc->ni(), nj = resc->nj();
517 float nif = static_cast<float>(ni)-1.0f, njf = static_cast<float>(nj)-1.0f;
518 float cs = col_start, ce = col_end;
519 float rs = row_start, re = row_end;
520 // clamp line extremes to valid image range
521 if (cs < 0.0f && ce < 0.0f) {
522 std::cerr << " image line outside of image - abandon plot" << std::endl;
523 return;
524 }
525 if(cs < 0.0f) cs = 0.0f;
526 if(ce < 0.0f) ce = 0.0f;
527
528 if(rs < 0.0f) rs = 0.0f;
529 if(re < 0.0f) re = 0.0f;
530 if (rs < 0.0f && re < 0.0f) {
531 std::cerr << " image line outside of image - abandon plot" << std::endl;
532 return;
533 }
534 if (cs > nif && ce > nif) {
535 std::cerr << " image line outside of image - abandon plot" << std::endl;
536 return;
537 }
538 if(cs > nif) cs = nif;
539 if(ce > nif) ce = nif;
540 if (rs > njf && re > njf) {
541 std::cerr << " image line outside of image - abandon plot" << std::endl;
542 return;
543 }
544 if(rs > njf) rs = njf;
545 if(re > njf) re = njf;
546
547
548
549 //Get the image data
550 // the line length in pixels
551 float length = std::sqrt((ce-cs)*(ce-cs) +
552 (re-rs)*(re-rs));
553 if (length == 0)
554 return;
555 //initialize the line scan parameters
556 float xstep = (ce-cs)/length;
557 float ystep = (re-rs)/length;
558 float sinc = std::sqrt(xstep*xstep + ystep*ystep);
559 float spos = 0;
560 line_pos.push_back(spos);
561 unsigned c = static_cast<unsigned>(cs),
562 r = static_cast<unsigned>(rs);
563 vals.push_back(get_pixel_value(c, r));
564
565 //extract the pixel values along the line
566 float xpos = cs, ypos = rs;
567 unsigned nsteps = static_cast<unsigned>(length);
568 for (unsigned i = 0; i<nsteps; ++i)
569 {
570 xpos += xstep;
571 ypos += ystep;
572 spos += sinc;
573 c = static_cast<unsigned>(xpos);
574 r = static_cast<unsigned>(ypos);
575 line_pos.push_back(spos);
576 vals.push_back(get_pixel_value(c, r));
577 }
578 }
579
580 //: Extract a line of pixel values return color if available
image_line(const float col_start,const float row_start,const float col_end,const float row_end,std::vector<double> & line_pos,std::vector<std::vector<double>> & vals)581 void bgui_image_tableau::image_line(const float col_start,
582 const float row_start,
583 const float col_end,
584 const float row_end,
585 std::vector<double>& line_pos,
586 std::vector<std::vector<double> >& vals)
587 {
588 line_pos.clear();vals.clear();
589 vil_image_resource_sptr resc = this->get_image_resource();
590 if(!resc){
591 std::cerr << "null image resoure in image_line" << std::endl;
592 return;
593 }
594 size_t ni = resc->ni(), nj = resc->nj();
595 float nif = static_cast<float>(ni)-1.0f, njf = static_cast<float>(nj)-1.0f;
596 float cs = col_start, ce = col_end;
597 float rs = row_start, re = row_end;
598 // clamp line extremes to valid image range
599 if (cs < 0.0f && ce < 0.0f) {
600 std::cerr << " image line outside of image - abandon plot" << std::endl;
601 return;
602 }
603 if (cs < 0.0f) cs = 0.0f;
604 if (ce < 0.0f) ce = 0.0f;
605
606 if (rs < 0.0f) rs = 0.0f;
607 if (re < 0.0f) re = 0.0f;
608 if (rs < 0.0f && re < 0.0f) {
609 std::cerr << " image line outside of image - abandon plot" << std::endl;
610 return;
611 }
612 if (cs > nif && ce > nif) {
613 std::cerr << " image line outside of image - abandon plot" << std::endl;
614 return;
615 }
616 if (cs > nif) cs = nif;
617 if (ce > nif) ce = nif;
618 if (rs > njf && re > njf) {
619 std::cerr << " image line outside of image - abandon plot" << std::endl;
620 return;
621 }
622 if (rs > njf) rs = njf;
623 if (re > njf) re = njf;
624
625
626 //Get the image data
627 // the line length in pixels
628 float length = std::sqrt((ce-cs)*(ce-cs) +
629 (re-rs)*(re-rs));
630 if (length == 0)
631 return;
632 //initialize the line scan parameters
633 float xstep = (ce-cs)/length;
634 float ystep = (re-rs)/length;
635 float sinc = std::sqrt(xstep*xstep + ystep*ystep);
636 float spos = 0;
637 line_pos.push_back(spos);
638 unsigned c = static_cast<unsigned>(cs),
639 r = static_cast<unsigned>(rs);
640 std::vector<double> cv = get_color_pixel_value(c, r);
641 unsigned n_bands = cv.size();
642 vals.resize(n_bands);
643 for (unsigned i = 0; i<n_bands; ++i)
644 vals[i].push_back(cv[i]);
645
646 //extract the pixel values along the line
647 float xpos = cs, ypos = rs;
648 unsigned nsteps = static_cast<unsigned>(length);
649 for (unsigned i = 0; i<nsteps; ++i)
650 {
651 xpos += xstep;
652 ypos += ystep;
653 spos += sinc;
654 c = static_cast<unsigned>(xpos);
655 r = static_cast<unsigned>(ypos);
656 line_pos.push_back(spos);
657 cv = get_color_pixel_value(c, r);
658 for (unsigned i = 0; i<n_bands; ++i)
659 vals[i].push_back(cv[i]);
660 }
661 }
unset_mouse_message()662 void bgui_image_tableau::unset_mouse_message(){
663 mouse_message_ = false;
664 capture_mouse_ = false;
665 tt_->clear();
666 post_redraw();
667 }
668
669 //--------------------------------------------------------------------------------
670 //:
671 // Handle all events for this tableau.
handle(vgui_event const & e)672 bool bgui_image_tableau::handle(vgui_event const &e)
673 {
674 #if 0
675 if(e.type != vgui_MOTION)
676 std::cout << "bgui_image " << e << '\n' << std::flush;
677 #endif
678 static bool button_down = false;
679 if (e.type == vgui_DRAW)
680 {
681 bool handled = base::handle(e);
682
683 if(tt_) tt_->handle(e);
684
685 return handled;
686 }
687
688 if (e.type == vgui_BUTTON_DOWN)
689 {
690 button_down = true;
691 if (handle_motion_)
692 vgui::out << ' ' << std::endl;
693 // if the mouse message is active
694 // then store the pixel location of the mouse
695 if(e.button == vgui_LEFT && capture_mouse_){
696 vgui_projection_inspector p_insp;
697 p_insp.window_to_image_coordinates(e.wx, e.wy, mouse_pos_[0],
698 mouse_pos_[1]);
699 }
700 }
701 else if (e.type == vgui_BUTTON_UP)
702 {
703 button_down = false;
704 // if the mouse message is active
705 // display a single line of text (mouse_message_text_)
706 if(e.button == vgui_LEFT && mouse_message_){
707 tt_->clear();
708 tt_->set_colour(0.0f, 0.0f, 0.0f);
709 tt_->set_size(12);
710 // display banner
711 // |
712 // V
713 tt_->add(mouse_pos_[0], mouse_pos_[1], mouse_message_text_);//need to modify text-tableau
714 post_redraw();
715 }
716 }
717 else if (e.type == vgui_MOTION && handle_motion_ && !button_down)
718 {
719 // Get X,Y position to display on status bar:
720 float pointx, pointy;
721 vgui_projection_inspector p_insp;
722 p_insp.window_to_image_coordinates(e.wx, e.wy, pointx, pointy);
723 int intx = (int)std::floor(pointx), inty = (int)std::floor(pointy);
724 char msg[100];
725
726 this->get_pixel_info_from_image(intx, inty,e, msg);
727
728 // gets a snapshot of the viewport so that it restores it back after vgui::out
729 // this is needed, because vgui::out changes viewport, and image tableau
730 // gets confused
731 bgui_image_tableau_vp_sc_snapshot snap;
732
733 // Display on status bar:
734 if (!locked_) {
735 if (show_path_)
736 vgui::out << msg << " " << this->file_name() << std::endl;
737 else
738 vgui::out << msg << std::endl;
739 }
740 }
741 return base::handle(e);
742 }
743
744 //--------------------------------------------------------------------------------
745