Пример #1
0
def process(args):
    '''process a set of files'''

    count = 0
    files = []
    for a in args:
        if os.path.isdir(a):
            files.extend(glob.glob(os.path.join(a, '*.png')))
        else:
            files.append(a)
    files.sort()
    num_files = len(files)
    print("num_files=%u" % num_files)

    if opts.mavlog:
        mpos = mav_position.MavInterpolator(gps_lag=opts.gps_lag)
        mpos.set_logfile(opts.mavlog)
    else:
        print("You must provide a mavlink log file")
        sys.exit(1)

    frame_time = 0

    if opts.destdir:
        cuav_util.mkdir_p(opts.destdir)

    for f in files:
        frame_time = os.path.getmtime(f)
        try:
            if opts.roll_stabilised:
                roll = 0
            else:
                roll = None
            pos = mpos.position(frame_time, opts.max_deltat, roll=roll)
        except mav_position.MavInterpolatorException as e:
            print e
            pos = None

        im_orig = cv.LoadImage(f)

        lat_deg = pos.lat
        lng_deg = pos.lon

        if opts.inplace:
            newfile = f
        else:
            basefile = f.split('.')[0]
            newfile = basefile + '.jpg'
            if opts.destdir:
                newfile = os.path.join(opts.destdir, os.path.basename(newfile))
        cv.SaveImage(newfile, im_orig)
        count += 1

        print("%s %.7f %.7f [%u/%u %.1f%%]" %
              (os.path.basename(newfile), lat_deg, lng_deg, count, num_files,
               (100.0 * count) / num_files))
        set_gps_location(newfile, lat_deg, lng_deg, pos.altitude, pos.time)
Пример #2
0
def process(args):
    '''process a set of files'''

    count = 0
    files = []
    types = ('*.png', '*.jpeg', '*.jpg')
    if os.path.isdir(args.files):
        for tp in types:
            files.extend(glob.glob(os.path.join(args.files, tp)))
    else:
        files.append(args.files)
    files.sort()
    num_files = len(files)
    print("num_files=%u" % num_files)

    mpos = mav_position.MavInterpolator(gps_lag=args.gps_lag)
    mpos.set_logfile(os.path.join(os.getcwd(), args.mavlog))

    frame_time = 0

    poshash = {}

    for f in files:
        #timestamp is in filename
        timestamp = (os.path.splitext(os.path.basename(f))[0])
        m = re.search("\d", timestamp)
        if m:
            timestamp = timestamp[m.start():]

        frame_time = cuav_util.parse_frame_time(f)

        try:
            if args.roll_stabilised:
                roll = 0
            else:
                roll = None
            pos = mpos.position(frame_time, roll=roll)
        except mav_position.MavInterpolatorException as e:
            print(e)
            pos = None

        if pos:
            poshash[os.path.basename(f)] = pos

    dirname = os.path.dirname(f)
    mavpos = os.path.join(dirname, "mavpos.dat")
    open(mavpos, "w").write(pickle.dumps(poshash))
    print("Wrote %s with %u entries" % (mavpos, len(poshash)))
Пример #3
0
def test_MavInterpolator():
    mpos = mav_position.MavInterpolator(gps_lag=0)
    mpos.set_logfile(
        os.path.join(os.getcwd(), 'tests', 'testdata', 'flight.tlog'))
    #frame_time = datetime.datetime.strptime('2016111223465695Z', "%Y%m%d%H%M%S%fZ")
    #frame_time = mav_position.datetime_to_float(frame_time)
    try:
        pos = mpos.position(1478994416.95, 0, roll=None)
    except mav_position.MavInterpolatorException as e:
        assert str(
            e
        ) == "no msgs of type GLOBAL_POSITION_INT before Sun Nov 13 10:46:56 2016 last=" or "no msgs of type GLOBAL_POSITION_INT before Sun Nov 13 23:46:56 2016 last="

    pos = mpos.position(1478996416.95, 0, roll=None)
    assert pos.lat == -35.22515214612007 and pos.lon == 149.53868537397852

    poss = mpos.position(1478996416.00, 0, roll=None)
    assert poss.lat == -35.225220995897715 and poss.lon == 149.53850268690633

    posss = mpos.position(1478998416.34, 0, roll=None)
    assert posss.lat == -35.07964313826459 and posss.lon == 149.92248564626732
Пример #4
0
def process(args):
  '''process a set of files'''

  global slipmap, mosaic
  scan_count = 0
  files = []
  for a in args:
    if os.path.isdir(a):
      files.extend(glob.glob(os.path.join(a, '*.pgm')))
    else:
      files.append(a)
  files.sort()
  num_files = len(files)
  print("num_files=%u" % num_files)
  region_count = 0
  joes = []

  if opts.mavlog:
    mpos = mav_position.MavInterpolator(gps_lag=opts.gps_lag)
    mpos.set_logfile(opts.mavlog)
  else:
    mpos = None

  if opts.boundary:
    boundary = cuav_util.polygon_load(opts.boundary)
  else:
    boundary = None

  if opts.mosaic:
    slipmap = mp_slipmap.MPSlipMap(service='GoogleSat', elevation=True, title='Map')
    icon = slipmap.icon('planetracker.png')
    slipmap.add_object(mp_slipmap.SlipIcon('plane', (0,0), icon, layer=3, rotation=0,
                                           follow=True,
                                           trail=mp_slipmap.SlipTrail()))
    C_params = cam_params.CameraParams(lens=opts.lens)
    path = os.path.join(os.path.dirname(os.path.realpath(__file__)), '..', '..',
                        'cuav', 'data', 'chameleon1_arecont0.json')
    C_params.load(path)
    mosaic = cuav_mosaic.Mosaic(slipmap, C=C_params)
    if boundary is not None:
      mosaic.set_boundary(boundary)

  if opts.joe:
    joes = cuav_util.polygon_load(opts.joe)
    if boundary:
      for i in range(len(joes)):
        joe = joes[i]
        if cuav_util.polygon_outside(joe, boundary):
          print("Error: joe outside boundary", joe)
          return
        icon = slipmap.icon('flag.png')
        slipmap.add_object(mp_slipmap.SlipIcon('joe%u' % i, (joe[0],joe[1]), icon, layer=4))

  joelog = cuav_joe.JoeLog('joe.log')      

  if opts.view:
    viewer = mp_image.MPImage(title='Image')

  frame_time = 0

  for f in files:
    if mpos:
      frame_time = cuav_util.parse_frame_time(f)
      try:
        if opts.roll_stabilised:
          roll = 0
        else:
          roll = None
        pos = mpos.position(frame_time, opts.max_deltat,roll=roll)
        slipmap.set_position('plane', (pos.lat, pos.lon), rotation=pos.yaw)
      except mav_position.MavInterpolatorException as e:
        print e
        pos = None
    else:
      pos = None

    # check for any events from the map
    if opts.mosaic:
      slipmap.check_events()
      mosaic.check_events()

    if f.endswith('.pgm'):
      pgm = cuav_util.PGM(f)
      im = pgm.array
      if pgm.eightbit:
        im_8bit = im
      else:
        im_8bit = numpy.zeros((960,1280,1),dtype='uint8')
        if opts.gamma != 0:
          scanner.gamma_correct(im, im_8bit, opts.gamma)
        else:
          scanner.reduce_depth(im, im_8bit)
      im_full = numpy.zeros((960,1280,3),dtype='uint8')
      scanner.debayer(im_8bit, im_full)
      im_640 = numpy.zeros((480,640,3),dtype='uint8')
      scanner.downsample(im_full, im_640)
    else:
      im_orig = cv.LoadImage(f)
      (w,h) = cuav_util.image_shape(im_orig)
      im_full = im_orig
      im_640 = cv.CreateImage((640, 480), 8, 3)
      cv.Resize(im_full, im_640, cv.CV_INTER_NN)
      im_640 = numpy.ascontiguousarray(cv.GetMat(im_640))
      im_full = numpy.ascontiguousarray(cv.GetMat(im_full))

    count = 0
    total_time = 0
    img_scan = im_640

    t0=time.time()
    for i in range(opts.repeat):
      if opts.fullres:
        regions = scanner.scan(im_full)
        regions = cuav_region.RegionsConvert(regions, 1280, 960)
      else:
        regions = scanner.scan(img_scan)
        regions = cuav_region.RegionsConvert(regions)
      count += 1
    t1=time.time()

    if opts.filter:
      regions = cuav_region.filter_regions(im_full, regions, frame_time=frame_time, min_score=opts.minscore,
                                           filter_type=opts.filter_type)

    scan_count += 1

    # optionally link all the images with joe into a separate directory
    # for faster re-running of the test with just joe images
    if pos and opts.linkjoe and len(regions) > 0:
      cuav_util.mkdir_p(opts.linkjoe)
      if not cuav_util.polygon_outside((pos.lat, pos.lon), boundary):
        joepath = os.path.join(opts.linkjoe, os.path.basename(f))
        if os.path.exists(joepath):
          os.unlink(joepath)
        os.symlink(f, joepath)

    if pos and len(regions) > 0:
      joelog.add_regions(frame_time, regions, pos, f, width=1280, height=960, altitude=opts.altitude)

      if boundary:
        regions = cuav_region.filter_boundary(regions, boundary, pos)

    region_count += len(regions)

    if opts.mosaic and len(regions) > 0:
      composite = cuav_mosaic.CompositeThumbnail(cv.GetImage(cv.fromarray(im_full)), regions)
      thumbs = cuav_mosaic.ExtractThumbs(composite, len(regions))
      mosaic.add_regions(regions, thumbs, f, pos)

    if opts.compress:
      jpeg = scanner.jpeg_compress(im_full, opts.quality)
      jpeg_filename = f[:-4] + '.jpg'
      if os.path.exists(jpeg_filename):
        print('jpeg %s already exists' % jpeg_filename)
        continue
      chameleon.save_file(jpeg_filename, jpeg)

    if opts.view:
      if opts.fullres:
        img_view = im_full
      else:
        img_view = img_scan
      mat = cv.fromarray(img_view)
      for r in regions:
        (x1,y1,x2,y2) = r.tuple()
        (w,h) = cuav_util.image_shape(img_view)
        x1 = x1*w//1280
        x2 = x2*w//1280
        y1 = y1*h//960
        y2 = y2*h//960
        cv.Rectangle(mat, (max(x1-2,0),max(y1-2,0)), (x2+2,y2+2), (255,0,0), 2)
      cv.CvtColor(mat, mat, cv.CV_BGR2RGB)
      viewer.set_image(mat)

    total_time += (t1-t0)
    if t1 != t0:
      print('%s scan %.1f fps  %u regions [%u/%u]' % (
        f, count/total_time, region_count, scan_count, num_files))
Пример #5
0
def process(args):
    '''process a set of files'''

    global slipmap, mosaic
    scan_count = 0
    files = []
    if os.path.isdir(args.directory):
        files.extend(file_list(args.directory, ['jpg', 'pgm', 'png']))
    else:
        if args.directory.find('*') != -1:
            files.extend(glob.glob(args.directory))
        else:
            files.append(args.directory)
    files.sort()
    num_files = len(files)
    print("num_files=%u" % num_files)
    region_count = 0

    slipmap = mp_slipmap.MPSlipMap(service=args.service,
                                   elevation=True,
                                   title='Map')
    icon = slipmap.icon('redplane.png')
    slipmap.add_object(
        mp_slipmap.SlipIcon('plane', (0, 0),
                            icon,
                            layer=3,
                            rotation=0,
                            follow=True,
                            trail=mp_slipmap.SlipTrail()))

    for flag in args.flag:
        a = flag.split(',')
        lat = a[0]
        lon = a[1]
        icon = 'flag.png'
        if len(a) > 2:
            icon = a[2] + '.png'
            icon = slipmap.icon(icon)
            slipmap.add_object(
                mp_slipmap.SlipIcon('icon - %s' % str(flag),
                                    (float(lat), float(lon)),
                                    icon,
                                    layer=3,
                                    rotation=0,
                                    follow=False))

    if args.mission:
        from pymavlink import mavwp
        wp = mavwp.MAVWPLoader()
        wp.load(args.mission.name)
        plist = wp.polygon_list()
        if len(plist) > 0:
            for i in range(len(plist)):
                slipmap.add_object(
                    mp_slipmap.SlipPolygon('Mission-%s-%u' %
                                           (args.mission.name, i),
                                           plist[i],
                                           layer='Mission',
                                           linewidth=2,
                                           colour=(255, 255, 255)))

    if args.mavlog:
        mpos = mav_position.MavInterpolator()
        mpos.set_logfile(args.mavlog.name)
    else:
        mpos = None

    if args.gammalog is not None:
        gamma = parse_gamma_log(args.gammalog)
    else:
        gamma = None

    if args.kmzlog:
        kmzpos = mav_position.KmlPosition(args.kmzlog.name)
    else:
        kmzpos = None

    if args.triggerlog:
        triggerpos = mav_position.TriggerPosition(args.triggerlog.name)
    else:
        triggerpos = None

    # create a simple lens model using the focal length

    if args.camera_params:
        C_params = cam_params.CameraParams.fromfile(args.camera_params.name)
    else:
        C_params = cam_params.CameraParams(lens=args.lens,
                                           sensorwidth=args.sensorwidth,
                                           xresolution=args.xresolution,
                                           yresolution=args.yresolution)

    if args.target:
        target = args.target.split(',')
    else:
        target = [0, 0, 0]

    camera_settings = MPSettings([
        MPSetting('roll_stabilised', bool, args.roll_stabilised,
                  'Roll Stabilised'),
        MPSetting('altitude',
                  int,
                  args.altitude,
                  'Altitude',
                  range=(0, 10000),
                  increment=1),
        MPSetting(
            'minalt', int, 30, 'MinAltitude', range=(0, 10000), increment=1),
        MPSetting('mpp100',
                  float,
                  0.0977,
                  'MPPat100m',
                  range=(0, 10000),
                  increment=0.001),
        MPSetting('rotate180', bool, args.rotate_180, 'rotate180'),
        MPSetting('filter_type',
                  str,
                  'compactness',
                  'Filter Type',
                  choice=['simple', 'compactness']),
        MPSetting('target_lattitude',
                  float,
                  float(target[0]),
                  'target latitude',
                  increment=1.0e-7),
        MPSetting('target_longitude',
                  float,
                  float(target[1]),
                  'target longitude',
                  increment=1.0e-7),
        MPSetting('target_radius',
                  float,
                  float(target[2]),
                  'target radius',
                  increment=1),
        MPSetting('quality',
                  int,
                  75,
                  'Compression Quality',
                  range=(1, 100),
                  increment=1),
        MPSetting('thumbsize',
                  int,
                  args.thumbsize,
                  'Thumbnail Size',
                  range=(10, 200),
                  increment=1),
        MPSetting('minscore',
                  int,
                  args.minscore,
                  'Min Score',
                  range=(0, 1000),
                  increment=1,
                  tab='Scoring'),
        MPSetting('brightness',
                  float,
                  1.0,
                  'Display Brightness',
                  range=(0.1, 10),
                  increment=0.1,
                  digits=2,
                  tab='Display'),
    ],
                                 title='Camera Settings')

    image_settings = MPSettings([
        MPSetting('MinRegionArea',
                  float,
                  0.05,
                  range=(0, 100),
                  increment=0.05,
                  digits=2,
                  tab='Image Processing'),
        MPSetting('MaxRegionArea',
                  float,
                  4.0,
                  range=(0, 100),
                  increment=0.1,
                  digits=1),
        MPSetting('MinRegionSize',
                  float,
                  0.02,
                  range=(0, 100),
                  increment=0.05,
                  digits=2),
        MPSetting('MaxRegionSize',
                  float,
                  3.0,
                  range=(0, 100),
                  increment=0.1,
                  digits=1),
        MPSetting('MaxRarityPct',
                  float,
                  0.02,
                  range=(0, 100),
                  increment=0.01,
                  digits=2),
        MPSetting('RegionMergeSize',
                  float,
                  1.0,
                  range=(0, 100),
                  increment=0.1,
                  digits=1),
        MPSetting('BlueEmphasis', bool, args.blue_emphasis),
        MPSetting('SaveIntermediate', bool, args.debug)
    ],
                                title='Image Settings')

    mosaic = cuav_mosaic.Mosaic(slipmap,
                                C=C_params,
                                camera_settings=camera_settings,
                                image_settings=image_settings,
                                start_menu=True,
                                classify=args.categories,
                                thumb_size=args.mosaic_thumbsize)

    joelog = cuav_joe.JoeLog(None)

    if args.view:
        viewer = mp_image.MPImage(title='Image', can_zoom=True, can_drag=True)

    start_time = time.time()
    for f in files:
        if not mosaic.started():
            print("Waiting for startup")
            if args.start:
                mosaic.has_started = True
            while not mosaic.started():
                mosaic.check_events()
                time.sleep(0.01)

        if mpos:
            # get the position by interpolating telemetry data from the MAVLink log file
            # this assumes that the filename contains the timestamp
            if gamma is not None:
                frame_time = parse_gamma_time(f, gamma)
            else:
                frame_time = cuav_util.parse_frame_time(f)
            frame_time += args.time_offset
            if camera_settings.roll_stabilised:
                roll = 0
            else:
                roll = None
            try:
                pos = mpos.position(frame_time, roll=roll)
            except Exception:
                print("No position available for %s" % frame_time)
                # skip this frame
                continue
        elif kmzpos is not None:
            pos = kmzpos.position(f)
        elif triggerpos is not None:
            pos = triggerpos.position(f)
        else:
            # get the position using EXIF data
            pos = mav_position.exif_position(f)
            pos.time += args.time_offset

        # update the plane icon on the map
        if pos is not None:
            slipmap.set_position('plane', (pos.lat, pos.lon), rotation=pos.yaw)
            if camera_settings.altitude > 0:
                pos.altitude = camera_settings.altitude

        # check for any events from the map
        slipmap.check_events()
        mosaic.check_events()

        im_orig = cuav_util.LoadImage(f, rotate180=camera_settings.rotate180)
        if im_orig is None:
            continue
        (w, h) = cuav_util.image_shape(im_orig)

        if False:
            im_640 = cv.CreateImage((640, 480), 8, 3)
            cv.Resize(im_full, im_640, cv.CV_INTER_NN)
            im_640 = numpy.ascontiguousarray(cv.GetMat(im_640))

        im_full = im_orig
        im_full = numpy.ascontiguousarray(cv.GetMat(im_full))

        count = 0
        total_time = 0

        t0 = time.time()
        img_scan = im_full

        scan_parms = {}
        for name in image_settings.list():
            scan_parms[name] = image_settings.get(name)
        scan_parms['SaveIntermediate'] = float(scan_parms['SaveIntermediate'])
        scan_parms['BlueEmphasis'] = float(scan_parms['BlueEmphasis'])

        if pos is not None:
            (sw, sh) = cuav_util.image_shape(img_scan)
            altitude = pos.altitude
            if altitude < camera_settings.minalt:
                altitude = camera_settings.minalt
            scan_parms[
                'MetersPerPixel'] = camera_settings.mpp100 * altitude / 100.0

            regions = scanner.scan(img_scan, scan_parms)
        else:
            regions = scanner.scan(img_scan)
        regions = cuav_region.RegionsConvert(regions,
                                             cuav_util.image_shape(img_scan),
                                             cuav_util.image_shape(im_full))
        count += 1
        t1 = time.time()

        frame_time = pos.time

        if pos:
            for r in regions:
                r.latlon = cuav_util.gps_position_from_image_region(
                    r, pos, w, h, altitude=altitude, C=C_params)

            if camera_settings.target_radius > 0 and pos is not None:
                regions = cuav_region.filter_radius(
                    regions, (camera_settings.target_lattitude,
                              camera_settings.target_longitude),
                    camera_settings.target_radius)

        regions = cuav_region.filter_regions(
            im_full,
            regions,
            frame_time=frame_time,
            min_score=camera_settings.minscore,
            filter_type=camera_settings.filter_type)

        scan_count += 1

        if pos and len(regions) > 0:
            altitude = camera_settings.altitude
            if altitude <= 0:
                altitude = None
            joelog.add_regions(frame_time,
                               regions,
                               pos,
                               f,
                               width=w,
                               height=h,
                               altitude=altitude)

        mosaic.add_image(pos.time, f, pos)

        region_count += len(regions)

        if len(regions) > 0:
            composite = cuav_mosaic.CompositeThumbnail(
                cv.GetImage(cv.fromarray(im_full)), regions)
            thumbs = cuav_mosaic.ExtractThumbs(composite, len(regions))
            mosaic.add_regions(regions, thumbs, f, pos)

        if args.view:
            img_view = img_scan
            (wview, hview) = cuav_util.image_shape(img_view)
            mat = cv.fromarray(img_view)
            for r in regions:
                r.draw_rectangle(mat, (255, 0, 0))
            cv.CvtColor(mat, mat, cv.CV_BGR2RGB)
            viewer.set_image(mat)
            viewer.set_title('Image: ' + os.path.basename(f))
            if args.saveview:
                cv.CvtColor(mat, mat, cv.CV_RGB2BGR)
                cv.SaveImage('view-' + os.path.basename(f), mat)

        total_time += (t1 - t0)
        if t1 != t0:
            print('%s scan %.1f fps  %u regions [%u/%u]' %
                  (os.path.basename(f), count / total_time, region_count,
                   scan_count, num_files))
        #raw_input("hit ENTER when ready")

    print("All images processed (%u seconds)" % (time.time() - start_time))
    while True:
        # check for any events from the map
        slipmap.check_events()
        mosaic.check_events()
        time.sleep(0.2)
Пример #6
0
    def __init__(self):
        self.running = False
        self.unload = threading.Event()
        self.unload.clear()

        self.capture_thread = None
        self.save_thread = None
        self.scan_thread1 = None
        self.scan_thread2 = None
        self.transmit_thread = None
        self.view_thread = None

        self.settings = mp_settings.MPSettings(
            [ ('depth', int, 8),
              ('gcs_address', str, None),
              ('gcs_view_port', int, 7543),
              ('bandwidth',  int, 40000),
              ('bandwidth2', int, 2000),
              ('capture_brightness', int, 150),
              ('gamma', int, 950),
              ('brightness', float, 1.0),
              ('quality', int, 75),
              ('save_pgm', int, 1),
              ('transmit', int, 1),
              ('roll_stabilised', int, 1),
              ('minscore', int, 75),
              ('minscore2', int, 500),
              ('altitude', int, None),
              ('send1', int, 1),
              ('send2', int, 1),
              ('maxqueue1', int, None),
              ('maxqueue2', int, 30),
              ('thumbsize', int, 60),
              ('packet_loss', int, 0),             
              ('gcs_slave', str, None)  
              ]
            )

        self.capture_count = 0
        self.scan_count = 0
        self.error_count = 0
        self.error_msg = None
        self.region_count = 0
        self.fps = 0
        self.scan_fps = 0
        self.cam = None
        self.save_queue = Queue.Queue()
        self.scan_queue = Queue.Queue()
        self.transmit_queue = Queue.Queue()
        self.viewing = False
        
        self.c_params = CameraParams(lens=4.0)
        self.jpeg_size = 0
        self.xmit_queue = 0
        self.xmit_queue2 = 0
        self.efficiency = 1.0

        self.last_watch = 0
        self.frame_loss = 0
        self.boundary = None
        self.boundary_polygon = None

        self.bandwidth_used = 0
        self.rtt_estimate = 0
        self.bsocket = None
        self.bsend2 = None
        self.bsend_slave = None
        
        # setup directory for images
        self.camera_dir = os.path.join(os.path.dirname(mpstate.logfile_name),
                                      "camera")
        cuav_util.mkdir_p(self.camera_dir)

        self.mpos = mav_position.MavInterpolator(backlog=5000, gps_lag=0.3)
        self.joelog = cuav_joe.JoeLog(os.path.join(self.camera_dir, 'joe.log'), append=mpstate.continue_mode)
        # load camera params
        path = os.path.join(os.path.dirname(os.path.realpath(__file__)), '..', '..', '..',
                            'cuav', 'data', 'chameleon1_arecont0.json')
        self.c_params.load(path)
Пример #7
0
    def __init__(self, mpstate):
        super(CameraAirModule, self).__init__(mpstate,
                                              "camera_air",
                                              "cuav camera control (air)",
                                              public=True)

        self.running = False
        self.unload_event = threading.Event()
        self.unload_event.clear()

        self.capture_thread = None
        self.scan_thread = None
        self.transmit_thread = None
        self.airstart_triggered = False
        self.terrain_alt = None
        self.handled_timestamps = {}
        self.imagefilenamemapping = {}
        self.posmapping = {}
        self.is_armed = True
        self.lz = cuav_landingregion.LandingZone()

        from MAVProxy.modules.lib.mp_settings import MPSettings, MPSetting
        self.camera_settings = MPSettings([
            MPSetting('roll_stabilised', bool, False, 'Roll Stabilised'),
            MPSetting('roll_limit', float, 0, 'Roll stabilisation limit'),
            MPSetting('minspeed', int, 20,
                      'For airstart, minimum speed for capture to start'),
            MPSetting('minalt',
                      int,
                      30,
                      'MinAltitude of images',
                      range=(0, 10000),
                      increment=1),
            MPSetting('rotate180',
                      bool,
                      False,
                      'rotate images by 180',
                      tab='Capture2'),
            MPSetting('ignoretimestamps',
                      bool,
                      False,
                      'Ignore image timestamps',
                      tab='Capture2'),
            MPSetting('camparms',
                      str,
                      None,
                      'camera parameters file (json) in cuav package',
                      tab='Imaging'),
            MPSetting(
                'imagefile', str, None, 'latest captured image',
                tab='Imaging'),
            MPSetting('filter_type',
                      str,
                      'simple',
                      'Filter Type',
                      choice=['simple'],
                      tab='Imaging'),
            MPSetting(
                'blue_emphasis', bool, False, 'BlueEmphasis', tab='Imaging'),
            MPSetting('use_capture_time',
                      bool,
                      True,
                      'Use Capture Time (false for sim)',
                      tab='Simulation'),
            MPSetting('target_latitude',
                      float,
                      0,
                      'filter detected images to latitude',
                      tab='Filter to Location'),
            MPSetting('target_longitude',
                      float,
                      0,
                      'filter detected images to longitude',
                      tab='Filter to Location'),
            MPSetting('target_radius',
                      float,
                      0,
                      'filter detected images to radius',
                      tab='Filter to Location'),
            MPSetting(
                'gcs_address',
                str,
                "",
                'GCS Addresses in RemIP:RemPort:LocalPort:Bandwidth format (127.0.0.1:1440:1234:45, ...)',
                tab='GCS'),
            MPSetting('qualitysend',
                      int,
                      90,
                      'Compression Quality for send',
                      range=(1, 100),
                      increment=1,
                      tab='GCS'),
            MPSetting('transmit',
                      bool,
                      True,
                      'Transmit Enable for thumbnails',
                      tab='GCS'),
            MPSetting('maxqueue', int, 50, 'Maximum images queue', tab='GCS'),
            MPSetting('thumbsize',
                      int,
                      60,
                      'Thumbnail Size',
                      range=(10, 200),
                      increment=1),
            MPSetting('minscore',
                      int,
                      1000,
                      'Min Score to pass detection',
                      range=(0, 100000),
                      increment=1,
                      tab='Imaging'),
            MPSetting('clock_sync', bool, False, 'GPS Clock Sync'),
            MPSetting('m_minscore',
                      int,
                      20000,
                      'Min Score to pass detection on mavlink',
                      range=(0, 100000),
                      increment=1,
                      tab='Imaging'),
            MPSetting('m_bandwidth',
                      int,
                      500,
                      'max bandwidth on mavlink',
                      increment=1,
                      tab='GCS'),
            MPSetting('m_maxqueue',
                      int,
                      5,
                      'Maximum images queue for mavlink',
                      tab='GCS'),
            MPSetting('preview',
                      bool,
                      True,
                      'enable camera preview window',
                      tab='Imaging'),
            MPSetting('previewquality',
                      int,
                      40,
                      'Compression Quality for preview',
                      range=(1, 100),
                      increment=1,
                      tab='Imaging'),
            MPSetting('previewscale',
                      int,
                      5,
                      'preview downscaling',
                      range=(1, 10),
                      increment=1,
                      tab='Imaging'),
            MPSetting('previewfreq',
                      int,
                      4,
                      'preview image frequency',
                      range=(1, 10),
                      increment=1,
                      tab='Imaging'),
        ],
                                          title='Camera Settings')

        self.image_settings = MPSettings([
            MPSetting('MinRegionArea',
                      float,
                      0.15,
                      range=(0, 100),
                      increment=0.05,
                      digits=2,
                      tab='Image Processing'),
            MPSetting('MaxRegionArea',
                      float,
                      1.0,
                      range=(0, 100),
                      increment=0.1,
                      digits=1,
                      tab='Image Processing'),
            MPSetting('MinRegionSize',
                      float,
                      0.2,
                      range=(0, 100),
                      increment=0.05,
                      digits=2,
                      tab='Image Processing'),
            MPSetting('MaxRegionSize',
                      float,
                      1.0,
                      range=(0, 100),
                      increment=0.1,
                      digits=1,
                      tab='Image Processing'),
            MPSetting('MaxRarityPct',
                      float,
                      0.02,
                      range=(0, 100),
                      increment=0.01,
                      digits=2,
                      tab='Image Processing'),
            MPSetting('RegionMergeSize',
                      float,
                      1.0,
                      range=(0, 100),
                      increment=0.1,
                      digits=1,
                      tab='Image Processing'),
        ],
                                         title='Image Settings')

        self.capture_count = 0
        self.scan_count = 0
        self.error_count = 0
        self.error_msg = None
        self.region_count = 0
        self.scan_fps = 0
        self.scan_queue = multiproc.Queue()
        self.transmit_queue = multiproc.Queue()
        self.have_set_gps_time = False

        self.c_params = None
        self.jpeg_size = 0
        self.xmit_queue = []
        self.efficiency = []

        self.last_watch = 0
        self.boundary = None
        self.boundary_polygon = None

        self.bandwidth_used = []
        self.rtt_estimate = []
        self.bsend = []  #note this is an array of bsends

        # msend is a BlockSender over MAVLink
        self.msocket = None
        self.msend = None
        self.last_heartbeat = time.time()

        self.mpos = mav_position.MavInterpolator(backlog=500, gps_lag=0.0)
        self.joelog = None  #cuav_joe.JoeLog(os.path.join(self.settings.imagefile, '..', 'joe.log'), append=self.continue_mode)

        self.add_command(
            'camera', self.cmd_camera, 'camera control',
            ['<start|stop|status|boundary|airstart>', 'set (CAMERASETTING)'])
        self.add_completion_function('(CAMERASETTING)',
                                     self.camera_settings.completion)

        # prevent loopback of messages
        for mtype in ['DATA16', 'DATA32', 'DATA64', 'DATA96']:
            self.module('link').no_fwd_types.add(mtype)

        print("camera initialised")
Пример #8
0
def process(args):
    '''process a set of files'''

    count = 0
    files = []
    types = ('*.png', '*.jpeg', '*.jpg')
    if os.path.isdir(args.files):
        for tp in types:
            files.extend(glob.glob(os.path.join(args.files, tp)))
    else:
        files.append(args.files)
    files.sort()
    num_files = len(files)
    print("num_files=%u" % num_files)

    mpos = mav_position.MavInterpolator(gps_lag=args.gps_lag)
    mpos.set_logfile(os.path.join(os.getcwd(), args.mavlog))

    frame_time = 0

    if args.destdir:
        cuav_util.mkdir_p(args.destdir)

    for f in files:
        #timestamp is in filename
        timestamp = (os.path.splitext(os.path.basename(f))[0])
        m = re.search("\d", timestamp)
        if m:
            timestamp = timestamp[m.start():]

        frame_time = datetime.datetime.strptime(timestamp, "%Y%m%d%H%M%S%fZ")
        frame_time = mav_position.datetime_to_float(frame_time)

        try:
            if args.roll_stabilised:
                roll = 0
            else:
                roll = None
            pos = mpos.position(frame_time, args.max_deltat, roll=roll)
        except mav_position.MavInterpolatorException as e:
            print(e)
            pos = None

        if pos:

            lat_deg = pos.lat
            lng_deg = pos.lon

            if args.inplace:
                outfile = f
            else:
                basefile = os.path.basename(f)
                outfile = ""
                if args.destdir:
                    outfile = os.path.join(args.destdir, basefile)
                else:
                    outfile = os.path.join(os.getcwd(), basefile)
                shutil.copy2(f, outfile)
            count += 1

            print(
                "%s %.7f %.7f [%u/%u %.1f%%]" %
                (os.path.basename(outfile), lat_deg, lng_deg, count, num_files,
                 (100.0 * count) / num_files))
            set_gps_location(outfile, lat_deg, lng_deg, pos.altitude, pos.time)
Пример #9
0
def process(args):
    '''process a set of files'''

    global slipmap, mosaic
    scan_count = 0
    files = []
    for a in args:
        if os.path.isdir(a):
            files.extend(file_list(a, ['jpg', 'pgm', 'png']))
        else:
            if a.find('*') != -1:
                files.extend(glob.glob(a))
            else:
                files.append(a)
    files.sort()
    num_files = len(files)
    print("num_files=%u" % num_files)
    region_count = 0

    slipmap = mp_slipmap.MPSlipMap(service=opts.service,
                                   elevation=True,
                                   title='Map')
    icon = slipmap.icon('redplane.png')
    slipmap.add_object(
        mp_slipmap.SlipIcon('plane', (0, 0),
                            icon,
                            layer=3,
                            rotation=0,
                            follow=True,
                            trail=mp_slipmap.SlipTrail()))

    if opts.mission:
        from pymavlink import mavwp
        wp = mavwp.MAVWPLoader()
        wp.load(opts.mission)
        boundary = wp.polygon()
        slipmap.add_object(
            mp_slipmap.SlipPolygon('mission',
                                   boundary,
                                   layer=1,
                                   linewidth=1,
                                   colour=(255, 255, 255)))

    if opts.mavlog:
        mpos = mav_position.MavInterpolator()
        mpos.set_logfile(opts.mavlog)
    else:
        mpos = None

    if opts.kmzlog:
        kmzpos = mav_position.KmlPosition(opts.kmzlog)
    else:
        kmzpos = None

    if opts.triggerlog:
        triggerpos = mav_position.TriggerPosition(opts.triggerlog)
    else:
        triggerpos = None

    # create a simple lens model using the focal length
    C_params = cam_params.CameraParams(lens=opts.lens,
                                       sensorwidth=opts.sensorwidth)

    if opts.camera_params:
        C_params.load(opts.camera_params)

    camera_settings = MPSettings([
        MPSetting('roll_stabilised', bool, True, 'Roll Stabilised'),
        MPSetting(
            'altitude', int, 0, 'Altitude', range=(0, 10000), increment=1),
        MPSetting('filter_type',
                  str,
                  'simple',
                  'Filter Type',
                  choice=['simple', 'compactness']),
        MPSetting('fullres', bool, False, 'Full Resolution'),
        MPSetting('quality',
                  int,
                  75,
                  'Compression Quality',
                  range=(1, 100),
                  increment=1),
        MPSetting('thumbsize',
                  int,
                  60,
                  'Thumbnail Size',
                  range=(10, 200),
                  increment=1),
        MPSetting('minscore',
                  int,
                  75,
                  'Min Score',
                  range=(0, 1000),
                  increment=1,
                  tab='Scoring'),
        MPSetting('brightness',
                  float,
                  1.0,
                  'Display Brightness',
                  range=(0.1, 10),
                  increment=0.1,
                  digits=2,
                  tab='Display')
    ],
                                 title='Camera Settings')

    image_settings = MPSettings([
        MPSetting('MinRegionArea',
                  float,
                  0.15,
                  range=(0, 100),
                  increment=0.05,
                  digits=2,
                  tab='Image Processing'),
        MPSetting('MaxRegionArea',
                  float,
                  2.0,
                  range=(0, 100),
                  increment=0.1,
                  digits=1),
        MPSetting('MinRegionSize',
                  float,
                  0.1,
                  range=(0, 100),
                  increment=0.05,
                  digits=2),
        MPSetting(
            'MaxRegionSize', float, 2, range=(0, 100), increment=0.1,
            digits=1),
        MPSetting('MaxRarityPct',
                  float,
                  0.02,
                  range=(0, 100),
                  increment=0.01,
                  digits=2),
        MPSetting('RegionMergeSize',
                  float,
                  3.0,
                  range=(0, 100),
                  increment=0.1,
                  digits=1),
        MPSetting('SaveIntermediate', bool, False)
    ],
                                title='Image Settings')

    mosaic = cuav_mosaic.Mosaic(slipmap,
                                C=C_params,
                                camera_settings=camera_settings,
                                image_settings=image_settings,
                                start_menu=True)

    joelog = cuav_joe.JoeLog(None)

    if opts.view:
        viewer = mp_image.MPImage(title='Image', can_zoom=True, can_drag=True)

    if camera_settings.filter_type == 'compactness':
        calculate_compactness = True
        print("Using compactness filter")
    else:
        calculate_compactness = False

    for f in files:
        if not mosaic.started():
            print("Waiting for startup")
            while not mosaic.started():
                mosaic.check_events()
                time.sleep(0.01)

        if mpos:
            # get the position by interpolating telemetry data from the MAVLink log file
            # this assumes that the filename contains the timestamp
            frame_time = cuav_util.parse_frame_time(f) + opts.time_offset
            if camera_settings.roll_stabilised:
                roll = 0
            else:
                roll = None
            try:
                pos = mpos.position(frame_time, roll=roll)
            except Exception:
                print("No position available for %s" % frame_time)
                # skip this frame
                continue
        elif kmzpos is not None:
            pos = kmzpos.position(f)
        elif triggerpos is not None:
            pos = triggerpos.position(f)
        else:
            # get the position using EXIF data
            pos = mav_position.exif_position(f)
            pos.time += opts.time_offset

        # update the plane icon on the map
        if pos is not None:
            slipmap.set_position('plane', (pos.lat, pos.lon), rotation=pos.yaw)
            if camera_settings.altitude > 0:
                pos.altitude = camera_settings.altitude

        # check for any events from the map
        slipmap.check_events()
        mosaic.check_events()

        im_orig = cuav_util.LoadImage(f)
        (w, h) = cuav_util.image_shape(im_orig)

        if not opts.camera_params:
            C_params.set_resolution(w, h)

        im_full = im_orig

        im_640 = cv.CreateImage((640, 480), 8, 3)
        cv.Resize(im_full, im_640, cv.CV_INTER_NN)
        im_640 = numpy.ascontiguousarray(cv.GetMat(im_640))
        im_full = numpy.ascontiguousarray(cv.GetMat(im_full))

        count = 0
        total_time = 0

        t0 = time.time()
        if camera_settings.fullres:
            img_scan = im_full
        else:
            img_scan = im_640

        scan_parms = {}
        for name in image_settings.list():
            scan_parms[name] = image_settings.get(name)
        scan_parms['SaveIntermediate'] = float(scan_parms['SaveIntermediate'])

        if pos is not None:
            (sw, sh) = cuav_util.image_shape(img_scan)
            mpp = cuav_util.meters_per_pixel(pos, C=C_params)
            if mpp is not None:
                scan_parms['MetersPerPixel'] = mpp * (w / float(sw))
            regions = scanner.scan(img_scan, scan_parms)
        else:
            regions = scanner.scan(img_scan)
        regions = cuav_region.RegionsConvert(regions,
                                             cuav_util.image_shape(img_scan),
                                             cuav_util.image_shape(im_full),
                                             calculate_compactness)
        count += 1
        t1 = time.time()

        frame_time = pos.time

        regions = cuav_region.filter_regions(
            im_full,
            regions,
            frame_time=frame_time,
            min_score=camera_settings.minscore,
            filter_type=camera_settings.filter_type)

        scan_count += 1

        mosaic.add_image(pos.time, f, pos)

        if pos and len(regions) > 0:
            altitude = camera_settings.altitude
            if altitude <= 0:
                altitude = None
            joelog.add_regions(frame_time,
                               regions,
                               pos,
                               f,
                               width=w,
                               height=h,
                               altitude=altitude)

        region_count += len(regions)

        if len(regions) > 0:
            composite = cuav_mosaic.CompositeThumbnail(
                cv.GetImage(cv.fromarray(im_full)), regions)
            thumbs = cuav_mosaic.ExtractThumbs(composite, len(regions))
            mosaic.add_regions(regions, thumbs, f, pos)

        if opts.view:
            img_view = img_scan
            (wview, hview) = cuav_util.image_shape(img_view)
            mat = cv.fromarray(img_view)
            for r in regions:
                r.draw_rectangle(mat, (255, 0, 0))
            cv.CvtColor(mat, mat, cv.CV_BGR2RGB)
            viewer.set_image(mat)
            viewer.set_title('Image: ' + os.path.basename(f))

        total_time += (t1 - t0)
        if t1 != t0:
            print('%s scan %.1f fps  %u regions [%u/%u]' %
                  (os.path.basename(f), count / total_time, region_count,
                   scan_count, num_files))
Пример #10
0
def process(args):
    '''process a set of files'''

    global slipmap, mosaic
    scan_count = 0
    files = scan_image_directory(args.imagedir)
    files.sort()
    num_files = len(files)
    print("num_files=%u" % num_files)
    region_count = 0
    joes = []

    if args.mavlog:
        mpos = mav_position.MavInterpolator(gps_lag=args.gps_lag)
        mpos.set_logfile(args.mavlog)
    else:
        mpos = None

    if args.boundary:
        boundary = cuav_util.polygon_load(args.boundary)
    else:
        boundary = None

    if args.mosaic:
        slipmap = mp_slipmap.MPSlipMap(service='GoogleSat', elevation=True, title='Map')
        icon = slipmap.icon('redplane.png')
        slipmap.add_object(mp_slipmap.SlipIcon('plane', (0,0), icon, layer=3, rotation=0,
                                         follow=True,
                                         trail=mp_slipmap.SlipTrail()))
        if args.camera_params:
            C_params = cam_params.CameraParams.fromfile(args.camera_params.name)
        else:
            im_orig = cv2.imread(files[0])
            (w,h) = cuav_util.image_shape(im_orig)
            C_params = cam_params.CameraParams(lens=args.lens, sensorwidth=args.sensorwidth, xresolution=w, yresolution=h)
        mosaic = cuav_mosaic.Mosaic(slipmap, C=C_params)
        if boundary is not None:
            mosaic.set_boundary(boundary)

    if args.joe:
        joes = cuav_util.polygon_load(args.joe)
        if boundary:
            for i in range(len(joes)):
                joe = joes[i]
                if cuav_util.polygon_outside(joe, boundary):
                    print("Error: joe outside boundary", joe)
                    return
                icon = slipmap.icon('flag.png')
                slipmap.add_object(mp_slipmap.SlipIcon('joe%u' % i, (joe[0],joe[1]), icon, layer=4))

    joelog = cuav_joe.JoeLog('joe.log')      

    if args.view:
        viewer = mp_image.MPImage(title='Image')

    frame_time = 0

    scan_parms = {
        'MinRegionArea' : args.min_region_area,
        'MaxRegionArea' : args.max_region_area,
        'MinRegionSize' : args.min_region_size,
        'MaxRegionSize' : args.max_region_size,
        'MaxRarityPct'  : args.max_rarity_pct,
        'RegionMergeSize' : args.region_merge,
        'SaveIntermediate' : float(0),
        #'SaveIntermediate' : float(args.debug),
        'MetersPerPixel' : args.meters_per_pixel100 * args.altitude / 100.0
    }

    filenum = 0
        
    for f in files:
        filenum += 1
        if mpos:
            frame_time = cuav_util.parse_frame_time(f)
            try:
                if args.roll_stabilised:
                    roll = 0
                else:
                    roll = None
                pos = mpos.position(frame_time, args.max_deltat,roll=roll)
                slipmap.set_position('plane', (pos.lat, pos.lon), rotation=pos.yaw)
            except mav_position.MavInterpolatorException as e:
                print(e)
                pos = None
        else:
              pos = None

        # check for any events from the map
        if args.mosaic:
            slipmap.check_events()
            mosaic.check_events()

        im_orig = cv2.imread(f)
        (w,h) = cuav_util.image_shape(im_orig)
        im_full = im_orig
        im_half = cv2.resize(im_orig, (0,0), fx=0.5, fy=0.5)
        im_half = numpy.ascontiguousarray(im_half)
        im_full = numpy.ascontiguousarray(im_full)

        count = 0
        total_time = 0
        if args.fullres:
            img_scan = im_full
        else:
            img_scan = im_half

        t0=time.time()
        for i in range(args.repeat):
            regions = scanner.scan(img_scan, scan_parms)
            regions = cuav_region.RegionsConvert(regions, cuav_util.image_shape(img_scan), cuav_util.image_shape(im_full))
            count += 1
        t1=time.time()

        if args.filter:
            regions = cuav_region.filter_regions(im_full, regions, min_score=args.minscore,
                                           filter_type=args.filter_type)

        if len(regions) > 0 and args.debug:
            composite = cuav_region.CompositeThumbnail(im_full, regions, thumb_size=args.thumb_size)
            thumbs = cuav_mosaic.ExtractThumbs(composite, len(regions))
            thumb_num = 0
            for thumb in thumbs:
                print("thumb %u score %f" % (thumb_num, regions[thumb_num].score))
                cv2.imwrite('%u_thumb%u.jpg' % (filenum,thumb_num), thumb)
                thumb_num += 1
            
        scan_count += 1

        # optionally link all the images with joe into a separate directory
        # for faster re-running of the test with just joe images
        if pos and args.linkjoe and len(regions) > 0:
            cuav_util.mkdir_p(args.linkjoe)
            if not cuav_util.polygon_outside((pos.lat, pos.lon), boundary):
                joepath = os.path.join(args.linkjoe, os.path.basename(f))
                if os.path.exists(joepath):
                    os.unlink(joepath)
                os.symlink(f, joepath)

        if pos and len(regions) > 0:
            joelog.add_regions(frame_time, regions, pos, f, width=w, height=h, altitude=args.altitude, C=C_params)

        if boundary:
            regions = cuav_region.filter_boundary(regions, boundary, pos)

        region_count += len(regions)

        if args.mosaic and len(regions) > 0 and pos:
            composite = cuav_region.CompositeThumbnail(im_full, regions)
            thumbs = cuav_mosaic.ExtractThumbs(composite, len(regions))
            mosaic.add_regions(regions, thumbs, f, pos)

        if args.view:
            if args.fullres:
                img_view = im_full
            else:
                img_view = img_scan
            #mat = cv.fromarray(img_view)
            for r in regions:
                r.draw_rectangle(img_view, colour=(255,0,0), linewidth=min(max(w/600,1),3), offset=max(w/200,1))
            img_view = cv2.cvtColor(img_view, cv2.COLOR_BGR2RGB)
            viewer.set_image(img_view)

        total_time += (t1-t0)
        if t1 != t0:
            print('%s scan %.1f fps  %u regions [%u/%u]' % (
                f, count/total_time, region_count, scan_count, num_files))
Пример #11
0
def playback(mavcon, images, targets, target_lat, target_lon, C_params):
    '''create synthetic images matching target position'''
    print("Connecting to %s" % mavcon)
    mlog = mavutil.mavlink_connection(mavcon)

    # get first message
    msg = mlog.recv_match(type='ATTITUDE', blocking=True)
    mavtime = msg.time_boot_ms * 0.001
    last_print = time.time()
    last_image = mavtime
    mpos = mav_position.MavInterpolator()

    Xres = 1640
    Yres = 1232

    tmpimages = "tmpimages"
    print("Using %s directory" % tmpimages)
    try:
        os.mkdir(tmpimages)
    except Exception:
        pass

    while True:
        msg = mlog.recv_match(blocking=False)
        if not msg:
            time.sleep(0.1)
            continue
        mpos.add_msg(msg)
        mtype = msg.get_type()

        if mtype == "ATTITUDE":
            mavtime = msg.time_boot_ms * 0.001
            if mavtime - last_image > 0.8:
                last_image = mavtime
                if not 'GLOBAL_POSITION_INT' in mlog.messages:
                    continue
                frame_time = time.time() - 2.0
                try:
                    pos = mpos.position(frame_time)
                except Exception:
                    continue

                imgfile = random.choice(images)
                img = cv2.imread(imgfile)
                filename = os.path.join(
                    tmpimages,
                    cuav_util.frame_time(frame_time) + ".jpg")

                # see if the target should be in the image
                xy = find_xy_in_image(target_lat, target_lon, pos, Xres, Yres,
                                      C_params)
                if xy is None:
                    # when we are not modifying the image use a hardlink to save space
                    os.link(imgfile, filename)
                else:
                    # overlay a random target on the image
                    (x, y) = xy
                    tgtfile = random.choice(targets)
                    # targets come from an 80m reference height
                    tgt_scale = 80.0 / max(pos.altitude, 1)
                    tgt = cv2.imread(tgtfile)
                    tgt = cv2.resize(tgt, (0, 0), fx=tgt_scale, fy=tgt_scale)

                    try:
                        img[y:y + tgt.shape[0], x:x + tgt.shape[1]] = tgt
                        cv2.imwrite(filename, img)
                    except Exception:
                        os.link(imgfile, filename)
                # create symlink
                try:
                    os.unlink("capture.jpg")
                except Exception:
                    pass
                os.symlink(filename, "capture.jpg")
                print(filename, xy)
Пример #12
0
def process(args):
    '''process a set of files'''

    global slipmap, mosaic
    scan_count = 0
    files = []
    for a in args:
        if os.path.isdir(a):
            files.extend(file_list(a, ['jpg', 'pgm', 'png']))
        else:
            if a.find('*') != -1:
                files.extend(glob.glob(a))
            else:
                files.append(a)
    files.sort()
    num_files = len(files)
    print("num_files=%u" % num_files)
    region_count = 0

    slipmap = mp_slipmap.MPSlipMap(service=opts.service,
                                   elevation=True,
                                   title='Map')
    icon = slipmap.icon('redplane.png')
    slipmap.add_object(
        mp_slipmap.SlipIcon('plane', (0, 0),
                            icon,
                            layer=3,
                            rotation=0,
                            follow=True,
                            trail=mp_slipmap.SlipTrail()))

    if opts.mission:
        from pymavlink import mavwp
        wp = mavwp.MAVWPLoader()
        wp.load(opts.mission)
        boundary = wp.polygon()
        slipmap.add_object(
            mp_slipmap.SlipPolygon('mission',
                                   boundary,
                                   layer=1,
                                   linewidth=1,
                                   colour=(255, 255, 255)))

    if opts.mavlog:
        mpos = mav_position.MavInterpolator()
        mpos.set_logfile(opts.mavlog)
    else:
        mpos = None

    if opts.kmzlog:
        kmzpos = mav_position.KmlPosition(opts.kmzlog)
    else:
        kmzpos = None

    if opts.triggerlog:
        triggerpos = mav_position.TriggerPosition(opts.triggerlog)
    else:
        triggerpos = None

    # create a simple lens model using the focal length
    C_params = cam_params.CameraParams(lens=opts.lens,
                                       sensorwidth=opts.sensorwidth)

    if opts.camera_params:
        C_params.load(opts.camera_params)

    mosaic = cuav_mosaic.Mosaic(slipmap, C=C_params)

    joelog = cuav_joe.JoeLog(None)

    if opts.view:
        viewer = mp_image.MPImage(title='Image', can_zoom=True, can_drag=True)

    scan_parms = {
        'MinRegionArea': opts.min_region_area,
        'MaxRegionArea': opts.max_region_area,
        'MinRegionSize': opts.min_region_size,
        'MaxRegionSize': opts.max_region_size,
        'MaxRarityPct': opts.max_rarity_pct,
        'RegionMergeSize': opts.region_merge
    }

    for f in files:
        if mpos:
            # get the position by interpolating telemetry data from the MAVLink log file
            # this assumes that the filename contains the timestamp
            frame_time = cuav_util.parse_frame_time(f) + opts.time_offset
            if opts.roll_stabilised:
                roll = 0
            else:
                roll = None
            try:
                pos = mpos.position(frame_time, roll=roll)
            except Exception:
                print("No position available for %s" % frame_time)
                # skip this frame
                continue
        elif kmzpos is not None:
            pos = kmzpos.position(f)
        elif triggerpos is not None:
            pos = triggerpos.position(f)
        else:
            # get the position using EXIF data
            pos = mav_position.exif_position(f)
            pos.time += opts.time_offset

        # update the plane icon on the map
        if pos is not None:
            slipmap.set_position('plane', (pos.lat, pos.lon), rotation=pos.yaw)

        # check for any events from the map
        slipmap.check_events()
        mosaic.check_events()

        im_orig = cuav_util.LoadImage(f)
        (w, h) = cuav_util.image_shape(im_orig)

        if not opts.camera_params:
            C_params.set_resolution(w, h)

        im_full = im_orig

        im_640 = cv.CreateImage((640, 480), 8, 3)
        cv.Resize(im_full, im_640, cv.CV_INTER_NN)
        im_640 = numpy.ascontiguousarray(cv.GetMat(im_640))
        im_full = numpy.ascontiguousarray(cv.GetMat(im_full))

        count = 0
        total_time = 0

        t0 = time.time()
        if opts.fullres:
            img_scan = im_full
        else:
            img_scan = im_640

        if pos is not None:
            (sw, sh) = cuav_util.image_shape(img_scan)
            mpp = cuav_util.meters_per_pixel(pos, C=C_params)
            if mpp is not None:
                scan_parms['MetersPerPixel'] = mpp * (w / float(sw))
            regions = scanner.scan(img_scan, scan_parms)
        else:
            regions = scanner.scan(img_scan)
        regions = cuav_region.RegionsConvert(regions,
                                             cuav_util.image_shape(img_scan),
                                             cuav_util.image_shape(im_full))
        count += 1
        t1 = time.time()

        frame_time = pos.time

        regions = cuav_region.filter_regions(im_full,
                                             regions,
                                             frame_time=frame_time,
                                             min_score=opts.minscore,
                                             filter_type=opts.filter_type)

        scan_count += 1

        mosaic.add_image(pos.time, f, pos)

        if pos and len(regions) > 0:
            joelog.add_regions(frame_time,
                               regions,
                               pos,
                               f,
                               width=w,
                               height=h,
                               altitude=opts.altitude)

        region_count += len(regions)

        if len(regions) > 0:
            composite = cuav_mosaic.CompositeThumbnail(
                cv.GetImage(cv.fromarray(im_full)), regions)
            thumbs = cuav_mosaic.ExtractThumbs(composite, len(regions))
            mosaic.add_regions(regions, thumbs, f, pos)

        if opts.view:
            img_view = img_scan
            (wview, hview) = cuav_util.image_shape(img_view)
            mat = cv.fromarray(img_view)
            for r in regions:
                r.draw_rectangle(mat, (255, 0, 0))
            cv.CvtColor(mat, mat, cv.CV_BGR2RGB)
            viewer.set_image(mat)
            viewer.set_title('Image: ' + os.path.basename(f))

        total_time += (t1 - t0)
        if t1 != t0:
            print('%s scan %.1f fps  %u regions [%u/%u]' %
                  (os.path.basename(f), count / total_time, region_count,
                   scan_count, num_files))