Пример #1
0
def test_CompositeThumbnail():
    regions = []
    regions.append(cuav_region.Region(1020, 658, 1050, 678, (30, 30), scan_score=20))
    regions.append(cuav_region.Region(30, 54, 50, 74, (20, 20), scan_score=15))
    regions.append(cuav_region.Region(60, 24, 170, 134, (110, 110), scan_score=0))
    im_orig = cv2.imread(os.path.join(os.getcwd(), 'tests', 'testdata', 'test-8bit.png'))
    composite = cuav_region.CompositeThumbnail(im_orig, regions)
    assert cuav_util.image_shape(composite) == (300, 100)
Пример #2
0
    def scan_threadfunc(self):
        '''image scanning thread'''
        while not self.unload_event.wait(0.05):
            if self.scan_queue.empty():
                continue
            (frame_time, im) = self.scan_queue.get()
            scan_parms = {}
            for name in self.image_settings.list():
                scan_parms[name] = self.image_settings.get(name)
            scan_parms['BlueEmphasis'] = float(
                self.camera_settings.blue_emphasis)

            if self.terrain_alt is not None:
                altitude = self.terrain_alt
                if altitude < self.camera_settings.minalt:
                    altitude = self.camera_settings.minalt
                scan_parms['MetersPerPixel'] = cuav_util.pixel_width(
                    altitude, self.c_params.xresolution, self.c_params.lens,
                    self.c_params.sensorwidth)

            t1 = time.time()
            try:
                img_scan = cv2.imread(im, -1)
            except Exception:
                continue
            if img_scan is None:
                continue
            (h, w) = img_scan.shape[:2]
            if self.camera_settings.rotate180:
                M = cv2.getRotationMatrix2D(center, angle180, scale)
                img_scan = cv2.warpAffine(img_scan, M, (w, h))
            im_numpy = numpy.ascontiguousarray(img_scan)
            regions = scanner.scan(im_numpy, scan_parms)
            regions = cuav_region.RegionsConvert(
                regions, cuav_util.image_shape(img_scan),
                cuav_util.image_shape(img_scan))
            t2 = time.time()
            self.scan_fps = 1.0 / (t2 - t1)
            self.scan_count += 1

            regions = cuav_region.filter_regions(
                img_scan,
                regions,
                min_score=self.camera_settings.minscore,
                filter_type=self.camera_settings.filter_type)
            self.region_count += len(regions)

            # possibly send a preview image
            self.send_preview(img_scan)

            if self.camera_settings.roll_stabilised:
                roll = 0
            else:
                roll = None
            pos = self.get_plane_position(frame_time, roll=roll)
            if pos is not None:
                self.posmapping[str(frame_time)] = pos

            # this adds the latlon field to the regions (georeferencing)
            for r in regions:
                r.latlon = cuav_util.gps_position_from_image_region(
                    r, pos, w, h, altitude=None, C=self.c_params)

            if self.joelog:
                self.log_joe_position(pos, frame_time, regions)

            # filter out any regions outside the target radius
            if self.camera_settings.target_radius > 0 and pos is not None:
                regions = cuav_region.filter_radius(
                    regions, (self.camera_settings.target_latitude,
                              self.camera_settings.target_longitude),
                    self.camera_settings.target_radius)

            # filter out any regions outside the boundary
            if self.boundary_polygon:
                regions = cuav_region.filter_boundary(regions,
                                                      self.boundary_polygon,
                                                      pos)

            #filter by minscore
            regions = cuav_region.filter_regions(
                img_scan,
                regions,
                min_score=self.camera_settings.minscore,
                filter_type=self.camera_settings.filter_type)
            high_score = 1
            for r in regions:
                if r.score > high_score:
                    high_score = r.score

            if len(regions) > 0 and pos is not None:
                for r in regions:
                    self.lz.checkaddregion(r, pos)
                try:
                    lzresult = self.lz.calclandingzone()
                except Exception as ex:
                    print("calclandingzone failed: ", ex)
                    continue
                if lzresult:
                    self.transmit_queue.put((lzresult, 100000, None))
                    if self.msend:
                        self.transmit_queue.put((lzresult, 100000, 'msend'))

            if len(regions) > 0 and self.camera_settings.transmit:
                # send a region message with thumbnails to the ground station
                thumb_img = cuav_region.CompositeThumbnail(
                    img_scan,
                    regions,
                    thumb_size=self.camera_settings.thumbsize)
                encode_param = [int(cv2.IMWRITE_JPEG_QUALITY), 90]
                (result, thumb) = cv2.imencode('.jpg', thumb_img, encode_param)
                pkt = cuav_command.ThumbPacket(frame_time, regions, thumb, pos)

                if self.transmit_queue.qsize() < 100:
                    self.transmit_queue.put((pkt, None, None))
                    if self.msend is not None and high_score >= self.camera_settings.m_minscore:
                        self.transmit_queue.put((pkt, None, 'msend'))
                else:
                    self.send_message("Warning: image Tx queue too long")
                    print("Warning: image Tx queue too long")
Пример #3
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))
Пример #4
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', 'jpeg', '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')
    if args.vehicle_type == "Copter":
        icon = slipmap.icon('redcopter.png')
    else:
        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)
    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)
    else:
        kmzpos = None

    if args.triggerlog:
        triggerpos = mav_position.TriggerPosition(args.triggerlog)
    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)
    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)

    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('pitch_stabilised', bool, args.pitch_stabilised,
                  'Pitch Stabilised'),
        MPSetting('roll_offset', float, args.roll_offset, 'Roll Offset'),
        MPSetting('pitch_offset', float, args.pitch_offset, 'Pitch Offset'),
        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, False, 'rotate180'),
        MPSetting('showlz', bool, args.showlz,
                  'Show calculated landing zone from regions'),
        MPSetting(
            'filter_type', str, 'simple', 'Filter Type', choice=['simple']),
        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('map_thumbsize',
                  int,
                  args.map_thumbsize,
                  'Map 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.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),
        MPSetting('MinRegionSize',
                  float,
                  0.2,
                  range=(0, 100),
                  increment=0.05,
                  digits=2),
        MPSetting('MaxRegionSize',
                  float,
                  1.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,
                                map_thumb_size=args.map_thumbsize)

    joelog = cuav_joe.JoeLog(None)

    lz = cuav_landingregion.LandingZone()

    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
            if camera_settings.pitch_stabilised:
                pitch = 0
            else:
                pitch = None
            try:
                pos = mpos.position(frame_time,
                                    roll=roll,
                                    pitch=pitch,
                                    roll_offset=camera_settings.roll_offset,
                                    pitch_offset=camera_settings.pitch_offset)
            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 vehicle 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)
        im_orig = cv2.imread(f)

        if im_orig is None:
            continue
        (w, h) = cuav_util.image_shape(im_orig)

        if args.downsample:
            im_full = cv2.resize(im_orig, (0, 0), fx=0.5, fy=0.5)
        else:
            im_full = im_orig

        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,
            min_score=camera_settings.minscore,
            filter_type=camera_settings.filter_type)

        scan_count += 1

        if pos and len(regions) > 0:
            joelog.add_regions(frame_time, regions, pos, f)

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

        if camera_settings.showlz:
            for r in regions:
                if r.score >= camera_settings.minscore and pos is not None:
                    lz.checkaddregion(r, pos)
            #if lz.landingzoneconfidence and lz.landingzoneconfidence < 20:
            #  print("Refining LZ")
            lzresult = lz.calclandingzone()
            if lzresult is not None:
                slipmap.add_object(
                    mp_slipmap.SlipCircle('LZ',
                                          'LZ',
                                          lzresult.latlon,
                                          lzresult.maxrange,
                                          linewidth=3,
                                          color=(0, 255, 0)))
                slipmap.add_object(
                    mp_slipmap.SlipCircle('LZMid',
                                          'LZMid',
                                          lzresult.latlon,
                                          2.0,
                                          linewidth=3,
                                          color=(0, 255, 0)))

        region_count += len(regions)

        if len(regions) > 0:
            composite = cuav_region.CompositeThumbnail(im_full, regions)
            thumbs = cuav_mosaic.ExtractThumbs(composite, len(regions))
            thumbsRGB = []

            #colour space conversion
            for thumb in thumbs:
                thumbsRGB.append(cv2.cvtColor(thumb, cv2.COLOR_BGR2RGB))
            mosaic.add_regions(regions, thumbsRGB, f, pos)

        if args.view:
            img_view = img_scan
            (wview, hview) = cuav_util.image_shape(img_view)
            for r in regions:
                r.draw_rectangle(img_view, (255, 0, 0))
            #cv.CvtColor(mat, mat, cv.CV_BGR2RGB)
            img_view = cv2.cvtColor(img_view, cv2.COLOR_BGR2RGB)
            viewer.set_image(img_view)
            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))
        #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)
Пример #5
0
def test_Mosaic():
    #slipmap = mp_slipmap.MPSlipMap(service='GoogleSat', elevation=True, title='Map')
    #mocked_slipmap.return_value = 1
    #monkeypatch.setattr('slipmap', lambda x: 1)
    mocked_slipmap = mock.MagicMock(return_value=1)
    C_params = CameraParams(lens=4.0, sensorwidth=5.0, xresolution=1280, yresolution=960)
    mosaic = cuav_mosaic.Mosaic(mocked_slipmap, C=C_params)
    mosaic.set_mosaic_size((200, 200))
    assert mosaic.mosaic.shape == (175, 175, 3)
    
    f = os.path.join(os.getcwd(), 'tests', 'testdata', 'raw2016111223465120Z.png')
    img = cv2.imread(f)
    pos = mav_position.MavPosition(-30, 145, 34.56, 20, -56.67, 345, frame_time=1478994408.76)
    regions = []
    regions.append(cuav_region.Region(1020, 658, 1050, 678, (30, 30), scan_score=20))
    regions.append(cuav_region.Region(30, 54, 50, 74, (20, 20), scan_score=15))
    regions.append(cuav_region.Region(30, 54, 55, 79, (25, 25), scan_score=10))
    for i in range(40):
        regions.append(cuav_region.Region(200, 600, 220, 620, (20, 20), scan_score=45))
    composite = cuav_region.CompositeThumbnail(img, regions)
    thumbs = cuav_mosaic.ExtractThumbs(composite, len(regions))
    mosaic.add_regions(regions, thumbs, f, pos)
    mosaic.add_image(1478994408.76, f, pos)
    
    mosaic.show_region(0)

    mosaic.view_imagefile(f)
    
    
    assert mosaic.find_image_idx(f) == 0
    mosaic.view_imagefile_by_idx(0)
    
    mocked_key = mock.MagicMock(return_value=1)
    mocked_key.objkey = "region 1"
    assert mosaic.show_selected(mocked_key) == True
    
    mosaic.show_closest((-30, 145), mocked_key)
    
    mosaic.view_image.terminate()
    
    #mosaic.map_menu_callback
    
    #mosaic.map_callback
    
    OBC_boundary = cuav_util.polygon_load(os.path.join(os.getcwd(), 'tests', 'testdata', 'OBC_boundary.txt'))
    mosaic.set_boundary(OBC_boundary)
    
    mosaic.change_page(1)
    mosaic.hide_page()
    assert len(mosaic.regions_sorted) == 25
    mosaic.unhide_all()
    assert len(mosaic.regions_sorted) == 43
    
    for i in ['Score', 'ScoreReverse', 'Distinctiveness', 'Whiteness', 'Time']:
        mosaic.sort_type = i
        mosaic.re_sort()
    
    #mosaic.menu_event
    
    assert mosaic.started() == True
    
    mosaic.popup_show_image(mosaic.regions[2])
    
    mosaic.popup_fetch_image(mosaic.regions[2], 'fetchImageFull')
    
    assert len(mosaic.get_image_requests()) == 1
    
    mosaic.view_image.terminate()
    
    #mosaic.menu_event_view
    
    mocked_pos = mock.MagicMock(return_value=1)
    mocked_pos.x = 10
    mocked_pos.y = 10
    assert mosaic.pos_to_region(mocked_pos) == mosaic.regions[0]
    
    assert mosaic.objkey_to_region(mocked_key) == mosaic.regions[1]
    
    #mosaic.mouse_event
    
    #mosaic.mouse_event_view
    
    mosaic.key_event(1)
    
    assert mosaic.region_on_page(2, 0) == True
    assert mosaic.region_on_page(2000, 20) == False
    
    mosaic.mouse_region = mosaic.regions[0]
    mosaic.display_mosaic_region(0)
    
    mosaic.redisplay_mosaic()
    
    assert mosaic.make_thumb(img, regions[0], 8).shape == (8, 8, 3)
    assert mosaic.make_thumb(img, regions[0], 30).shape == (30, 30, 3)
    
    mosaic.tag_image(1478994408.76)
    
    #mosaic.check_events
    
    mosaic.image_mosaic.terminate()