Пример #1
0
void AcsAlarmTestCase::testTimestamp()
{
	acsalarm::ASIMessage message;
	laserSource::CERNASIMessage cernMsg(message);

	// test timestampToXML method
	acsalarm::Timestamp tstamp(SECONDS_VALUE,MICROSECONDS_VALUE);
	verifyTimestampXML(cernMsg.timestampToXML(&tstamp,std::string("user-timestamp"),3));
}
Пример #2
0
// also keep timestamps from ImageSpecClass
void CaptureImageState::WriteImageSpec(ImageSpecClass &my_image_spec, int frames)
{
    std::string h5_name = h5file + ":/imgSpec/";
    std::vector<int> tstamp(my_image_spec.timestamps,  my_image_spec.timestamps + frames);
    printf("[CaptureImageState] Writing Image Spec to %s\n",h5file.c_str());
    H5File::WriteVector (h5_name + "timestamps", tstamp, false);
    // save number of frames
    std::vector<int> H5frames(1,frames);
    H5File::WriteVector (h5_name + "frames", H5frames, false);
}
Пример #3
0
bool camera<Tdata>::start_recording(uint window_id, const char *name)
{
    wid = window_id;
    record_cnt = 0;
    if (name)
        recording_name = name;
    // add timestamp to name
    recording_name += "_";
    recording_name += tstamp();
    // create directory
    mkdir_full(recording_name);
    return true;
}
Пример #4
0
std::string detection_thread<T>::
get_output_directory(configuration &conf) {
  std::string s;
  if (conf.exists("output_dir")) s << conf.get_string("output_dir");
  else s << conf.get_string("current_dir");
  if (conf.exists("detections_dir"))
    s << conf.get_string("detections_dir");
  else {
    s << "/detections";
    if (conf.exists_true("nms")) s << "_" << tstamp();
  }
  s << "/";
  mkdir_full(s);
  return s;
}
/**
 * Tests whether a given reading matches a given LIST or SET set.
 *
 * In the https://visl.sdu.dk/cg3_performance.html test data, this function is executed 5746792 times,
 * of which only 1700292 make it past the first index check.
 *
 * @param[in] reading The reading to test
 * @param[in] set The hash of the set to test against
 * @param[in] bypass_index Flag whether to bypass indexes; needed for certain tests, such as unification and sets with special tags
 * @param[in] unif_mode Used to signal that a parent set was a $$unified set
 */
bool GrammarApplicator::doesSetMatchReading(const Reading& reading, const uint32_t set, bool bypass_index, bool unif_mode) {
	// Check whether we have previously seen that this set matches or doesn't match this reading.
	// These indexes are cleared every ((num_windows+4)*2+1) windows to avoid memory ballooning.
	// Only 30% of tests get past this.
	// ToDo: This is not good enough...while numeric tags are special, their failures can be indexed.
	if (!bypass_index && !unif_mode) {
		if (index_readingSet_no[set].find(reading.hash) != index_readingSet_no[set].end()) {
			return false;
		}
		if (index_readingSet_yes[set].find(reading.hash) != index_readingSet_yes[set].end()) {
			return true;
		}
	}

	bool retval = false;

	ticks tstamp(gtimer);
	if (statistics) {
		tstamp = getticks();
	}

	// ToDo: Make all places have Set* directly so we don't need to perform this lookup.
	const Set& theset = *grammar->sets_list[set];

	// The (*) set always matches.
	if (theset.type & ST_ANY) {
		retval = true;
	}
	// If there are no sub-sets, it must be a LIST set.
	else if (theset.sets.empty()) {
		retval = doesSetMatchReading_tags(reading, theset, ((theset.type & ST_TAG_UNIFY) != 0) | unif_mode);
	}
	// &&unified sets
	else if (theset.type & ST_SET_UNIFY) {
		// ToDo: Handle multiple active &&sets at a time.
		// First time, figure out all the sub-sets that match the reading and store them for later comparison
		if (unif_sets_firstrun) {
			const Set& uset = *grammar->sets_list[theset.sets[0]];
			const size_t size = uset.sets.size();
			for (size_t i = 0; i < size; ++i) {
				const Set& tset = *grammar->sets_list[uset.sets[i]];
				if (doesSetMatchReading(reading, tset.number, bypass_index, ((theset.type & ST_TAG_UNIFY) != 0) | unif_mode)) {
					unif_sets->insert(tset.number);
				}
			}
			retval = !unif_sets->empty();
			unif_sets_firstrun = !retval;
		}
		// Subsequent times, test whether any of the previously stored sets match the reading
		else {
			auto sets = ss_u32sv.get();
			for (auto usi : *unif_sets) {
				if (doesSetMatchReading(reading, usi, bypass_index, unif_mode)) {
					sets->insert(usi);
				}
			}
			retval = !sets->empty();
		}
	}
	else {
		// If all else fails, it must be a SET set.
		// Loop through the sub-sets and apply the set operators
		const size_t size = theset.sets.size();
		for (size_t i = 0; i < size; ++i) {
			bool match = doesSetMatchReading(reading, theset.sets[i], bypass_index, ((theset.type & ST_TAG_UNIFY) != 0) | unif_mode);
			bool failfast = false;
			// Operator OR does not modify match, so simply skip it.
			// The result of doing so means that the other operators gain precedence.
			while (i < size - 1 && theset.set_ops[i] != S_OR) {
				switch (theset.set_ops[i]) {
				case S_PLUS:
					if (match) {
						match = doesSetMatchReading(reading, theset.sets[i + 1], bypass_index, ((theset.type & ST_TAG_UNIFY) != 0) | unif_mode);
					}
					break;
				// Failfast makes a difference in A OR B ^ C OR D, where - does not.
				case S_FAILFAST:
					if (doesSetMatchReading(reading, theset.sets[i + 1], bypass_index, ((theset.type & ST_TAG_UNIFY) != 0) | unif_mode)) {
						match = false;
						failfast = true;
					}
					break;
				case S_MINUS:
					if (match) {
						if (doesSetMatchReading(reading, theset.sets[i + 1], bypass_index, ((theset.type & ST_TAG_UNIFY) != 0) | unif_mode)) {
							match = false;
						}
					}
					break;
				case S_NOT:
					if (!match) {
						if (!doesSetMatchReading(reading, theset.sets[i + 1], bypass_index, ((theset.type & ST_TAG_UNIFY) != 0) | unif_mode)) {
							match = true;
						}
					}
					break;
				default:
					break;
				}
				++i;
			}
			if (match) {
				match_sub++;
				retval = true;
				break;
			}
			if (failfast) {
				match_sub++;
				retval = false;
				break;
			}
		}
		// Propagate unified tag to other sets of this set, if applicable
		if (unif_mode || (theset.type & ST_TAG_UNIFY)) {
			const void* tag = 0;
			for (size_t i = 0; i < size; ++i) {
				auto it = unif_tags->find(theset.sets[i]);
				if (it != unif_tags->end()) {
					tag = it->second;
					break;
				}
			}
			if (tag) {
				for (size_t i = 0; i < size; ++i) {
					(*unif_tags)[theset.sets[i]] = tag;
				}
			}
		}
	}
	if (statistics) {
		if (retval) {
			theset.num_match++;
		}
		else {
			theset.num_fail++;
		}
		ticks tmp = getticks();
		theset.total_time += elapsed(tmp, tstamp);
	}

	// Store the result in the indexes in hopes that later runs can pull it directly from them.
	if (retval) {
		index_readingSet_yes[set].insert(reading.hash);
	}
	else {
		if (!(theset.type & ST_TAG_UNIFY) && !unif_mode) {
			index_readingSet_no[set].insert(reading.hash);
		}
	}

	return retval;
}
Пример #6
0
MAIN_QTHREAD(int, argc, char **, argv) { // macro to enable multithreaded gui
#else
  int main(int argc, char **argv) { // regular main without gui
#endif
    try {
      // check input parameters
      if ((argc != 2) && (argc != 3) ) {
	cerr << "wrong number of parameters." << endl;
	cerr << "usage: objdetect <config file> [directory or file]" << endl;
	return -1;
      }
#ifdef __LINUX__
      feenableexcept(FE_DIVBYZERO | FE_INVALID); // enable float exceptions
#endif
      ipp_init(1); // limit IPP (if available) to 1 core
      // load configuration
      configuration	conf(argv[1], true, true, false);
      if (!conf.exists("root2")) {
	string dir;
	dir << dirname(argv[1]) << "/";
	cout << "Looking for trained files in: " << dir << endl;
	conf.set("root2", dir.c_str());
	conf.set("current_dir", dir.c_str());
      }
      conf.resolve();
      if (conf.exists_true("show_conf")) conf.pretty();
      bool		color	      = conf.exists_bool("color");
      uint		norm_size     = conf.get_uint("normalization_size");
      Tnet		threshold     = (Tnet) conf.get_double("threshold");
      bool		display       = false;
      bool		display_states= false;
      bool		mindisplay    = false;
      uint		display_sleep = 0;
      bool		save_video    = false;
      string		cam_type      = conf.get_string("camera");
      int		height        = -1;
      int		width         = -1;
      if (conf.exists("input_height")) height = conf.get_int("input_height");
      if (conf.exists("input_width")) width = conf.get_int("input_width");
      bool              input_random  = conf.exists_true("input_random");
      uint              npasses       = 1;
      char              next_on_key   = 0;
      uint              wid           = 0; // window id
      uint              wid_states    = 0; // window id
      string		outdir        = "out_";
      if (conf.exists("next_on_key")) {
	next_on_key = conf.get_char("next_on_key");
	cout << "Press " << next_on_key << " to process next frame." << endl;
      }
      outdir += tstamp();
      outdir += "/";
      cout << "Saving outputs to " << outdir << endl;

      // load network and weights
      parameter<fs(Tnet)> theparam;
      idx<ubyte> classes(1,1);
      try {
	load_matrix<ubyte>(classes, conf.get_cstring("classes"));
      } catch(string &err) { cerr << "warning: " << err << endl; }
      vector<string> sclasses = ubyteidx_to_stringvector(classes);
      answer_module<SFUNC2(Tnet)> *ans =
       create_answer<SFUNC2(Tnet)>(conf, classes.dim(0));
      uint noutputs = ans->get_nfeatures();
      module_1_1<SFUNC(Tnet)> *net =
	create_network<SFUNC(Tnet)>(theparam, conf, noutputs);
      // loading weights
      if (!conf.exists("weights")) { // manual weights
	cerr << "warning: \"weights\" variable not defined, loading manually "
	     << "if manual_load defined" << endl;
       if (conf.exists_true("manual_load"))
	 manually_load_network(*((layers<SFUNC(Tnet)>*)net), conf);
      } else { // multiple-file weights
	// concatenate weights if multiple ones
	vector<string> w =
	  string_to_stringvector(conf.get_string("weights"));
	cout << "Loading weights from: " << w << endl;
	theparam.load_x(w);
      }
      
      // detector
      detector<fs(Tnet)> detect(*net, sclasses, *ans, NULL, NULL);
      // multi-scaling parameters      
      double maxs = conf.exists("max_scale")?conf.get_double("max_scale") : 1.0;
      double mins = conf.exists("min_scale")?conf.get_double("min_scale") : 1.0;
      t_scaling scaling_type = SCALES_STEP;
      vector<idxdim> scales;
      if (conf.exists("scaling_type"))
       scaling_type = (t_scaling) conf.get_uint("scaling_type");
      switch (scaling_type) {
      case MANUAL:
	if (!conf.exists("scales"))
	  eblerror("expected \"scales\" variable to be defined in manual mode");
	scales = string_to_idxdimvector(conf.get_cstring("scales"));
	detect.set_resolutions(scales);
	break ;
      case ORIGINAL: detect.set_scaling_original(); break ;
      case SCALES_STEP:
	detect.set_resolutions(conf.get_double("scaling"), maxs, mins);
	break ;
      case SCALES_STEP_UP:
	detect.set_resolutions(conf.get_double("scaling"), maxs, mins);
	detect.set_scaling_type(scaling_type);
	break ;
      default:
	detect.set_scaling_type(scaling_type);
      }
     // optimize memory usage by using only 2 buffers for entire flow
     SBUF<Tnet> input(1, 1, 1), output(1, 1, 1);
     if (!conf.exists_false("mem_optimization"))
       detect.set_mem_optimization(input, output, true);
     // zero padding
     float hzpad = 0, wzpad = 0;
     if (conf.exists("hzpad")) hzpad = conf.get_float("hzpad");
     if (conf.exists("wzpad")) wzpad = conf.get_float("wzpad");
     detect.set_zpads(hzpad, wzpad);
      
      bool bmask_class = false;
      if (conf.exists("mask_class"))
	bmask_class = detect.set_mask_class(conf.get_cstring("mask_class"));
      if (conf.exists("input_min")) // limit inputs size
	detect.set_min_resolution(conf.get_uint("input_min")); 
      if (conf.exists("input_max")) // limit inputs size
	detect.set_max_resolution(conf.get_uint("input_max"));
      detect.set_silent();
      if (conf.exists_bool("save_detections")) {
	string detdir = outdir;
	detdir += "detections";
	detdir = detect.set_save(detdir);
	if (conf.exists("save_max_per_frame"))
	  detect.set_save_max_per_frame(conf.get_uint("save_max_per_frame"));
      }
      // nms
      detect.set_cluster_nms(conf.exists_true("cluster_nms"));
      detect.set_scaler_mode(conf.exists_true("scaler_mode"));
      if (conf.exists("nms"))
	detect.set_pruning((t_pruning)conf.get_uint("nms"), 
			   conf.exists("min_hcenter_dist") ? 
			   conf.get_float("min_hcenter_dist") : 0.0,
			   conf.exists("min_wcenter_dist") ? 
			   conf.get_float("min_wcenter_dist") : 0.0,
			   conf.exists("bbox_max_overlap") ? 
			   conf.get_float("bbox_max_overlap") : 1.0,
			   conf.exists_true("share_parts"),
			   conf.exists("threshold2") ? 
			   (Tnet) conf.get_float("threshold2") : 0.0,
			   conf.exists("bbox_max_center_dist") ? 
			   conf.get_float("bbox_max_center_dist") : 0.0,
			   conf.exists("bbox_max_center_dist2") ? 
			   conf.get_float("bbox_max_center_dist2") : 0.0,
			   conf.exists("bbox_max_wcenter_dist") ? 
			   conf.get_float("bbox_max_wcenter_dist") : 0.0,
			   conf.exists("bbox_max_wcenter_dist2") ? 
			   conf.get_float("bbox_max_wcenter_dist2") : 0.0,
			   conf.exists("min_wcenter_dist2") ? 
			   conf.get_float("min_wcenter_dist2") : 0.0,
			   conf.exists("bbox_max_overlap2") ? 
			   conf.get_float("bbox_max_overlap2") : 0.0,
			   conf.exists_true("mean_bb"),
			   conf.exists("same_scale_mhd") ? 
			   conf.get_float("same_scale_mhd") : 0.0,
			   conf.exists("same_scale_mwd") ? 
			   conf.get_float("same_scale_mwd") : 0.0,
			   conf.exists("min_scale_pred") ? 
			   conf.get_float("min_scale_pred") : 0.0,
			   conf.exists("max_scale_pred") ? 
			   conf.get_float("max_scale_pred") : 0.0
			   );
      if (conf.exists("bbox_hfactor") && conf.exists("bbox_wfactor"))
	detect.set_bbox_factors(conf.get_float("bbox_hfactor"),
				conf.get_float("bbox_wfactor"),
				conf.exists("bbox_woverh") ?
				conf.get_float("bbox_woverh") : 1.0,
				conf.exists("bbox_hfactor2") ?
				conf.get_float("bbox_hfactor2") : 1.0,
				conf.exists("bbox_wfactor2") ?
				conf.get_float("bbox_wfactor2") : 1.0);
      if (conf.exists("max_object_hratio"))
	detect.set_max_object_hratio(conf.get_double("max_object_hratio"));
      if (conf.exists("net_min_height") && conf.exists("net_min_width"))
	detect.set_min_input(conf.get_int("net_min_height"),
			     conf.get_int("net_min_width"));
      if (conf.exists("smoothing"))
	detect.set_smoothing(conf.get_uint("smoothing"));
      if (conf.exists("background_name"))
	detect.set_bgclass(conf.get_cstring("background_name"));
      // image search can be configured with a search pattern
      const char *fpattern = IMAGE_PATTERN_MAT;
      if (conf.exists("file_pattern"))
	fpattern = conf.get_cstring("file_pattern");

      // initialize camera (opencv, directory, shmem or video)
      idx<ubyte> frame;
      camera<ubyte> *cam = NULL, *cam2 = NULL;
      if (!strcmp(cam_type.c_str(), "directory")) {
	string dir;
	if (argc >= 3) // read input dir from command line
	  dir = argv[2];
	else if (conf.exists("input_dir"))
	  dir = conf.get_string("input_dir");
	// given list
	list<string> files;
	if (conf.exists("input_list")) {
	  files = string_to_stringlist(conf.get_string("input_list"));
	  cam = new camera_directory<ubyte>(dir.c_str(), height, width,
					    input_random, npasses,
					    std::cout, std::cerr,
					    fpattern, &files);
	} else // given directory only
	  cam = new camera_directory<ubyte>(dir.c_str(), height, width,
					    input_random, npasses,
					    std::cout, std::cerr,
					    fpattern, &files);
      } else if (!strcmp(cam_type.c_str(), "opencv"))
	cam = new camera_opencv<ubyte>(-1, height, width);
#ifdef __LINUX__
      else if (!strcmp(cam_type.c_str(), "v4l2"))
	cam = new camera_v4l2<ubyte>(conf.get_cstring("device"),
				     height, width,
				     conf.exists_true("camera_grayscale"));
#endif
      else if (!strcmp(cam_type.c_str(), "shmem"))
	cam = new camera_shmem<ubyte>("shared-mem", height, width);
      else if (!strcmp(cam_type.c_str(), "video")) {
	if (argc >= 3)
	  cam = new camera_video<ubyte>
	    (argv[2], height, width, conf.get_uint("input_video_sstep"),
	     conf.get_uint("input_video_max_duration"));
	else eblerror("expected 2nd argument");
      } else eblerror("unknown camera type");
      // a camera directory may be used first, then switching to regular cam
      if (conf.exists_bool("precamera"))
	cam2 = new camera_directory<ubyte>(conf.get_cstring("precamdir"),
					   height, width);

      // answer variables & initializations
      vector<bbox*> bboxes;
      vector<bbox*>::iterator ibboxes;
      ostringstream answer_fname;
      mkdir_full(outdir);
      answer_fname << outdir << "bbox.txt";
      // open file      
      ofstream fp(answer_fname.str().c_str());
      if (!fp) {
	cerr << "failed to open " << answer_fname.str() << endl;
	eblerror("open failed");
      }
    
      // gui
#ifdef __GUI__
      display	     = conf.exists_bool("display");
      mindisplay     = conf.exists_bool("minimal_display");
      display_sleep  = conf.get_uint("display_sleep");
      display_states = conf.exists_bool("display_states");
      save_video     = conf.exists_bool("save_video");
      uint qstep1 = 0, qheight1 = 0, qwidth1 = 0,
	qheight2 = 0, qwidth2 = 0, qstep2 = 0;
      if (conf.exists_bool("queue1")) {
	qstep1 = conf.get_uint("qstep1");
	qheight1 = conf.get_uint("qheight1");
	qwidth1 = conf.get_uint("qwidth1"); }
      if (conf.exists_bool("queue2")) {
	qstep2 = conf.get_uint("qstep2");
	qheight2 = conf.get_uint("qheight2");
	qwidth2 = conf.get_uint("qwidth2"); }
      module_1_1_gui netgui;
      wid_states  = display_states ? new_window("network states"):0;
      night_mode();
      wid  = display ? new_window("eblearn object recognition") : 0;
      night_mode();
      float	zoom = 1;
      detector_gui<fs(Tnet)> dgui(conf.exists_bool("queue1"), qstep1, qheight1,
				   qwidth1, conf.exists_bool("queue2"), qstep2,
				   qheight2, qwidth2);
      if (bmask_class)
	dgui.set_mask_class(conf.get_cstring("mask_class"),
			    (Tnet) conf.get_double("mask_threshold"));
      if (save_video) {
	string viddir = outdir;
	viddir += "video";
	cam->start_recording(wid, viddir.c_str());
      }
#endif  
      // timing variables
      timer tpass, toverall;
      long ms;
  
      // loop
      toverall.start();
      while(!cam->empty()) {
	// get a new frame
	tpass.restart();
	// if the pre-camera is defined use it until empty
	if (cam2 && !cam2->empty())
	  frame = cam2->grab();
	else // empty pre-camera, use regular camera
	  frame = cam->grab();
	string frame_name = cam->frame_name();
	// run detector
	if (!display) { // fprop without display
	  bboxes = detect.fprop(frame, threshold, frame_name.c_str());
	}
#ifdef __GUI__
	else { // fprop and display
	  disable_window_updates();
	  clear_window();
	  if (mindisplay)
	    bboxes = dgui.display(detect, frame, threshold, frame_name.c_str(),
				  0, 0, zoom, (Tnet)0, (Tnet)255, wid);
	  else
	    bboxes =
	      dgui.display_inputs_outputs(detect, frame, threshold,
					  frame_name.c_str(), 0, 0, zoom,
					  (Tnet)-1.1, (Tnet)1.1, wid);
	  enable_window_updates();
	  if (display_states) {
	    dgui.display_current(detect, frame, wid_states);
	    select_window(wid);
	  }
	  if (save_video)
	    cam->record_frame();
	}	    
#endif
	ms = tpass.elapsed_milliseconds();
	cout << "processing: " << ms << " ms." << endl;
	cout << "fps: " << cam->fps() << endl;
	// save bounding boxes
	for (ibboxes = bboxes.begin(); ibboxes != bboxes.end(); ++ibboxes) {
	  fp << cam->frame_name() << " " << (*ibboxes)->class_id << " "
	     << (*ibboxes)->confidence << " ";
	  fp << (*ibboxes)->w0 << " " << (*ibboxes)->h0 << " ";
	  fp << (*ibboxes)->w0 + (*ibboxes)->width << " ";
	  fp << (*ibboxes)->h0 + (*ibboxes)->height << endl;
	}
	// sleep display
	if (display_sleep > 0) {
	  cout << "sleeping for " << display_sleep << "ms." << endl;
	  millisleep(display_sleep);
	}
	if (conf.exists("save_max") && 
	    detect.get_total_saved() > conf.get_uint("save_max")) {
	  cout << "Reached max number of detections, exiting." << endl;
	  break ; // limit number of detection saves
	}
      }
      cout << "Execution time: " << toverall.elapsed_minutes() <<" mins" <<endl;
      if (save_video)
	cam->stop_recording(conf.exists_bool("use_original_fps") ?
			    cam->fps() : conf.get_uint("save_video_fps"));
      // free variables
      if (net) delete net;
      if (cam) delete cam;
      // close files
      fp.close();
#ifdef __GUI__
      if (!conf.exists_true("no_gui_quit")) {
	cout << "Closing windows..." << endl;
	quit_gui(); // close all windows
	cout << "Windows closed." << endl;
      }
#endif
    } eblcatcherror();
  return 0;
}
Пример #7
0
NOCONSOLE_MAIN_QTHREAD(int, argc, char**, argv) {
#else
  MAIN_QTHREAD(int, argc, char**, argv) {
#endif /* NOCONSOLE */
#else
    int main(int argc, char **argv) {
      ERROR_MSG("QT not found, install and recompile.");
#endif /* __GUI__ */
      try {
        if (!parse_args(argc, argv))
          return -1;
        // variables
        range.push_back(-1.0); // default range min
        range.push_back(1.0); // default range max
        string conf_fname, diff_fname;
        // show mat images
        list<string> *argmats = new list<string>();
        list<string>::iterator i;
        for (int i = 1; i < argc; ++i) {
          // check for options
          try {
            if (!strcmp(argv[i], "-conf")) {
              ++i; if (i >= argc) throw 0;
              conf_fname = argv[i];
            } else if (!strcmp(argv[i], "-diff")) {
              ++i; if (i >= argc) throw 0;
              diff_fname = argv[i];
            } else if (!strcmp(argv[i], "-zoom")) {
              ++i; if (i >= argc) throw 0;
              zoom = (float) atof(argv[i]);
            } else if (!strcmp(argv[i], "-maxwidth")) {
              ++i; if (i >= argc) throw 0;
              maxwidth = (int) atoi(argv[i]);
            } else if (!strcmp(argv[i], "-video")) {
              video = true;
            } else if (!strcmp(argv[i], "-print")) {
              print = true;
            } else if (!strcmp(argv[i], "-interleaved")) {
              interleaved = true;
            } else if (!strcmp(argv[i], "-save_individually")) {
              save_individually = true;
            } else if (!strcmp(argv[i], "-filename")) {
              show_filename = true;
            } else if (!strcmp(argv[i], "-range")) {
              range.clear();
              ++i; if (i >= argc) throw 0;
              string s = argv[i];
              int k = 0;
              while (s.size()) {
                uint j;
                for (j = 0; j < s.size(); ++j)
                  if (s[j] == ',')
                    break ;
                string s0 = s.substr(0, j);
                if (j >= s.size())
                  s = "";
                else
                  s = s.substr(j + 1, s.size());
                range.push_back(atof(s0.c_str()));
                k++;
              }
              cout << "Fixing input range to " << range[0] << " .. "
                   << range[1] << endl;
              fixed_range = true;
            }
            // enqueue file names
            else {
              cout << argv[i] << endl;
              argmats->push_back(argv[i]);
            }
          } catch (int err) {
            cerr << "input error: ";
            switch (err) {
              case 0: cerr << "expecting string after " << argv[i-1]; break;
              case 1: cerr << "expecting integer after " << argv[i-1]; break;
              case 2: cerr << "unknown parameter " << argv[i-1]; break;
              case 3: cerr << "unknown channel mode " << argv[i-1]; break;
              default: cerr << "undefined error";
            }
            cerr << endl << endl;
            return false;
          }
        }

        // load configuration in conf mode
        if (conf_fname.size() > 0) {
          conf = new configuration(conf_fname);
          if (!conf->exists("root2")) {
            string dir = dirname(conf_fname.c_str());
            cout << "Looking for trained files in: " << dir << endl;
            conf->set("root2", dir.c_str());
            conf->resolve();
          }
          // enable auto range by default in conf mode
          if (!fixed_range)
            autorange = true;
        }
        // diff mode, just print matrices differences
        if (!diff_fname.empty()) {
          i = argmats->begin();
          idx<double> m1 = load_matrix<double>((*i).c_str());
          idx<double> m2 = load_matrix<double>(diff_fname);
          if (!m1.same_dim(m2.get_idxdim())) {
            eblerror("cannot compare matrices of different dimensions " << m1
                     << " and " << m2);
            return -1;
          }
          idx_sub(m1, m2);
          double sum = idx_sum(m1);
          cout << "sum(m1 - m2) = " << sum << endl;
          return 0;
        }

        // display first matrix/image
        i = argmats->begin();
        if (!video) {
          if (!load_display(i, true, argmats)) {
            ERROR_MSG("failed to load image(s)");
            return -1;
          }
        }
        // explore working directory for more images only if a
        // single file was passed
        if (argmats->size() == 1)
          explore = true;

#ifdef __GUI__
#ifdef __BOOST__
        // list all other mat files in image directory
        string dir = argv[1];
        string imgname, tmpname;
        size_t pos = dir.find_last_of('/');
        if (pos == string::npos) {
          imgname = dir;
          dir = "./";
        } else { // it contains a directory
          imgname = dir.substr(pos + 1, dir.size() - pos + 1);
          dir = dir.substr(0, pos);
        }
        list<string> *mats = argmats;
        if (explore)
          mats = find_fullfiles(dir, IMAGE_PATTERN_MAT,
                                NULL, true, false);
        // video mode
        if (video) {
          string out;
          out << "video_" << tstamp();
          mkdir_full(out);
          uint j = 0;
          for (i = mats->begin(); i != mats->end(); ++i, ++j) {
            cout << "video mode: displaying " << *i << endl;
            if (!load_display(i, true, mats)) {
              ERROR_MSG("failed to load image(s)");
              return -1;
            }
            millisleep(3000);
            ostringstream fname;
            fname << out << "/" << setfill('0') << setw(4) << j << "_"
                  << ebl::basename(i->c_str()) << ".png";
            save_window(fname.str().c_str());
            cout << "video mode: saved " << fname.str() << endl;
          }
        } else { // interactive mode
          if ((mats) && (mats->size() >= 1)) {
            // find current position in this list
            for (i = mats->begin(); i != mats->end(); ++i) {
              tmpname = ebl::basename(i->c_str());
              if (!imgname.compare(tmpname))
                break ;
            }
            if (i == mats->end())
              i = mats->begin();
            // loop and wait for key pressed
            while (1) {
              millisleep(50);
              int key = gui.pop_key_pressed();
              // next/previous images only if not everuything is already displayed
              if (mats->size() > nh * nw) {
                if ((key == Qt::Key_Space) || (key == Qt::Key_Right)) {
                  // show next image
                  for (uint k = 0; k < nw * nh; ++k) {
                    i++;
                    if (i == mats->end()) {
                      i = mats->begin();
                    }
                  }
                  load_display(i, true, mats);
                } else if ((key == Qt::Key_Backspace) || (key == Qt::Key_Left)) {
                  // show previous image
                  for (uint k = 0; k < nw * nh; ++k) {
                    if (i == mats->begin())
                      i = mats->end();
                    i--;
                  }
                  load_display(i, true, mats);
                }
              }
              if (key == Qt::Key_I) {
                // show info
                show_info = !show_info;
                if (show_info)
                  show_help = false;
                load_display(i, false, mats);
              } else if (key == Qt::Key_A) {
                // enable autorange
                autorange = !autorange;
                if (autorange)
                  cout << "Enabling automatic input range." << endl;
                else
                  cout << "Disabling automatic input range." << endl;
                load_display(i, false, mats);
              } else if (key == Qt::Key_H) {
                // show help
                show_help = !show_help;
                if (show_help)
                  show_info = false;
                load_display(i, false, mats);
              } else if (key == Qt::Key_Y) {
                // increase number of images shown on height axis
                if (nh * nw < mats->size())
                  nh++;
                load_display(i, false, mats);
              } else if (key == Qt::Key_T) {
                // decrease number of images shown on height axis
                nh = (std::max)((uint) 1, nh - 1);
                load_display(i, false, mats);
              } else if (key == Qt::Key_X) {
                // increase number of images shown on width axis
                if (nh * nw < mats->size())
                  nw++;
                load_display(i, false, mats);
              } else if (key == Qt::Key_Z) {
                // decrease number of images shown on width axis
                nw = (std::max)((uint) 1, nw - 1);
                load_display(i, false, mats);
              } else if (key == Qt::Key_0) {
                // show only channel 0
                chans = 0;
                load_display(i, false, mats);
                cout << "Showing channel 0 only." << endl;
              } else if (key == Qt::Key_1) {
                // show only channel 1
                chans = 1;
                load_display(i, false, mats);
                cout << "Showing channel 1 only." << endl;
              } else if (key == Qt::Key_2) {
                // show only channel 2
                chans = 2;
                load_display(i, false, mats);
                cout << "Showing channel 2 only." << endl;
              } else if (key == Qt::Key_9) {
                // show all channels
                chans = -1;
                load_display(i, false, mats);
                cout << "Showing alls channel." << endl;
              }
            }
          }
        }
        // free objects
        if (mats) delete mats;
#endif /* __BOOST__ */
#endif /* __GUI__ */
        if (argmats) delete argmats;
        if (conf) delete conf;
      } catch(string &err) {
        ERROR_MSG(err.c_str());
      }
      millisleep(500); // TODO: this lets time for window to open, fix this issue
      return 0;
    }