コード例 #1
0
ファイル: test_cuav_region.py プロジェクト: stephendade/cuav
def test_filter_boundary():
    OBC_boundary = cuav_util.polygon_load(os.path.join(os.getcwd(), 'tests', 'testdata', 'OBC_boundary.txt'))
    regions = []
    regOne = cuav_region.Region(1020, 658, 1050, 678, (30, 30))
    regOne.latlon=(-26.6398870, 151.8220000)
    regOne.score = 20
    regions.append(regOne)
    regTwo = cuav_region.Region(1020, 658, 1050, 678, (30, 30))
    regTwo.score = 32
    regTwo.latlon=(-26.6418700, 151.8709260)
    regions.append(regTwo)
    pos = mav_position.MavPosition(-30, 145, 34.56, 20, -56.67, 345, frame_time=None)
    ret = cuav_region.filter_boundary(regions, OBC_boundary, pos)
    assert len(ret) == 2
    assert ret[0].score == 0
    assert ret[1].score == 32
コード例 #2
0
ファイル: test_cuav_region.py プロジェクト: tajisoft/cuav
def test_filter_boundary():
    OBC_boundary = cuav_util.polygon_load(os.path.join(os.getcwd(), 'tests', 'testdata', 'OBC_boundary.txt'))
    regions = []
    regOne = cuav_region.Region(1020, 658, 1050, 678, (30, 30))
    regOne.latlon=(-26.6398870, 151.8220000)
    regOne.score = 20
    regions.append(regOne)
    regTwo = cuav_region.Region(1020, 658, 1050, 678, (30, 30))
    regTwo.score = 32
    regTwo.latlon=(-26.6418700, 151.8709260)
    regions.append(regTwo)
    pos = mav_position.MavPosition(-30, 145, 34.56, 20, -56.67, 345, frame_time=None)
    ret = cuav_region.filter_boundary(regions, OBC_boundary, pos)
    assert len(ret) == 2
    assert ret[0].score == 0
    assert ret[1].score == 32
コード例 #3
0
 def cmd_camera(self, args):
     '''camera commands'''
     usage = "usage: camera <status|view|boundary|set>"
     if len(args) == 0:
         print(usage)
         return
     elif args[0] == "status":
         #print("Cap imgs: regions:%u" % (self.region_count))
         #request status update from air module
         pkt = cuav_command.CommandPacket('status')
         self.send_packet(pkt)
         pkt = cuav_command.CommandPacket('queue')
         self.send_packet(pkt)
     elif args[0] == "view":
         #check cam params
         if not self.check_camera_parms():
             print("Error - incorrect camera params")
             return
         if self.mpstate.map is None:
             print("Error - load map module first")
             return
         if not self.viewing:
             print("Starting image viewer")
         self.joelog = cuav_joe.JoeLog(os.path.join(self.camera_dir,
                                                    'joe_ground.log'),
                                       append=self.continue_mode)
         if self.view_thread is None:
             self.view_thread = self.start_thread(self.view_threadfunc)
         self.viewing = True
     elif args[0] == "set":
         self.camera_settings.command(args[1:])
     elif args[0] == "boundary":
         if len(args) != 2:
             print("boundary=%s" % self.boundary)
         else:
             self.boundary = args[1]
             self.boundary_polygon = cuav_util.polygon_load(self.boundary)
             if self.mpstate.map is not None:
                 self.mpstate.map.add_object(
                     mp_slipmap.SlipPolygon('boundary',
                                            self.boundary_polygon,
                                            layer=1,
                                            linewidth=2,
                                            colour=(0, 0, 255)))
コード例 #4
0
ファイル: camera_ground.py プロジェクト: stephendade/cuav
 def cmd_camera(self, args):
     '''camera commands'''
     usage = "usage: camera <status|view|boundary|set>"
     if len(args) == 0:
         print(usage)
         return
     elif args[0] == "status":
         #print("Cap imgs: regions:%u" % (self.region_count))
         #request status update from air module
         pkt = cuav_command.CommandPacket('status')
         self.send_packet(pkt)
         pkt = cuav_command.CommandPacket('queue')
         self.send_packet(pkt)
     elif args[0] == "view":
         #check cam params
         if not self.check_camera_parms():
             print("Error - incorrect camera params")
             return
         if self.mpstate.map is None:
             print("Error - load map module first")
             return
         if not self.viewing:
             print("Starting image viewer")
         self.joelog = cuav_joe.JoeLog(os.path.join(self.camera_dir,
                                                    'joe_ground.log'),
                                       append=self.continue_mode)
         if self.view_thread is None:
             self.view_thread = self.start_thread(self.view_threadfunc)
         self.viewing = True
     elif args[0] == "set":
         self.camera_settings.command(args[1:])
     elif args[0] == "boundary":
         if len(args) != 2:
             print("boundary=%s" % self.boundary)
         else:
             self.boundary = args[1]
             self.boundary_polygon = cuav_util.polygon_load(self.boundary)
             if self.mpstate.map is not None:
                 self.mpstate.map.add_object(mp_slipmap.SlipPolygon('boundary',
                                                                    self.boundary_polygon,
                                                                    layer=1, linewidth=2,
                                                                    colour=(0, 0, 255)))
コード例 #5
0
ファイル: camera.py プロジェクト: qtonthat/MAVProxy
def cmd_camera(args):
    """camera commands"""
    state = mpstate.camera_state
    if args[0] == "start":
        state.capture_count = 0
        state.error_count = 0
        state.error_msg = None
        state.running = True
        if state.capture_thread is None:
            state.capture_thread = start_thread(capture_thread)
            state.save_thread = start_thread(save_thread)
            state.scan_thread1 = start_thread(scan_thread)
            state.scan_thread2 = start_thread(scan_thread)
            state.transmit_thread = start_thread(transmit_thread)
        print ("started camera running")
    elif args[0] == "stop":
        state.running = False
        print ("stopped camera capture")
    elif args[0] == "status":
        print (
            "Cap imgs:%u err:%u scan:%u regions:%u jsize:%.0f xmitq:%u/%u lst:%u sq:%.1f eff:%.2f"
            % (
                state.capture_count,
                state.error_count,
                state.scan_count,
                state.region_count,
                state.jpeg_size,
                state.xmit_queue,
                state.xmit_queue2,
                state.frame_loss,
                state.scan_queue.qsize(),
                state.efficiency,
            )
        )
        if state.bsend2:
            state.bsend2.report(detailed=False)
    elif args[0] == "queue":
        print (
            "scan %u  save %u  transmit %u  eff %.1f  bw %.1f  rtt %.1f"
            % (
                state.scan_queue.qsize(),
                state.save_queue.qsize(),
                state.transmit_queue.qsize(),
                state.efficiency,
                state.bandwidth_used,
                state.rtt_estimate,
            )
        )
    elif args[0] == "view":
        if mpstate.map is None:
            print ("Please load map module first")
            return
        if not state.viewing:
            print ("Starting image viewer")
        if state.view_thread is None:
            state.view_thread = start_thread(view_thread)
        state.viewing = True
    elif args[0] == "noview":
        if state.viewing:
            print ("Stopping image viewer")
        state.viewing = False
    elif args[0] == "set":
        if len(args) < 3:
            state.settings.show_all()
        else:
            state.settings.set(args[1], args[2])
    elif args[0] == "boundary":
        if len(args) != 2:
            print ("boundary=%s" % state.boundary)
        else:
            state.boundary = args[1]
            state.boundary_polygon = cuav_util.polygon_load(state.boundary)
            if mpstate.map is not None:
                mpstate.map.add_object(
                    mp_slipmap.SlipPolygon("boundary", state.boundary_polygon, layer=1, linewidth=2, colour=(0, 0, 255))
                )

    else:
        print ("usage: camera <start|stop|status|view|noview|boundary|set>")
コード例 #6
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))
コード例 #7
0
ファイル: camera.py プロジェクト: minhduccse/MAVProxy
def cmd_camera(args):
    '''camera commands'''
    state = mpstate.camera_state
    if args[0] == "start":
        state.capture_count = 0
        state.error_count = 0
        state.error_msg = None
        state.running = True
        if state.capture_thread is None:
            state.capture_thread = start_thread(capture_thread)
            state.save_thread = start_thread(save_thread)
            state.scan_thread1 = start_thread(scan_thread)
            state.scan_thread2 = start_thread(scan_thread)
            state.transmit_thread = start_thread(transmit_thread)
        print("started camera running")
    elif args[0] == "stop":
        state.running = False
        print("stopped camera capture")
    elif args[0] == "status":
        print("Cap imgs:%u err:%u scan:%u regions:%u jsize:%.0f xmitq:%u/%u lst:%u sq:%.1f eff:%.2f" % (
            state.capture_count, state.error_count, state.scan_count, state.region_count, 
            state.jpeg_size,
            state.xmit_queue, state.xmit_queue2, state.frame_loss, state.scan_queue.qsize(), state.efficiency))
        if state.bsend2:
            state.bsend2.report(detailed=False)
    elif args[0] == "queue":
        print("scan %u  save %u  transmit %u  eff %.1f  bw %.1f  rtt %.1f" % (
                state.scan_queue.qsize(),
                state.save_queue.qsize(),
                state.transmit_queue.qsize(),
                state.efficiency,
                state.bandwidth_used,
                state.rtt_estimate))
    elif args[0] == "view":
        if mpstate.map is None:
            print("Please load map module first")
            return
        if not state.viewing:
            print("Starting image viewer")
        if state.view_thread is None:
            state.view_thread = start_thread(view_thread)
        state.viewing = True
    elif args[0] == "noview":
        if state.viewing:
            print("Stopping image viewer")
        state.viewing = False
    elif args[0] == "set":
        if len(args) < 3:
            state.settings.show_all()
        else:
            state.settings.set(args[1], args[2])
    elif args[0] == "boundary":
        if len(args) != 2:
            print("boundary=%s" % state.boundary)
        else:
            state.boundary = args[1]
            state.boundary_polygon = cuav_util.polygon_load(state.boundary)
            if mpstate.map is not None:
                mpstate.map.add_object(mp_slipmap.SlipPolygon('boundary', state.boundary_polygon, layer=1, linewidth=2, colour=(0,0,255)))
                
    else:
        print("usage: camera <start|stop|status|view|noview|boundary|set>")
コード例 #8
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))
コード例 #9
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()