예제 #1
0
파일: camera.py 프로젝트: wuyou33/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>")
예제 #2
0
파일: camera.py 프로젝트: Digital8/mavelous
def view_thread():
    '''image viewing thread - this runs on the ground station'''
    import cuav_mosaic
    state = mpstate.camera_state

    bsend = block_xmit.BlockSender(state.gcs_view_port, state.bandwidth)

    view_window = False
    image_count = 0
    thumb_count = 0
    image_total_bytes = 0
    jpeg_total_bytes = 0
    thumb_total_bytes = 0
    region_count = 0
    mosaic = None
    view_dir = os.path.join(state.camera_dir, "view")
    thumb_dir = os.path.join(state.camera_dir, "thumb")
    cuav_util.mkdir_p(view_dir)
    cuav_util.mkdir_p(thumb_dir)

    img_window = mp_image.MPImage(title='Camera')

    mpstate.console.set_status('Images', 'Images %u' % image_count, row=6)
    mpstate.console.set_status('Lost', 'Lost %u' % 0, row=6)
    mpstate.console.set_status('Regions', 'Regions %u' % region_count, row=6)
    mpstate.console.set_status('JPGSize', 'JPGSize %.0f' % 0.0, row=6)
    mpstate.console.set_status('XMITQ', 'XMITQ %.0f' % 0.0, row=6)

    mpstate.console.set_status('Thumbs', 'Thumbs %u' % thumb_count, row=7)
    mpstate.console.set_status('ThumbSize', 'ThumbSize %.0f' % 0.0, row=7)
    mpstate.console.set_status('ImageSize', 'ImageSize %.0f' % 0.0, row=7)

    while not state.unload.wait(0.02):
        if state.viewing:
            bsend.tick(packet_count=1000)
            cv.WaitKey(1)
            if not view_window:
                view_window = True
                key = cv.WaitKey(1)
                mosaic = cuav_mosaic.Mosaic(slipmap=mpstate.map, lens=state.lens)
                if state.boundary is not None:
                    boundary = cuav_util.polygon_load(state.boundary)
                    mosaic.set_boundary(boundary)
            buf = bsend.recv(0)
            if buf is None:
                continue
            try:
                obj = cPickle.loads(str(buf))
                if obj == None:
                    continue
            except Exception as e:
                continue

            if isinstance(obj, ThumbPacket):
                # we've received a set of thumbnails from the plane for a positive hit
                thumb_total_bytes += len(buf)

                # save the thumbnails
                filename = '%s/v%s.jpg' % (thumb_dir, cuav_util.frame_time(obj.frame_time))
                chameleon.save_file(filename, obj.thumb)
                composite = cv.LoadImage(filename)
                thumbs = cuav_mosaic.ExtractThumbs(composite, len(obj.regions))

                # log the joe positions
                filename = '%s/v%s.jpg' % (view_dir, cuav_util.frame_time(obj.frame_time))
                pos = get_plane_position(obj.frame_time)
                log_joe_position(pos, obj.frame_time, obj.regions, filename)

                # update the mosaic and map
                mosaic.add_regions(obj.regions, thumbs, obj.latlon_list, filename, pos=pos)

                # update console display
                region_count += len(obj.regions)
                state.frame_loss = obj.frame_loss
                state.xmit_queue = obj.xmit_queue
                thumb_count += 1

                mpstate.console.set_status('Lost', 'Lost %u' % state.frame_loss)
                mpstate.console.set_status('Regions', 'Regions %u' % region_count)
                mpstate.console.set_status('XMITQ', 'XMITQ %.0f' % state.xmit_queue)
                mpstate.console.set_status('Thumbs', 'Thumbs %u' % thumb_count)
                mpstate.console.set_status('ThumbSize', 'ThumbSize %.0f' % (thumb_total_bytes/thumb_count))

            if isinstance(obj, ImagePacket):
                # we have an image from the plane
                image_total_bytes += len(buf)

                # save it to disk
                filename = '%s/v%s.jpg' % (view_dir, cuav_util.frame_time(obj.frame_time))
                chameleon.save_file(filename, obj.jpeg)
                img = cv.LoadImage(filename)
                    
                # work out where we were at the time
                try:
                    pos = state.mpos.position(obj.frame_time, 0)
                except mav_position.MavInterpolatorException, msg:
                    print msg
                    pos = None
                if pos:
                    mosaic.add_image(filename, img, pos)

                img = cv.LoadImage(filename)
                if img.width == 1280:
                    display_img = cv.CreateImage((640, 480), 8, 3)
                    cv.Resize(img, display_img)
                else:
                    display_img = img

                cv.ConvertScale(display_img, display_img, scale=state.brightness)
                img_window.set_image(display_img, bgr=True)

                # update console
                image_count += 1
                jpeg_total_bytes += len(obj.jpeg)
                state.jpeg_size = 0.95 * state.jpeg_size + 0.05 * len(obj.jpeg)
                mpstate.console.set_status('Images', 'Images %u' % image_count)
                mpstate.console.set_status('JPGSize', 'JPG Size %.0f' % (jpeg_total_bytes/image_count))
                mpstate.console.set_status('ImageSize', 'ImageSize %.0f' % (image_total_bytes/image_count))
                
        else:
            if view_window:
                view_window = False
예제 #3
0
파일: camera.py 프로젝트: tjhowse/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>")
예제 #4
0
파일: scantest.py 프로젝트: tjhowse/cuav
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")

    for f in files:
        frame_time = cuav_util.parse_frame_time(f)
        if mpos:
            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_full(im_8bit, im_full)
            im_640 = numpy.zeros((480, 640, 3), dtype="uint8")
            scanner.downsample(im_full, im_640)
        else:
            im_full = cv.LoadImage(f)
            im_640 = cv.CreateImage((640, 480), 8, 3)
            cv.Resize(im_full, im_640)
            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_full(im_full)
            else:
                regions = scanner.scan(img_scan)
            count += 1
        regions = cuav_region.RegionsConvert(regions)
        t1 = time.time()

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

        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, quality=opts.quality
            )
            chameleon.save_file("composite.jpg", composite)
            thumbs = cuav_mosaic.ExtractThumbs(cv.LoadImage("composite.jpg"), 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()
                if opts.fullres:
                    x1 *= 2
                    y1 *= 2
                    x2 *= 2
                    y2 *= 2
                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
        print ("%s scan %.1f fps  %u regions [%u/%u]" % (f, count / total_time, region_count, scan_count, num_files))
예제 #5
0
def cmd_camera(args):
    '''camera commands'''
    state = mpstate.camera_state
    if not args:
        print("usage: camera <start|stop|status|view|noview|gcs|brightness|capbrightness|boundary|bandwidth|bandwidth2|thumbsize|transmit|loss|save|minscore|altitude|send2>")
        return
    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 %u imgs  %u err %u scan  %u regions %.0f jsize %.0f xmitq %u/%u lst %u sq %.1f eff" % (
            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] == "gcs":
        if len(args) != 2:
            print("usage: camera gcs <IPADDRESS>")
            return
        state.gcs_address = args[1]
    elif args[0] == "brightness":
        if len(args) != 2:
            print("brightness=%f" % state.brightness)
        else:
            state.brightness = float(args[1])
    elif args[0] == "capbrightness":
        if len(args) != 2:
            print("capbrightness=%u" % state.capture_brightness)
        else:
            state.capture_brightness = int(args[1])
    elif args[0] == "gamma":
        if len(args) != 2:
            print("gamma=%u" % state.gamma)
        else:
            state.gamma = int(args[1])
    elif args[0] == "quality":
        if len(args) != 2:
            print("quality=%u" % state.quality)
        else:
            state.quality = int(args[1])
    elif args[0] == "thumbsize":
        if len(args) != 2:
            print("thumbsize=%u" % state.thumbsize)
        else:
            state.thumbsize = int(args[1])
    elif args[0] == "bandwidth":
        if len(args) != 2:
            print("bandwidth=%u" % state.bandwidth)
        else:
            state.bandwidth = int(args[1])
    elif args[0] == "bandwidth2":
        if len(args) != 2:
            print("bandwidth2=%u" % state.bandwidth2)
        else:
            state.bandwidth2 = int(args[1])
    elif args[0] == "loss":
        if len(args) != 2:
            print("packet_loss=%u" % state.packet_loss)
        else:
            state.packet_loss = int(args[1])
    elif args[0] == "save":
        if len(args) != 2:
            print("save_pgm=%s" % str(state.save_pgm))
        else:
            state.save_pgm = bool(int(args[1]))
    elif args[0] == "transmit":
        if len(args) != 2:
            print("transmit=%s" % str(state.transmit))
        else:
            state.transmit = bool(int(args[1]))
    elif args[0] == "send2":
        if len(args) != 2:
            print("send2=%s" % str(state.send2))
        else:
            state.send2 = bool(int(args[1]))
    elif args[0] == "minscore":
        if len(args) != 2:
            print("minscore=%u" % state.minscore)
        else:
            state.minscore = int(args[1])
    elif args[0] == "altitude":
        if len(args) != 2:
            print("altitude=%u" % state.altitude)
        else:
            state.altitude = int(args[1])
    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|gcs|brightness|capbrightness|boundary|bandwidth|bandwidth2|thumbsize|transmit|loss|save|minscore|altitude|send2>")
예제 #6
0
파일: camera.py 프로젝트: ulise75/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 %u imgs  %u err %u scan  %u regions %.0f jsize %.0f xmitq %u lst %u sq %.1f eff" % (
            state.capture_count, state.error_count, state.scan_count, state.region_count, 
            state.jpeg_size, state.xmit_queue, state.frame_loss, state.scan_queue.qsize(), state.efficiency))
    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] == "gcs":
        if len(args) != 2:
            print("usage: camera gcs <IPADDRESS>")
            return
        state.gcs_address = args[1]
    elif args[0] == "brightness":
        if len(args) != 2:
            print("brightness=%f" % state.brightness)
        else:
            state.brightness = float(args[1])
    elif args[0] == "capbrightness":
        if len(args) != 2:
            print("capbrightness=%u" % state.capture_brightness)
        else:
            state.capture_brightness = int(args[1])
    elif args[0] == "gamma":
        if len(args) != 2:
            print("gamma=%u" % state.gamma)
        else:
            state.gamma = int(args[1])
    elif args[0] == "quality":
        if len(args) != 2:
            print("quality=%u" % state.quality)
        else:
            state.quality = int(args[1])
    elif args[0] == "bandwidth":
        if len(args) != 2:
            print("bandwidth=%u" % state.bandwidth)
        else:
            state.bandwidth = int(args[1])
    elif args[0] == "loss":
        if len(args) != 2:
            print("packet_loss=%u" % state.packet_loss)
        else:
            state.packet_loss = int(args[1])
    elif args[0] == "save":
        if len(args) != 2:
            print("save_pgm=%s" % str(state.save_pgm))
        else:
            state.save_pgm = bool(int(args[1]))
    elif args[0] == "transmit":
        if len(args) != 2:
            print("transmit=%s" % str(state.transmit))
        else:
            state.transmit = bool(int(args[1]))
    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)
    else:
        print("usage: camera <start|stop|status|view|noview|gcs|brightness|capbrightness|boundary|bandwidth|transmit|loss|save>")
예제 #7
0
파일: camera.py 프로젝트: regaleagle/SQUID
def view_thread():
    '''image viewing thread - this runs on the ground station'''
    import cuav_mosaic
    state = mpstate.camera_state

    bsend = block_xmit.BlockSender(state.gcs_view_port, state.bandwidth)

    view_window = False
    image_count = 0
    thumb_count = 0
    image_total_bytes = 0
    jpeg_total_bytes = 0
    thumb_total_bytes = 0
    region_count = 0
    mosaic = None
    view_dir = os.path.join(state.camera_dir, "view")
    thumb_dir = os.path.join(state.camera_dir, "thumb")
    cuav_util.mkdir_p(view_dir)
    cuav_util.mkdir_p(thumb_dir)

    img_window = mp_image.MPImage(title='Camera')

    mpstate.console.set_status('Images', 'Images %u' % image_count, row=6)
    mpstate.console.set_status('Lost', 'Lost %u' % 0, row=6)
    mpstate.console.set_status('Regions', 'Regions %u' % region_count, row=6)
    mpstate.console.set_status('JPGSize', 'JPGSize %.0f' % 0.0, row=6)
    mpstate.console.set_status('XMITQ', 'XMITQ %.0f' % 0.0, row=6)

    mpstate.console.set_status('Thumbs', 'Thumbs %u' % thumb_count, row=7)
    mpstate.console.set_status('ThumbSize', 'ThumbSize %.0f' % 0.0, row=7)
    mpstate.console.set_status('ImageSize', 'ImageSize %.0f' % 0.0, row=7)

    while not state.unload.wait(0.02):
        if state.viewing:
            bsend.tick(packet_count=1000)
            cv.WaitKey(1)
            if not view_window:
                view_window = True
                key = cv.WaitKey(1)
                mosaic = cuav_mosaic.Mosaic(slipmap=mpstate.map,
                                            lens=state.lens)
                if state.boundary is not None:
                    boundary = cuav_util.polygon_load(state.boundary)
                    mosaic.set_boundary(boundary)
            buf = bsend.recv(0)
            if buf is None:
                continue
            try:
                obj = cPickle.loads(str(buf))
                if obj == None:
                    continue
            except Exception as e:
                continue

            if isinstance(obj, ThumbPacket):
                # we've received a set of thumbnails from the plane for a positive hit
                thumb_total_bytes += len(buf)

                # save the thumbnails
                filename = '%s/v%s.jpg' % (
                    thumb_dir, cuav_util.frame_time(obj.frame_time))
                chameleon.save_file(filename, obj.thumb)
                composite = cv.LoadImage(filename)
                thumbs = cuav_mosaic.ExtractThumbs(composite, len(obj.regions))

                # log the joe positions
                filename = '%s/v%s.jpg' % (
                    view_dir, cuav_util.frame_time(obj.frame_time))
                pos = get_plane_position(obj.frame_time)
                log_joe_position(pos, obj.frame_time, obj.regions, filename)

                # update the mosaic and map
                mosaic.add_regions(obj.regions,
                                   thumbs,
                                   obj.latlon_list,
                                   filename,
                                   pos=pos)

                # update console display
                region_count += len(obj.regions)
                state.frame_loss = obj.frame_loss
                state.xmit_queue = obj.xmit_queue
                thumb_count += 1

                mpstate.console.set_status('Lost',
                                           'Lost %u' % state.frame_loss)
                mpstate.console.set_status('Regions',
                                           'Regions %u' % region_count)
                mpstate.console.set_status('XMITQ',
                                           'XMITQ %.0f' % state.xmit_queue)
                mpstate.console.set_status('Thumbs', 'Thumbs %u' % thumb_count)
                mpstate.console.set_status(
                    'ThumbSize',
                    'ThumbSize %.0f' % (thumb_total_bytes / thumb_count))

            if isinstance(obj, ImagePacket):
                # we have an image from the plane
                image_total_bytes += len(buf)

                # save it to disk
                filename = '%s/v%s.jpg' % (
                    view_dir, cuav_util.frame_time(obj.frame_time))
                chameleon.save_file(filename, obj.jpeg)
                img = cv.LoadImage(filename)

                # work out where we were at the time
                try:
                    pos = state.mpos.position(obj.frame_time, 0)
                except mav_position.MavInterpolatorException, msg:
                    print msg
                    pos = None
                if pos:
                    mosaic.add_image(filename, img, pos)

                img = cv.LoadImage(filename)
                if img.width == 1280:
                    display_img = cv.CreateImage((640, 480), 8, 3)
                    cv.Resize(img, display_img)
                else:
                    display_img = img

                cv.ConvertScale(display_img,
                                display_img,
                                scale=state.brightness)
                img_window.set_image(display_img, bgr=True)

                # update console
                image_count += 1
                jpeg_total_bytes += len(obj.jpeg)
                state.jpeg_size = 0.95 * state.jpeg_size + 0.05 * len(obj.jpeg)
                mpstate.console.set_status('Images', 'Images %u' % image_count)
                mpstate.console.set_status(
                    'JPGSize',
                    'JPG Size %.0f' % (jpeg_total_bytes / image_count))
                mpstate.console.set_status(
                    'ImageSize',
                    'ImageSize %.0f' % (image_total_bytes / image_count))

        else:
            if view_window:
                view_window = False