Пример #1
0
    def test_sparse_stereo(self):
        left = Image.new("L", (640, 480))
        circle(left, 320, 200, 4, 255)

        for disparity in range(20):
            right = Image.new("L", (640, 480))
            circle(right, 320 - disparity, 200, 4, 255)
            sf = SparseStereoFrame(left, right)
            self.assertAlmostEqual(sf.lookup_disparity(320, 200), disparity, 0)
Пример #2
0
  def test_sparse_stereo(self):
    left = Image.new("L", (640,480))
    circle(left, 320, 200, 4, 255)

    for disparity in range(20):
      right = Image.new("L", (640,480))
      circle(right, 320 - disparity, 200, 4, 255)
      sf = SparseStereoFrame(left, right)
      self.assertAlmostEqual(sf.lookup_disparity(320,200), disparity, 0)
Пример #3
0
    def display_array(self, iar):
        diag = ""
        af = None
        if self.vo:
            if not self.started:
                self.started = time.time()
            if 0:
                time.sleep(0.028)
            else:
                imgR = imgAdapted(iar.images[0])
                imgL = imgAdapted(iar.images[1])
                af = SparseStereoFrame(imgL, imgR)
                if 1:
                    pose = self.vo.handle_frame(af)
                    diag = "%d inliers, moved %.1f" % (self.vo.inl,
                                                       pose.distance())
            if (self.frame % 1) == 0:
                took = time.time() - self.started
                print "%4d: %5.1f [%f fps]" % (self.frame, took,
                                               self.frame / took), diag
            self.frame += 1

        #print "got message", len(iar.images)
        #print iar.images[0].width
        if SEE:
            right = ut.ros2cv(iar.images[0])
            left = ut.ros2cv(iar.images[1])
            hg.cvShowImage('channel L', left)
            hg.cvShowImage('channel R', right)
            hg.cvWaitKey(5)
Пример #4
0
 def handle_raw_stereo(self, msg):
     size = (msg.left_info.width, msg.left_info.height)
     if self.vo == None:
         cam = camera.StereoCamera(msg.right_info)
         self.vo = VisualOdometer(cam,
                                  scavenge=False,
                                  inlier_error_threshold=3.0,
                                  sba=None,
                                  inlier_thresh=100,
                                  position_keypoint_thresh=0.2,
                                  angle_keypoint_thresh=0.15)
     pair = [imgAdapted(i, size) for i in [msg.left_image, msg.right_image]]
     af = SparseStereoFrame(pair[0],
                            pair[1],
                            feature_detector=self.fd,
                            descriptor_scheme=self.ds)
     pose = self.vo.handle_frame(af)
     p = deprecated_msgs.msg.VOPose()
     p.inliers = self.vo.inl
     # XXX - remove after camera sets frame_id
     p.header = roslib.msg.Header(0, msg.header.stamp, "stereo_link")
     p.pose = geometry_msgs.msg.Pose(
         geometry_msgs.msg.Point(*pose.xform(0, 0, 0)),
         geometry_msgs.msg.Quaternion(*pose.quaternion()))
     self.pub_vo.publish(p)
Пример #5
0
  def test_stereo(self):
    cam = camera.VidereCamera(open("wallcal.ini").read())
    #lf = Image.open("wallcal-L.bmp").convert("L")
    #rf = Image.open("wallcal-R.bmp").convert("L")
    for offset in [ 1, 10, 10.25, 10.5, 10.75, 11, 63]:
      lf = Image.open("snap.png").convert("L")
      rf = Image.open("snap.png").convert("L")
      rf = rf.resize((16 * 640, 480))
      rf = ImageChops.offset(rf, -int(offset * 16), 0)
      rf = rf.resize((640,480), Image.ANTIALIAS)
      for gradient in [ False, True ]:
        af = SparseStereoFrame(lf, rf, gradient)
        vo = VisualOdometer(cam)
        vo.find_keypoints(af)
        vo.find_disparities(af)
        error = offset - sum([d for (x,y,d) in af.kp]) / len(af.kp)
        self.assert_(abs(error) < 0.25) 

    if 0:
      scribble = Image.merge("RGB", (lf,rf,Image.new("L", lf.size))).resize((1280,960))
      #scribble = Image.merge("RGB", (Image.fromstring("L", lf.size, af0.lgrad),Image.fromstring("L", lf.size, af0.rgrad),Image.new("L", lf.size))).resize((1280,960))
      draw = ImageDraw.Draw(scribble)
      for (x,y,d) in af0.kp:
        draw.line([ (2*x,2*y), (2*x-2*d,2*y) ], fill = (255,255,255))
      for (x,y,d) in af1.kp:
        draw.line([ (2*x,2*y+1), (2*x-2*d,2*y+1) ], fill = (0,0,255))
Пример #6
0
    def xtest_image_pan(self):
        cam = camera.Camera((1.0, 1.0, 89.23, 320., 320., 240.0))
        vo = VisualOdometer(cam)
        prev_af = None
        pose = None
        im = Image.open("img1.pgm")
        for x in [0,
                  5]:  # range(0,100,10) + list(reversed(range(0, 100, 10))):
            lf = im.crop((x, 0, x + 640, 480))
            rf = im.crop((x, 0, x + 640, 480))
            af = SparseStereoFrame(lf, rf)

            vo.find_keypoints(af)

            vo.find_disparities(af)
            vo.collect_descriptors(af)

            if prev_af:
                pairs = vo.temporal_match(prev_af, af)
                pose = vo.solve(prev_af.kp, af.kp, pairs)
                for i in range(10):
                    old = prev_af.kp[pairs[i][0]]
                    new = af.kp[pairs[i][1]]
                    print old, new, new[0] - old[0]
            prev_af = af
            print "frame", x, "has", len(af.kp), "keypoints", pose
Пример #7
0
    def xtest_smoke(self):
        cam = camera.Camera((389.0, 389.0, 89.23, 323.42, 323.42, 274.95))
        vo = VisualOdometer(cam)
        vo.reset_timers()
        dir = "/u/konolige/vslam/data/indoor1/"

        trail = []
        prev_scale = None

        schedule = [(f + 1000)
                    for f in (range(0, 100) + range(100, 0, -1) + [0] * 10)]
        schedule = range(1507)
        schedule = range(30)
        for f in schedule:
            lf = Image.open("%s/left-%04d.ppm" % (dir, f))
            rf = Image.open("%s/right-%04d.ppm" % (dir, f))
            lf.load()
            rf.load()
            af = SparseStereoFrame(lf, rf)

            vo.handle_frame(af)
            print f, vo.inl
            trail.append(numpy.array(vo.pose.M[0:3, 3].T)[0])

        def d(a, b):
            d = a - b
            return sqrt(numpy.dot(d, d.conj()))

        print "covered   ", sum([d(a, b) for (a, b) in zip(trail, trail[1:])])
        print "from start", d(trail[0], trail[-1]), trail[0] - trail[-1]

        vo.summarize_timers()
        print vo.log_keyframes
Пример #8
0
    def xtest_smoke_bag(self):
        import rosrecord
        import visualize

        class imgAdapted:
            def __init__(self, i):
                self.i = i
                self.size = (i.width, i.height)

            def tostring(self):
                return self.i.data

        cam = None
        filename = "/u/prdata/videre-bags/loop1-mono.bag"
        filename = "/u/prdata/videre-bags/vo1.bag"
        framecounter = 0
        for topic, msg in rosrecord.logplayer(filename):
            print framecounter
            if rospy.is_shutdown():
                break
            #print topic,msg
            if topic == "/videre/cal_params" and not cam:
                cam = camera.VidereCamera(msg.data)
                vo = VisualOdometer(cam)
            if cam and topic == "/videre/images":
                if -1 <= framecounter and framecounter < 360:
                    imgR = imgAdapted(msg.images[0])
                    imgL = imgAdapted(msg.images[1])
                    af = SparseStereoFrame(imgL, imgR)
                    pose = vo.handle_frame(af)
                    visualize.viz(vo, af)
                framecounter += 1
        print "distance from start:", vo.pose.distance()
        vo.summarize_timers()
Пример #9
0
def load_from_bag(filename, selected_frames):
    cam = None
    framecounter = 0
    afs = {}
    for topic, msg in rosrecord.logplayer(filename):
        if rospy.is_shutdown():
            break

        if topic == "/videre/cal_params" and not cam:
            cam = camera.VidereCamera(msg.data)

        if cam and topic == "/videre/images":
            print "frame", framecounter
            if framecounter in selected_frames:

                def imgAdapted(msg_img):
                    return Image.fromstring("L",
                                            (msg_img.width, msg_img.height),
                                            msg_img.data)

                imgR = imgAdapted(msg.images[0])
                imgL = imgAdapted(msg.images[1])
                afs[framecounter] = SparseStereoFrame(imgL, imgR)
                if framecounter == max(selected_frames):
                    break
            framecounter += 1
    return (cam, afs)
Пример #10
0
 def handle_array(self, iar):
   if self.vo:
     t0 = time.time()
     self.intervals.append(t0)
     if (self.modulo % self.decimate) == 0:
       imgR = imgAdapted(iar.images[0])
       imgL = imgAdapted(iar.images[1])
       af = SparseStereoFrame(imgL, imgR)
       if 1:
         pose = self.vo.handle_frame(af)
       else:
         pose = Pose()
       #print self.vo.num_frames, pose.xform(0,0,0), pose.quaternion()
       p = VOPose()
       p.inliers = self.vo.inl
       # XXX - remove after camera sets frame_id
       p.header = rostools.msg.Header(0, iar.header.stamp, "stereo_link")
       p.pose = stdmsg.Pose(stdmsg.Point(*pose.xform(0,0,0)), stdmsg.Quaternion(*pose.quaternion()))
       self.pub_vo.publish(p)
     self.modulo += 1
     self.took.append(time.time() - t0)
     if (len(self.took) % 100) == 0:
       print len(self.took)
    def frame(self, imarray):

        # No calibration params yet.
        if not self.vo:
            return

        if self.seq > 10000:
            sys.exit()
        if DEBUG:
            print ""
            print ""
            print "Frame ", self.seq
            print ""
            print ""

        im = imarray.images[1]
        im_r = imarray.images[0]
        if im.colorspace == "mono8":
            im_py = Image.fromstring("L", (im.width, im.height), im.data)
            im_r_py = Image.fromstring("L", (im_r.width, im_r.height),
                                       im_r.data)
        elif im.colorspace == "rgb24":
            use_color = True
            im_col_py = Image.fromstring("RGB", (im.width, im.height), im.data)
            im_py = im_col_py.convert("L")
            im_r_py = Image.fromstring("RGB", (im_r.width, im_r.height),
                                       im_r.data)
            im_r_py = im_r_py.convert("L")
        else:
            print "Unknown colorspace"
            return

        # Detect faces on the first frame
        if not self.current_keyframes:
            self.faces = self.p.detectAllFaces(im_py.tostring(), im.width,
                                               im.height, self.cascade_file,
                                               1.0, None, None, True)
            if DEBUG:
                print "Faces ", self.faces

        sparse_pred_list = []
        sparse_pred_list_2d = []
        old_rect = [0, 0, 0, 0]
        ia = SparseStereoFrame(im_py, im_r_py)
        ia.matches = []
        ia.desc_diffs = []
        ia.good_matches = []

        # Track each face
        iface = -1
        for face in self.faces:

            iface += 1

            (x, y, w, h) = copy.copy(self.faces[iface])
            if DEBUG:
                print "A face ", (x, y, w, h)

            (old_center, old_diff) = self.rect_to_center_diff((x, y, w, h))

            if self.face_centers_3d and iface < len(self.face_centers_3d):
                censize3d = list(copy.copy(self.face_centers_3d[iface]))
                censize3d.append(2.0 *
                                 self.real_face_sizes_3d[iface])  ###ZMULT
                self.get_features(ia, self.num_feats, (x, y, w, h), censize3d)
            else:
                self.get_features(ia, self.num_feats, (x, y, w, h),
                                  (0.0, 0.0, 0.0, 1000000.0))
            if not ia.kp2d:
                continue

            # First frame:
            if len(self.current_keyframes) < iface + 1:

                (cen, diff) = self.rect_to_center_diff((x, y, w, h))
                cen3d = self.cam.pix2cam(cen[0], cen[1], ia.avgd)
                cen3d = list(cen3d)
                ltf = self.cam.pix2cam(x, y, ia.avgd)
                rbf = self.cam.pix2cam(x + w, y + h, ia.avgd)
                fs3d = ((rbf[0] - ltf[0]) + (rbf[1] - ltf[1])) / 4.0
                # This assumes that we're tracking the face plane center, not the center of the head sphere.
                # If you want to track the center of the sphere instead, do: cen3d[2] += fs3d

                # Check that the face is a reasonable size. If not, skip this face.
                if 2 * fs3d < self.min_real_face_size or 2 * fs3d > self.max_real_face_size or iface > 1:  #HACK: ONLY ALLOW ONE FACE
                    self.faces.pop(iface)
                    iface -= 1
                    continue

                if DESCRIPTOR == 'CALONDER':
                    self.vo.collect_descriptors(ia)
                elif DESCRIPTOR == 'SAD':
                    self.vo.collect_descriptors_sad(ia)
                else:
                    pass

                self.current_keyframes.append(0)
                self.keyframes.append(copy.copy(ia))

                self.feats_to_centers.append(
                    self.make_face_model(cen, diff, ia.kp2d))

                self.real_face_sizes_3d.append(copy.deepcopy(fs3d))
                self.feats_to_centers_3d.append(
                    self.make_face_model(cen3d, (fs3d, fs3d, fs3d), ia.kp3d))
                self.face_centers_3d.append(copy.deepcopy(cen3d))

                self.recent_good_frames.append(copy.copy(ia))
                self.recent_good_rects.append(copy.deepcopy([x, y, w, h]))
                self.recent_good_centers_3d.append(copy.deepcopy(cen3d))
                self.recent_good_motion.append([0.0] * 3)  #dx,dy,dimfacesize
                self.recent_good_motion_3d.append([0.0] * 3)

                self.same_key_rgfs.append(True)

                if DEBUG:
                    print "cen2d", cen
                    print "cen3d", self.face_centers_3d[iface]

                # End first frame

            # Later frames
            else:
                if DESCRIPTOR == 'CALONDER':
                    self.vo.collect_descriptors(ia)
                elif DESCRIPTOR == 'SAD':
                    self.vo.collect_descriptors_sad(ia)
                else:
                    pass

                done_matching = False
                bad_frame = False
                while not done_matching:

                    # Try matching to the keyframe
                    keyframe = self.keyframes[self.current_keyframes[iface]]
                    temp_match = self.vo.temporal_match(ia,
                                                        keyframe,
                                                        want_distances=True)
                    ia.matches = [(m2, m1) for (m1, m2, m3) in temp_match]
                    ia.desc_diffs = [m3 for (m1, m2, m3) in temp_match]
                    print "temp matches", temp_match
                    ia.good_matches = [
                        s < self.desc_diff_thresh for s in ia.desc_diffs
                    ]

                    n_good_matches = len([
                        m for m in ia.desc_diffs if m < self.desc_diff_thresh
                    ])

                    if DEBUG:
                        if len(keyframe.kp) < 2:
                            print "Keyframe has less than 2 kps"
                        if n_good_matches < len(keyframe.kp) / 2.0:
                            print "ngoodmatches, len key.kp, len key.kp/2", n_good_matches, len(
                                keyframe.kp), len(keyframe.kp) / 2.0

                    # Not enough matches, get a new keyframe
                    if len(keyframe.kp) < 2 or n_good_matches < len(
                            keyframe.kp) / 2.0:

                        if DEBUG:
                            print "New keyframe"

                        # Make a new face model, either from a recent good frame, or from the current image
                        if not self.same_key_rgfs[iface]:

                            if DEBUG:
                                print "centers at beginning of new keyframe"
                                print "cen2d", [
                                    self.faces[iface][0] +
                                    self.faces[iface][2] / 2.0,
                                    self.faces[iface][1] +
                                    self.faces[iface][3] / 2.0
                                ]
                                print "cen3d", self.face_centers_3d[iface]

                            matched_z_list = [
                                kp3d[2] for (kp3d, is_good) in zip(
                                    self.recent_good_frames[iface].kp3d, self.
                                    recent_good_frames[iface].good_matches)
                                if is_good
                            ]
                            if len(matched_z_list) == 0:
                                matched_z_list = [
                                    kp3d[2] for kp3d in
                                    self.recent_good_frames[iface].kp3d
                                ]
                            avgz_goodmatches = sum(matched_z_list) / len(
                                matched_z_list)
                            tokeep = [
                                math.fabs(
                                    self.recent_good_frames[iface].kp3d[i][2] -
                                    avgz_goodmatches) <
                                2.0 * self.real_face_sizes_3d[iface]
                                for i in range(
                                    len(self.recent_good_frames[iface].kp3d))
                            ]
                            kp3d_for_model = [
                                kp3d for (kp3d, tk) in zip(
                                    self.recent_good_frames[iface].kp3d,
                                    tokeep) if tk
                            ]
                            kp_for_model = [
                                kp for (kp, tk) in zip(
                                    self.recent_good_frames[iface].kp, tokeep)
                                if tk
                            ]
                            # If you're not left with enough points, just take all of them and don't worry about the depth constraints.
                            if len(kp3d_for_model) < 2:
                                kp3d_for_model = copy.deepcopy(
                                    self.recent_good_frames[iface].kp3d)
                                kp_for_model = copy.deepcopy(
                                    self.recent_good_frames[iface].kp)

                            (cen, diff) = self.rect_to_center_diff(
                                self.recent_good_rects[iface])
                            self.feats_to_centers[
                                iface] = self.make_face_model(
                                    cen, diff,
                                    [(kp0, kp1)
                                     for (kp0, kp1, kp2) in kp_for_model])

                            cen3d = self.recent_good_centers_3d[iface]
                            self.feats_to_centers_3d[
                                iface] = self.make_face_model(
                                    cen3d,
                                    [self.real_face_sizes_3d[iface]] * 3,
                                    kp3d_for_model)

                            self.keyframes[
                                self.current_keyframes[iface]] = copy.copy(
                                    self.recent_good_frames[iface])
                            self.keyframes[self.current_keyframes[
                                iface]].kp = kp_for_model
                            self.keyframes[
                                self.current_keyframes[iface]].kp2d = [
                                    (k0, k1) for (k0, k1, k2) in kp_for_model
                                ]
                            self.keyframes[self.current_keyframes[
                                iface]].kp3d = kp3d_for_model
                            self.keyframes[
                                self.current_keyframes[iface]].matches = [
                                    (i, i) for i in range(len(kp_for_model))
                                ]
                            self.keyframes[
                                self.current_keyframes[iface]].good_matches = [
                                    True
                                ] * len(kp_for_model)
                            self.keyframes[self.current_keyframes[
                                iface]].desc_diffs = [0] * len(kp_for_model)

                            if DESCRIPTOR == 'CALONDER':
                                self.vo.collect_descriptors(self.keyframes[
                                    self.current_keyframes[iface]])
                            elif DESCRIPTOR == 'SAD':
                                self.vo.collect_descriptors_sad(self.keyframes[
                                    self.current_keyframes[iface]])
                            else:
                                pass

                            self.face_centers_3d[iface] = copy.deepcopy(cen3d)
                            # Not changing the face size

                            self.current_keyframes[
                                iface] = 0  #### HACK: ONLY ONE KEYFRAME!!!

                            self.same_key_rgfs[iface] = True
                            # Don't need to change the recent good frame yet.

                            if DEBUG:
                                print "centers at end of new keyframe"
                                print "cen2d", [
                                    self.faces[iface][0] +
                                    self.faces[iface][2] / 2.0,
                                    self.faces[iface][1] +
                                    self.faces[iface][3] / 2.0
                                ]
                                print "cen3d", self.face_centers_3d[iface]

                        else:

                            # Making a new model off of the current frame but with the predicted new position.
                            # HACK: The displacement computation assumes that the robot/head is still, fix this.
                            bad_frame = True
                            #done_matching = True
                            if DEBUG:
                                print "Bad frame ", self.seq, " for face ", iface

                            (cen, diff) = self.rect_to_center_diff(
                                self.faces[iface])
                            if DEBUG:
                                print "Motion for bad frame ", self.recent_good_motion[
                                    iface], self.recent_good_motion_3d[iface]
                            new_cen = [
                                cen[0] + self.recent_good_motion[iface][0],
                                cen[1] + self.recent_good_motion[iface][1]
                            ]
                            diff = [
                                diff[0] + self.recent_good_motion[iface][2],
                                diff[1] + self.recent_good_motion[iface][2]
                            ]

                            self.faces[iface] = (new_cen[0] - diff[0],
                                                 new_cen[1] - diff[1],
                                                 2.0 * diff[0], 2.0 * diff[1])
                            (x, y, w, h) = copy.deepcopy(self.faces[iface])

                            pred_cen_3d = [
                                o + n for (o, n) in zip(
                                    self.face_centers_3d[iface],
                                    self.recent_good_motion_3d[iface])
                            ]
                            pred_cen_3d.append(
                                2.0 *
                                self.real_face_sizes_3d[iface])  #### ZMULT
                            self.get_features(ia, self.num_feats, (x, y, w, h),
                                              pred_cen_3d)
                            if not ia.kp2d:
                                break

                            if DESCRIPTOR == 'CALONDER':
                                self.vo.collect_descriptors(ia)
                            elif DESCRIPTOR == 'SAD':
                                self.vo.collect_descriptors_sad(ia)
                            else:
                                pass

                            self.keyframes[
                                self.current_keyframes[iface]] = copy.copy(ia)
                            self.current_keyframes[iface] = 0
                            (cen, diff) = self.rect_to_center_diff(
                                self.faces[iface])
                            self.feats_to_centers[
                                iface] = self.make_face_model(
                                    cen, diff, ia.kp2d)
                            self.feats_to_centers_3d[
                                iface] = self.make_face_model([
                                    pred_cen_3d[0], pred_cen_3d[1],
                                    pred_cen_3d[2]
                                ], [self.real_face_sizes_3d[iface]] * 3,
                                                              ia.kp3d)
                            self.face_centers_3d[iface] = copy.deepcopy(
                                pred_cen_3d)
                            self.same_key_rgfs[iface] = True

                    # Good matches, mark this frame as good
                    else:
                        done_matching = True

                    # END MATCHING

                # If we got enough matches for this frame, track.
                if ia.kp and ia.kp2d:

                    # Track
                    sparse_pred_list = []
                    sparse_pred_list_2d = []
                    probs = []
                    bandwidths = []
                    size_mult = 0.05  #1.0

                    for ((match1, match2),
                         score) in zip(ia.matches, ia.desc_diffs):
                        if score < self.desc_diff_thresh:
                            sparse_pred_list.append([
                                ia.kp3d[match2][i] +
                                self.feats_to_centers_3d[iface][match1][i]
                                for i in range(3)
                            ])
                            sparse_pred_list_2d.append([
                                ia.kp2d[match2][i] +
                                self.feats_to_centers[iface][match1][i]
                                for i in range(2)
                            ])
                            #probs.append(score)
                    probs = [1.0] * len(
                        sparse_pred_list_2d
                    )  # Ignore actual match scores. Uncomment line above to use the match scores.
                    bandwidths = [size_mult * self.real_face_sizes_3d[iface]
                                  ] * len(sparse_pred_list_2d)

                    (old_center,
                     old_diff) = self.rect_to_center_diff(self.faces[iface])

                    if DEBUG:
                        print "Old center 3d ", self.face_centers_3d[iface]
                        print "Old center 2d ", old_center

                    old_rect = self.faces[iface]  # For display only

                    new_center = self.mean_shift_sparse(
                        self.face_centers_3d[iface][0:3], sparse_pred_list,
                        probs, bandwidths, 10, 1.0)
                    new_center_2d = self.cam.cam2pix(new_center[0],
                                                     new_center[1],
                                                     new_center[2])
                    # The above line assumes that we're tracking the face plane center, not the center of the head sphere.
                    # If you want to track the center of the sphere instead, subtract self.real_face_sizes[iface] from the z-coord.
                    ltf = self.cam.cam2pix(
                        new_center[0] - self.real_face_sizes_3d[iface],
                        new_center[1] - self.real_face_sizes_3d[iface],
                        new_center[2])
                    rbf = self.cam.cam2pix(
                        new_center[0] + self.real_face_sizes_3d[iface],
                        new_center[1] + self.real_face_sizes_3d[iface],
                        new_center[2])
                    w = rbf[0] - ltf[0]
                    h = rbf[1] - ltf[1]

                    if DEBUG:
                        print "new center 3d ", new_center
                        print "new_center 2d ", new_center_2d

                    (nx, ny, nw, nh) = (new_center_2d[0] - (w - 1) / 2.0,
                                        new_center_2d[1] - (h - 1) / 2.0, w, h)

                    # Force the window back into the image.
                    nx += max(0, 0 - nx) + min(0, im.width - nx + nw)
                    ny += max(0, 0 - ny) + min(0, im.height - ny + nh)

                    self.faces[iface] = [nx, ny, nw, nh]
                    self.recent_good_rects[iface] = [nx, ny, nw, nh]
                    self.recent_good_centers_3d[iface] = copy.deepcopy(
                        new_center)
                    if bad_frame:
                        self.recent_good_motion[
                            iface] = self.recent_good_motion[iface]
                        self.recent_good_motion_3d[
                            iface] = self.recent_good_motion_3d[iface]
                    else:
                        self.recent_good_motion[iface] = [
                            new_center_2d[0] - old_center[0],
                            new_center_2d[1] - old_center[1],
                            ((nw - 1.0) / 2.0) - old_diff[0]
                        ]
                        self.recent_good_motion_3d[iface] = [
                            new_center[i] - self.face_centers_3d[iface][i]
                            for i in range(len(new_center))
                        ]
                    self.face_centers_3d[iface] = copy.deepcopy(new_center)
                    self.recent_good_frames[iface] = copy.copy(ia)
                    self.same_key_rgfs[iface] = False

                    if DEBUG:
                        print "motion ", self.recent_good_motion[
                            iface], self.recent_good_motion_3d[iface]
                        print "face 2d ", self.faces[iface]
                        print "face center 3d ", self.face_centers_3d[iface]

                    # Output the location of this face center in the 3D camera frame (of the left camera), and rotate
                    # the coordinates to match the robot's idea of the 3D camera frame.
                    center_uvd = (nx + (nw - 1) / 2.0, ny + (nh - 1) / 2.0,
                                  (numpy.average(ia.kp, 0))[2])
                    center_camXYZ = self.cam.pix2cam(center_uvd[0],
                                                     center_uvd[1],
                                                     center_uvd[2])
                    center_robXYZ = (center_camXYZ[2], -center_camXYZ[0],
                                     -center_camXYZ[1])

                    ########### PUBLISH the face center for the head controller to track. ########
                    if not self.usebag:
                        #stamped_point = PointStamped()
                        #(stamped_point.point.x, stamped_point.point.y, stamped_point.point.z) = center_robXYZ
                        #stamped_point.header.frame_id = "stereo"
                        #stamped_point.header.stamp = imarray.header.stamp
                        #self.pub.publish(stamped_point)
                        pm = PositionMeasurement()
                        pm.header.stamp = imarray.header.stamp
                        pm.name = "stereo_face_feature_tracker"
                        pm.object_id = -1
                        (pm.pos.x, pm.pos.y, pm.pos.z) = center_robXYZ
                        pm.header.frame_id = "stereo_link"
                        pm.reliability = 0.5
                        pm.initialization = 0
                        #pm.covariance
                        self.pub.publish(pm)

                # End later frames

            ############ DRAWING ################
            if SAVE_PICS:

                if not self.keyframes or len(self.keyframes) <= iface:
                    bigim_py = im_py
                    draw = ImageDraw.Draw(bigim_py)
                else:
                    key_im = self.keyframes[self.current_keyframes[iface]]
                    keyim_py = Image.fromstring("L", key_im.size,
                                                key_im.rawdata)
                    bigim_py = Image.new(
                        "RGB", (im_py.size[0] + key_im.size[0], im_py.size[1]))
                    bigim_py.paste(keyim_py.convert("RGB"), (0, 0))
                    bigim_py.paste(im_py, (key_im.size[0] + 1, 0))
                    draw = ImageDraw.Draw(bigim_py)

                    (x, y, w, h) = self.faces[iface]
                    draw.rectangle((x, y, x + w, y + h), outline=(0, 255, 0))
                    draw.rectangle(
                        (x + key_im.size[0], y, x + w + key_im.size[0], y + h),
                        outline=(0, 255, 0))
                    (x, y, w, h) = old_rect
                    draw.rectangle((x, y, x + w, y + h),
                                   outline=(255, 255, 255))
                    draw.rectangle(
                        (x + key_im.size[0], y, x + w + key_im.size[0], y + h),
                        outline=(255, 255, 255))

                    mstart = old_center
                    mend = (old_center[0] + self.recent_good_motion[iface][0],
                            old_center[1] + self.recent_good_motion[iface][1])
                    draw.rectangle((mstart[0] - 1, mstart[1] - 1,
                                    mstart[0] + 1, mstart[1] + 1),
                                   outline=(255, 255, 255))
                    draw.rectangle(
                        (mend[0] - 1, mend[1] - 1, mend[0] + 1, mend[1] + 1),
                        outline=(0, 255, 0))
                    draw.line(mstart + mend, fill=(255, 255, 255))

                    for (x, y) in key_im.kp2d:
                        draw_x(draw, (x, y), (1, 1), (255, 0, 0))
                    for (x, y) in ia.kp2d:
                        draw_x(draw, (x + key_im.size[0], y), (1, 1),
                               (255, 0, 0))

                    if self.seq > 0:

                        if ia.matches:
                            for ((m1, m2),
                                 score) in zip(ia.matches, ia.desc_diffs):
                                if score > self.desc_diff_thresh:
                                    color = (255, 0, 0)
                                else:
                                    color = (0, 255, 0)
                                draw.line(
                                    (key_im.kp2d[m1][0], key_im.kp2d[m1][1],
                                     ia.kp2d[m2][0] + key_im.size[0],
                                     ia.kp2d[m2][1]),
                                    fill=color)

                        for (i, (u, v)) in enumerate(sparse_pred_list_2d):
                            bscale = min(1, probs[i] / 0.01)
                            draw_x(draw, (u, v), (1, 1),
                                   (128.0 + 128.0 * bscale,
                                    128.0 + 128.0 * bscale,
                                    (1.0 - bscale) * 255.0))
                            draw_x(draw, (u + key_im.size[0], v), (1, 1),
                                   (128.0 + 128.0 * bscale,
                                    128.0 + 128.0 * bscale,
                                    (1.0 - bscale) * 255.0))

                    ####### PUBLISH 3d visualization point cloud ###################
                    if self.usebag and self.visualize:
                        cloud = PointCloud()
                        cloud.header.frame_id = "stereo"
                        cloud.header.stamp = imarray.header.stamp
                        cloud.pts = []
                        cloud.pts.append(Point())
                        (cloud.pts[0].x, cloud.pts[0].y,
                         cloud.pts[0].z) = self.face_centers_3d[iface][:3]
                        for (i, kp3d) in enumerate(ia.kp3d):
                            cloud.pts.append(Point())
                            (cloud.pts[i].x, cloud.pts[i].y,
                             cloud.pts[i].z) = kp3d

                        lp = len(cloud.pts)
                        if self.seq > 0:
                            for (i, (u, v)) in enumerate(sparse_pred_list):
                                cloud.pts[lp + i].append(Point())
                                (cloud.pts[lp + i].x, cloud.pts[lp + i].y,
                                 cloud.pts[lp + i].z) = sparse_pred_list[i][:3]

                        self.pub.publish(cloud)

                bigim_py.save("/tmp/tiff/feats%06d_%03d.tiff" %
                              (self.seq, iface))
                #END DRAWING

            # END FACE LOOP

        self.seq += 1
Пример #12
0
        imL, imR, _ = im.split()
        if use_magic_disparity:
            imD = [
                Image.open("/tmp/out%06d-x.tiff" % fn),
                Image.open("/tmp/out%06d-y.tiff" % fn),
                Image.open("/tmp/out%06d-z.tiff" % fn)
            ]
        if 0:
            imL, imR = imR, imL
            imL = imL.transpose(Image.FLIP_LEFT_RIGHT)
            imR = imR.transpose(Image.FLIP_LEFT_RIGHT)
            for i in range(3):
                imD[i] = imD[i].transpose(Image.FLIP_LEFT_RIGHT)
    if evaluate_disparity:
        f0 = MagicStereoFrame(imgStereo(imL), imgStereo(imR), imD, stereo_cam)
        f1 = SparseStereoFrame(imgStereo(imL), imgStereo(imR))
        vos[0].find_keypoints(f0)
        pairs = [(f0.lookup_disparity(x, y), f1.lookup_disparity(x, y))
                 for (x, y) in f0.kp2d]
        disparities += [(a, b) for (a, b) in pairs if b != None]
    else:
        for j, vo in enumerate(vos):
            if use_magic_disparity:
                f = MagicStereoFrame(imgStereo(imL), imgStereo(imR), imD,
                                     stereo_cam)
            else:
                f = SparseStereoFrame(imgStereo(imL), imgStereo(imR))

            #f = PhonyFrame(~desired_pose, stereo_cam)
            #vo.lock_handle_frame(f)
Пример #13
0
            break

        if topic.endswith("videre/cal_params") and not cam:
            cam = camera.VidereCamera(msg.data)

            vo = VisualOdometer(cam,
                                feature_detector=FeatureDetectorFast(),
                                descriptor_scheme=DescriptorSchemeSAD())

        if cam and topic.endswith("videre/images"):
            imgR = imgAdapted(msg.images[0])
            imgL = imgAdapted(msg.images[1])
            assert msg.images[0].label == "right_rectified"
            assert msg.images[1].label == "left_rectified"

            frame = SparseStereoFrame(imgL, imgR)
            vo.find_keypoints(frame)
            vo.find_disparities(frame)
            #frame.kp = [ (x,y,d) for (x,y,d) in frame.kp if d > 8]
            all_ds += [d for (x, y, d) in frame.kp]

            vo.collect_descriptors(frame)
            if prev_frame:
                pairs = vo.temporal_match(prev_frame, frame)
                solution = vo.solve(prev_frame.kp, frame.kp, pairs, True)
                (inl, rot, shift) = solution
                sos += numpy.array(shift)
                print sos
            prev_frame = frame

            framecounter += 1
  def frame(self, imarray):

    # No calibration params yet.
    if not self.vo:
      return

    if self.seq > 10000:
      sys.exit()
    if DEBUG:
      print ""
      print ""
      print "Frame ", self.seq
      print ""
      print ""


    im = imarray.images[1]
    im_r = imarray.images[0]
    if im.colorspace == "mono8":
      im_py = Image.fromstring("L", (im.width, im.height), im.data)
      im_r_py = Image.fromstring("L", (im_r.width, im_r.height), im_r.data)
    elif im.colorspace == "rgb24":
      use_color = True
      im_col_py = Image.fromstring("RGB", (im.width, im.height), im.data)
      im_py = im_col_py.convert("L")
      im_r_py = Image.fromstring("RGB", (im_r.width, im_r.height), im_r.data)
      im_r_py = im_r_py.convert("L")
    else :
      print "Unknown colorspace"
      return
    

    # Detect faces on the first frame
    if not self.current_keyframes :
      self.faces = self.p.detectAllFaces(im_py.tostring(), im.width, im.height, self.cascade_file, 1.0, None, None, True) 
      if DEBUG:
        print "Faces ", self.faces
      
    sparse_pred_list = []
    sparse_pred_list_2d = []
    old_rect = [0,0,0,0]
    ia = SparseStereoFrame(im_py,im_r_py)
    ia.matches = []
    ia.desc_diffs = []
    ia.good_matches = []

    # Track each face
    iface = -1
    for face in self.faces:
      
      iface += 1

      (x,y,w,h) = copy.copy(self.faces[iface])
      if DEBUG:
        print "A face ", (x,y,w,h)

      (old_center, old_diff) = self.rect_to_center_diff((x,y,w,h)) 
      
      if self.face_centers_3d and iface<len(self.face_centers_3d):
        censize3d = list(copy.copy(self.face_centers_3d[iface]))
        censize3d.append(2.0*self.real_face_sizes_3d[iface]) ###ZMULT
        self.get_features(ia, self.num_feats, (x,y,w,h), censize3d)
      else:
        self.get_features(ia, self.num_feats, (x, y, w, h), (0.0,0.0,0.0,1000000.0))
      if not ia.kp2d:
        continue

      # First frame:
      if len(self.current_keyframes) < iface+1:

        (cen,diff) = self.rect_to_center_diff((x,y,w,h))
        cen3d = self.cam.pix2cam(cen[0],cen[1],ia.avgd)
        cen3d = list(cen3d)
        ltf = self.cam.pix2cam(x,y,ia.avgd)
        rbf = self.cam.pix2cam(x+w,y+h,ia.avgd)
        fs3d = ( (rbf[0]-ltf[0]) + (rbf[1]-ltf[1]) )/4.0
        # This assumes that we're tracking the face plane center, not the center of the head sphere. 
        # If you want to track the center of the sphere instead, do: cen3d[2] += fs3d

        # Check that the face is a reasonable size. If not, skip this face.
        if 2*fs3d < self.min_real_face_size or 2*fs3d > self.max_real_face_size or iface > 1: #HACK: ONLY ALLOW ONE FACE
          self.faces.pop(iface)
          iface -= 1
          continue

        if DESCRIPTOR=='CALONDER':
          self.vo.collect_descriptors(ia)
        elif DESCRIPTOR=='SAD':
          self.vo.collect_descriptors_sad(ia)
        else:
          pass

        self.current_keyframes.append(0)
        self.keyframes.append(copy.copy(ia))

        self.feats_to_centers.append(self.make_face_model( cen, diff, ia.kp2d ))

        self.real_face_sizes_3d.append( copy.deepcopy(fs3d) )
        self.feats_to_centers_3d.append( self.make_face_model( cen3d, (fs3d,fs3d,fs3d), ia.kp3d) )
        self.face_centers_3d.append( copy.deepcopy(cen3d) )

        self.recent_good_frames.append(copy.copy(ia))
        self.recent_good_rects.append(copy.deepcopy([x,y,w,h]))
        self.recent_good_centers_3d.append(copy.deepcopy(cen3d))
        self.recent_good_motion.append([0.0]*3) #dx,dy,dimfacesize
        self.recent_good_motion_3d.append([0.0]*3)

        self.same_key_rgfs.append(True)
        
        if DEBUG:
          print "cen2d", cen
          print "cen3d", self.face_centers_3d[iface]

        # End first frame

      # Later frames
      else :
        if DESCRIPTOR=='CALONDER':
          self.vo.collect_descriptors(ia)
        elif DESCRIPTOR=='SAD':
          self.vo.collect_descriptors_sad(ia)
        else:
          pass


        done_matching = False
        bad_frame = False
        while not done_matching:

          # Try matching to the keyframe
          keyframe = self.keyframes[self.current_keyframes[iface]]
          temp_match = self.vo.temporal_match(ia,keyframe,want_distances=True)
          ia.matches = [(m2,m1) for (m1,m2,m3) in temp_match]
          ia.desc_diffs = [m3 for (m1,m2,m3) in temp_match]
          print "temp matches", temp_match       
          ia.good_matches = [s < self.desc_diff_thresh for s in ia.desc_diffs]

          n_good_matches = len([m for m in ia.desc_diffs if m < self.desc_diff_thresh])

          if DEBUG:
            if len(keyframe.kp)<2:
              print "Keyframe has less than 2 kps"
            if n_good_matches < len(keyframe.kp)/2.0:
              print "ngoodmatches, len key.kp, len key.kp/2", n_good_matches, len(keyframe.kp), len(keyframe.kp)/2.0
        
          # Not enough matches, get a new keyframe
          if len(keyframe.kp)<2 or n_good_matches < len(keyframe.kp)/2.0 : 

            if DEBUG:
              print "New keyframe"

            # Make a new face model, either from a recent good frame, or from the current image
            if not self.same_key_rgfs[iface] :

              if DEBUG:
                print "centers at beginning of new keyframe"
                print "cen2d", [self.faces[iface][0]+self.faces[iface][2]/2.0, self.faces[iface][1]+self.faces[iface][3]/2.0]
                print "cen3d", self.face_centers_3d[iface]


              matched_z_list = [kp3d[2] for (kp3d,is_good) in zip(self.recent_good_frames[iface].kp3d,self.recent_good_frames[iface].good_matches) if is_good]
              if len(matched_z_list) == 0:
                matched_z_list = [kp3d[2] for kp3d in self.recent_good_frames[iface].kp3d]
              avgz_goodmatches = sum(matched_z_list)/ len(matched_z_list)
              tokeep = [math.fabs(self.recent_good_frames[iface].kp3d[i][2]-avgz_goodmatches) < 2.0*self.real_face_sizes_3d[iface] 
                        for i in range(len(self.recent_good_frames[iface].kp3d))]
              kp3d_for_model = [kp3d for (kp3d,tk) in zip(self.recent_good_frames[iface].kp3d,tokeep) if tk]
              kp_for_model = [kp for (kp,tk) in zip(self.recent_good_frames[iface].kp,tokeep) if tk]
              # If you're not left with enough points, just take all of them and don't worry about the depth constraints.
              if len(kp3d_for_model) < 2:
                kp3d_for_model = copy.deepcopy(self.recent_good_frames[iface].kp3d)
                kp_for_model = copy.deepcopy(self.recent_good_frames[iface].kp)

              (cen, diff) = self.rect_to_center_diff(self.recent_good_rects[iface])
              self.feats_to_centers[iface] = self.make_face_model( cen, diff, [(kp0,kp1) for (kp0,kp1,kp2) in kp_for_model])

              cen3d = self.recent_good_centers_3d[iface]
              self.feats_to_centers_3d[iface] = self.make_face_model( cen3d, [self.real_face_sizes_3d[iface]]*3, kp3d_for_model)

              self.keyframes[self.current_keyframes[iface]] = copy.copy(self.recent_good_frames[iface])
              self.keyframes[self.current_keyframes[iface]].kp = kp_for_model
              self.keyframes[self.current_keyframes[iface]].kp2d = [(k0,k1) for (k0,k1,k2) in kp_for_model]
              self.keyframes[self.current_keyframes[iface]].kp3d = kp3d_for_model
              self.keyframes[self.current_keyframes[iface]].matches = [(i,i) for i in range(len(kp_for_model))]
              self.keyframes[self.current_keyframes[iface]].good_matches = [True]*len(kp_for_model)
              self.keyframes[self.current_keyframes[iface]].desc_diffs = [0]*len(kp_for_model)

              if DESCRIPTOR=='CALONDER':
                self.vo.collect_descriptors(self.keyframes[self.current_keyframes[iface]])
              elif DESCRIPTOR=='SAD':
                self.vo.collect_descriptors_sad(self.keyframes[self.current_keyframes[iface]])
              else:
                pass
              

              self.face_centers_3d[iface] = copy.deepcopy(cen3d)
              # Not changing the face size

              self.current_keyframes[iface] = 0 #### HACK: ONLY ONE KEYFRAME!!!

              self.same_key_rgfs[iface] = True
              # Don't need to change the recent good frame yet.

              if DEBUG:
                print "centers at end of new keyframe"
                print "cen2d", [self.faces[iface][0]+self.faces[iface][2]/2.0, self.faces[iface][1]+self.faces[iface][3]/2.0]
                print "cen3d", self.face_centers_3d[iface]

            else :

              # Making a new model off of the current frame but with the predicted new position. 
              # HACK: The displacement computation assumes that the robot/head is still, fix this.
              bad_frame = True
              #done_matching = True
              if DEBUG:
                print "Bad frame ", self.seq, " for face ", iface

              (cen,diff) = self.rect_to_center_diff(self.faces[iface])
              if DEBUG:
                print "Motion for bad frame ", self.recent_good_motion[iface], self.recent_good_motion_3d[iface]
              new_cen = [cen[0]+self.recent_good_motion[iface][0], cen[1]+self.recent_good_motion[iface][1]]
              diff = [diff[0]+self.recent_good_motion[iface][2], diff[1]+self.recent_good_motion[iface][2]]                 

              self.faces[iface] = (new_cen[0]-diff[0], new_cen[1]-diff[1], 2.0*diff[0], 2.0*diff[1])
              (x,y,w,h) = copy.deepcopy(self.faces[iface])

              pred_cen_3d = [o+n for (o,n) in zip(self.face_centers_3d[iface],self.recent_good_motion_3d[iface])]
              pred_cen_3d.append(2.0*self.real_face_sizes_3d[iface])  #### ZMULT
              self.get_features(ia, self.num_feats, (x,y,w,h), pred_cen_3d)
              if not ia.kp2d:
                break

              if DESCRIPTOR=='CALONDER':
                self.vo.collect_descriptors(ia)
              elif DESCRIPTOR=='SAD':
                self.vo.collect_descriptors_sad(ia)
              else:
                pass


              self.keyframes[self.current_keyframes[iface]] = copy.copy(ia)
              self.current_keyframes[iface] = 0
              (cen,diff) = self.rect_to_center_diff(self.faces[iface])
              self.feats_to_centers[iface] = self.make_face_model( cen, diff, ia.kp2d )
              self.feats_to_centers_3d[iface] = self.make_face_model( [pred_cen_3d[0],pred_cen_3d[1],pred_cen_3d[2]], [self.real_face_sizes_3d[iface]]*3, ia.kp3d)
              self.face_centers_3d[iface] = copy.deepcopy(pred_cen_3d)
              self.same_key_rgfs[iface] = True

          # Good matches, mark this frame as good
          else:
            done_matching = True

          # END MATCHING


        # If we got enough matches for this frame, track.
        if ia.kp and ia.kp2d:

          # Track
          sparse_pred_list = []
          sparse_pred_list_2d = []
          probs = []
          bandwidths = []
          size_mult = 0.05 #1.0

          for ((match1, match2), score) in zip(ia.matches, ia.desc_diffs):
            if score < self.desc_diff_thresh:
              sparse_pred_list.append( [ia.kp3d[match2][i]+self.feats_to_centers_3d[iface][match1][i] for i in range(3)] )
              sparse_pred_list_2d.append( [ia.kp2d[match2][i]+self.feats_to_centers[iface][match1][i] for i in range(2)] )
              #probs.append(score)
          probs = [1.0] * len(sparse_pred_list_2d) # Ignore actual match scores. Uncomment line above to use the match scores.
          bandwidths = [size_mult*self.real_face_sizes_3d[iface]] * len(sparse_pred_list_2d)

          (old_center, old_diff) = self.rect_to_center_diff(self.faces[iface])
 
          if DEBUG:
            print "Old center 3d ", self.face_centers_3d[iface]
            print "Old center 2d ", old_center

          old_rect = self.faces[iface] # For display only

          new_center = self.mean_shift_sparse( self.face_centers_3d[iface][0:3], sparse_pred_list, probs, bandwidths, 10, 1.0 )
          new_center_2d = self.cam.cam2pix(new_center[0], new_center[1], new_center[2]) 
          # The above line assumes that we're tracking the face plane center, not the center of the head sphere. 
          # If you want to track the center of the sphere instead, subtract self.real_face_sizes[iface] from the z-coord.
          ltf = self.cam.cam2pix( new_center[0]-self.real_face_sizes_3d[iface], new_center[1]-self.real_face_sizes_3d[iface], new_center[2])
          rbf = self.cam.cam2pix( new_center[0]+self.real_face_sizes_3d[iface], new_center[1]+self.real_face_sizes_3d[iface], new_center[2])
          w = rbf[0]-ltf[0]
          h = rbf[1]-ltf[1]       

          if DEBUG:
            print "new center 3d ", new_center
            print "new_center 2d ", new_center_2d

          (nx,ny,nw,nh) = (new_center_2d[0]-(w-1)/2.0, new_center_2d[1]-(h-1)/2.0, w, h)

          # Force the window back into the image.
          nx += max(0,0-nx) + min(0, im.width - nx+nw)
          ny += max(0,0-ny) + min(0, im.height - ny+nh)

          self.faces[iface] = [nx, ny, nw, nh]
          self.recent_good_rects[iface] = [nx,ny,nw,nh]
          self.recent_good_centers_3d[iface] = copy.deepcopy(new_center)
          if bad_frame:
            self.recent_good_motion[iface] = self.recent_good_motion[iface]
            self.recent_good_motion_3d[iface] = self.recent_good_motion_3d[iface]
          else:
            self.recent_good_motion[iface] = [new_center_2d[0]-old_center[0], new_center_2d[1]-old_center[1], ((nw-1.0)/2.0)-old_diff[0]]
            self.recent_good_motion_3d[iface] = [ new_center[i]-self.face_centers_3d[iface][i] for i in range(len(new_center))]
          self.face_centers_3d[iface] = copy.deepcopy(new_center)
          self.recent_good_frames[iface] = copy.copy(ia)
          self.same_key_rgfs[iface] = False


          if DEBUG:
            print "motion ", self.recent_good_motion[iface], self.recent_good_motion_3d[iface]
            print "face 2d ", self.faces[iface]
            print "face center 3d ", self.face_centers_3d[iface]


          # Output the location of this face center in the 3D camera frame (of the left camera), and rotate 
          # the coordinates to match the robot's idea of the 3D camera frame.
          center_uvd = (nx + (nw-1)/2.0, ny + (nh-1)/2.0, (numpy.average(ia.kp,0))[2] )
          center_camXYZ = self.cam.pix2cam(center_uvd[0], center_uvd[1], center_uvd[2])
          center_robXYZ = (center_camXYZ[2], -center_camXYZ[0], -center_camXYZ[1])

          ########### PUBLISH the face center for the head controller to track. ########
          if not self.usebag:
            #stamped_point = PointStamped()
            #(stamped_point.point.x, stamped_point.point.y, stamped_point.point.z) = center_robXYZ
            #stamped_point.header.frame_id = "stereo"
            #stamped_point.header.stamp = imarray.header.stamp
            #self.pub.publish(stamped_point)
            pm = PositionMeasurement()
            pm.header.stamp = imarray.header.stamp
            pm.name = "stereo_face_feature_tracker"
            pm.object_id = -1
            (pm.pos.x,pm.pos.y, pm.pos.z) = center_robXYZ
            pm.header.frame_id = "stereo_link"
            pm.reliability = 0.5;
            pm.initialization = 0;
            #pm.covariance
            self.pub.publish(pm)            
    

        # End later frames


      ############ DRAWING ################
      if SAVE_PICS:

        if not self.keyframes or len(self.keyframes) <= iface :
          bigim_py = im_py
          draw = ImageDraw.Draw(bigim_py)
        else :
          key_im = self.keyframes[self.current_keyframes[iface]]
          keyim_py = Image.fromstring("L", key_im.size, key_im.rawdata)
          bigim_py = Image.new("RGB",(im_py.size[0]+key_im.size[0], im_py.size[1]))
          bigim_py.paste(keyim_py.convert("RGB"),(0,0))
          bigim_py.paste(im_py,(key_im.size[0]+1,0))
          draw = ImageDraw.Draw(bigim_py)

          (x,y,w,h) = self.faces[iface]
          draw.rectangle((x,y,x+w,y+h),outline=(0,255,0))
          draw.rectangle((x+key_im.size[0],y,x+w+key_im.size[0],y+h),outline=(0,255,0))
          (x,y,w,h) = old_rect
          draw.rectangle((x,y,x+w,y+h),outline=(255,255,255))
          draw.rectangle((x+key_im.size[0],y,x+w+key_im.size[0],y+h),outline=(255,255,255))

          mstart = old_center
          mend = (old_center[0]+self.recent_good_motion[iface][0], old_center[1]+self.recent_good_motion[iface][1])
          draw.rectangle((mstart[0]-1,mstart[1]-1,mstart[0]+1,mstart[1]+1), outline=(255,255,255))
          draw.rectangle((mend[0]-1,mend[1]-1,mend[0]+1,mend[1]+1), outline=(0,255,0))
          draw.line(mstart+mend, fill=(255,255,255))

          for (x,y) in key_im.kp2d :
            draw_x(draw, (x,y), (1,1), (255,0,0))
          for (x,y) in ia.kp2d:
            draw_x(draw, (x+key_im.size[0],y), (1,1), (255,0,0))

          if self.seq > 0 :

            if ia.matches:
              for ((m1,m2), score) in zip(ia.matches,ia.desc_diffs) :
                if score > self.desc_diff_thresh :
                  color = (255,0,0)
                else :
                  color = (0,255,0)
                draw.line((key_im.kp2d[m1][0], key_im.kp2d[m1][1], ia.kp2d[m2][0]+key_im.size[0], ia.kp2d[m2][1]), fill=color)

            for (i, (u,v)) in enumerate(sparse_pred_list_2d) :
              bscale = min(1,probs[i]/0.01)
              draw_x(draw, (u,v), (1,1), (128.0+128.0*bscale,128.0+128.0*bscale,(1.0-bscale)*255.0))
              draw_x(draw, (u+key_im.size[0],v), (1,1),(128.0+128.0*bscale,128.0+128.0*bscale,(1.0-bscale)*255.0))      
 

          ####### PUBLISH 3d visualization point cloud ###################
          if self.usebag and self.visualize:
            cloud = PointCloud()
            cloud.header.frame_id = "stereo"
            cloud.header.stamp = imarray.header.stamp
            cloud.pts = []
            cloud.pts.append(Point())
            (cloud.pts[0].x, cloud.pts[0].y, cloud.pts[0].z) = self.face_centers_3d[iface][:3]
            for (i,kp3d) in enumerate(ia.kp3d):
              cloud.pts.append(Point())
              (cloud.pts[i].x,cloud.pts[i].y,cloud.pts[i].z) = kp3d

            lp = len(cloud.pts)
            if self.seq > 0:
              for (i, (u,v)) in enumerate(sparse_pred_list):
                cloud.pts[lp+i].append(Point())
                (cloud.pts[lp+i].x,cloud.pts[lp+i].y,cloud.pts[lp+i].z) = sparse_pred_list[i][:3]
                        
            self.pub.publish(cloud)

        bigim_py.save("/tmp/tiff/feats%06d_%03d.tiff" % (self.seq, iface))
        #END DRAWING


      # END FACE LOOP

    self.seq += 1
Пример #15
0
from stereo_utils import camera
import pylab, numpy

from stereo import ComputedDenseStereoFrame, SparseStereoFrame
from visualodometer import VisualOdometer, Pose, DescriptorSchemeCalonder, DescriptorSchemeSAD, FeatureDetectorFast, FeatureDetector4x4, FeatureDetectorStar, FeatureDetectorHarris, from_xyz_euler

stereo_cam = camera.Camera(
    (389.0, 389.0, 89.23 * 1e-3, 323.42, 323.42, 274.95))

vo = VisualOdometer(stereo_cam,
                    feature_detector=FeatureDetectorStar(),
                    descriptor_scheme=DescriptorSchemeCalonder())

(f0, f1) = [
    SparseStereoFrame(Image.open("f%d-left.png" % i),
                      Image.open("f%d-right.png" % i)) for i in [0, 1]
]

vo.setup_frame(f0)
vo.setup_frame(f1)

pairs = vo.temporal_match(f0, f1)
for (a, b) in pairs:
    pylab.plot([f0.kp[a][0], f1.kp[b][0]], [f0.kp[a][1], f1.kp[b][1]])
pylab.imshow(numpy.fromstring(f0.lf.tostring(), numpy.uint8).reshape(480, 640),
             cmap=pylab.cm.gray)
pylab.scatter([x for (x, y, d) in f0.kp], [y for (x, y, d) in f0.kp],
              label='f0 kp',
              c='red')
pylab.scatter([x for (x, y, d) in f1.kp], [y for (x, y, d) in f1.kp],
              label='f1 kp',
Пример #16
0
        if prev_wheel_pose and wheel_pose:
            angles.append(prev_wheel_pose.angle(wheel_pose))
            qangles.append(prev_wheel_pose.qangle(wheel_pose))

        if not wheel_pose:
            has_moved = True  # be conservative until wheel odom starts up
        elif not prev_wheel_pose or \
               ((not flag_15Hz or framecounter%2 == 0) and \
                prev_wheel_pose.further_than(wheel_pose, dist_thresh, angle_thresh)):
            prev_wheel_pose = wheel_pose
            prev_wheel_o = wheel_o
            has_moved = True

        if has_moved and start <= framecounter:
            af = SparseStereoFrame(dcamImage(msg.left_image),
                                   dcamImage(msg.right_image))
            # save frames, hope there's enough storage
            if framecounter > f1start and framecounter < f1end:
                frames1.append(af)
                vo.setup_frame(af)
            if framecounter > f2start and framecounter < f2end:
                frames2.append(af)
                vo.setup_frame(af)
                for fr in frames1:
                    vo.check_inliers(af, fr)
                    print "Inliers: ", vo.inl
#      vo.handle_frame(af)
            x, y, z = vo.pose.xform(0, 0, 0)
            trajectory.append((x, y, z))
            vo_x.append(x)
            vo_y.append(z)
Пример #17
0
    def xtest_sim(self):
        # Test process with one 'ideal' camera, one real-world Videre
        camera_param_list = [
            # (200.0, 200.0, 3.00,  320.0, 320.0, 240.0),
            (389.0, 389.0, 89.23, 323.42, 323.42, 274.95)
        ]

        def move_combo(i):
            R = rotation(i * 0.02, 0, 1, 0)
            S = (i * -0.01, 0, 0)
            return Pose(R, S)

        def move_translate(i):
            R = rotation(0, 0, 1, 0)
            S = (0, 0, 0)
            return Pose(R, S)

        def move_Yrot(i):
            R = rotation(i * 0.02, 0, 1, 0)
            S = (i * 0, 0, 0)
            return Pose(R, S)

        for movement in [move_combo, move_Yrot]:
            for cam_params in camera_param_list:
                cam = camera.Camera(cam_params)

                kps = []
                model = [(x * 200, y * 200, z * 200) for x in range(-3, 4)
                         for y in range(-3, 4) for z in range(-3, 4)]

                def rndimg():
                    b = "".join(random.sample([chr(c) for c in range(256)],
                                              64))
                    return Image.fromstring("L", (8, 8), b)

                def sprite(dst, x, y, src):
                    try:
                        dst.paste(src, (int(x) - 4, int(y) - 4))
                    except:
                        print "paste failed", x, y

                random.seed(0)
                palette = [rndimg() for i in model]
                expected = []
                afs = []
                for i in range(100):
                    P = movement(i)
                    li = Image.new("L", (640, 480))
                    ri = Image.new("L", (640, 480))
                    q = 0
                    for (mx, my, mz) in model:
                        pp = None
                        pt_camera = (numpy.dot(P.M.I,
                                               numpy.array([mx, my, mz, 1]).T))
                        (cx, cy, cz, cw) = numpy.array(pt_camera).ravel()
                        if cz > 100:
                            ((xl, yl), (xr, yr)) = cam.cam2pixLR(cx, cy, cz)
                            if 0 <= xl and xl < 640 and 0 <= yl and yl < 480:
                                sprite(li, xl, yl, palette[q])
                                sprite(ri, xr, yr, palette[q])
                        q += 1
                    #li.save("sim/left-%04d.png" % i)
                    #ri.save("sim/right-%04d.png" % i)
                    expected.append(P)
                    afs.append(SparseStereoFrame(li, ri))

            threshes = [0.0, 0.01, 0.02, 0.03, 0.04, 0.05, 0.06]
            threshes = [0.001 * i for i in range(100)]
            threshes = range(100, 500, 10)
            error = []
            for thresh in threshes:
                vo = VisualOdometer(cam, inlier_thresh=thresh)
                for (e, af) in zip(expected, afs)[::1]:
                    vo.handle_frame(af)
Пример #18
0
  def frame(self, imarray):

    # No calibration params yet.
    if not self.vo:
      return

    if self.seq > 10000:
      sys.exit()
    if DEBUG:
      print ""
      print ""
      print "Frame ", self.seq
      print ""
      print ""


    im = imarray.images[1]
    im_r = imarray.images[0]
    if im.colorspace == "mono8":
      im_py = Image.fromstring("L", (im.width, im.height), im.data)
      im_r_py = Image.fromstring("L", (im_r.width, im_r.height), im_r.data)
    elif im.colorspace == "rgb24":
      use_color = True
      im_col_py = Image.fromstring("RGB", (im.width, im.height), im.data)
      im_py = im_col_py.convert("L")
      im_r_py = Image.fromstring("RGB", (im_r.width, im_r.height), im_r.data)
      im_r_py = im_r_py.convert("L")
    else :
      print "Unknown colorspace"
      return
    

    # Detect faces on the first frame
    if not self.current_keyframes :
      self.faces = self.p.detectAllFaces(im_py.tostring(), im.width, im.height, self.cascade_file, 1.0, None, None, True) 
      if DEBUG:
        print "Faces ", self.faces
      
    sparse_pred_list = []
    sparse_pred_list_2d = []
    old_rect = [0,0,0,0]
    ia = SparseStereoFrame(im_py,im_r_py)
    ia.matches = []
    ia.desc_diffs = []
    ia.good_matches = []

    # Track each face
    iface = -1
    for face in self.faces:
      
      iface += 1

      (x,y,w,h) = copy.copy(self.faces[iface])
      if DEBUG:
        print "A face ", (x,y,w,h)

      (old_center, old_diff) = self.rect_to_center_diff((x,y,w,h)) 
      
      if self.face_centers_3d and iface<len(self.face_centers_3d):
        censize3d = list(copy.copy(self.face_centers_3d[iface]))
        censize3d.append(1.0*self.real_face_sizes_3d[iface]) ###ZMULT
        self.get_features(ia, self.num_feats, (x,y,w,h), censize3d)
      else:
        self.get_features(ia, self.num_feats, (x, y, w, h), (0.0,0.0,0.0,1000000.0))
      if not ia.kp2d:
        continue

      # First frame:
      if len(self.current_keyframes) < iface+1:

        (cen,diff) = self.rect_to_center_diff((x,y,w,h))
        cen3d = self.cam.pix2cam(cen[0],cen[1],ia.avgd)
        ltf = self.cam.pix2cam(x,y,ia.avgd)
        rbf = self.cam.pix2cam(x+w,y+h,ia.avgd)
        fs3d = ( (rbf[0]-ltf[0]) + (rbf[1]-ltf[1]) )/4.0

        # Check that the face is a reasonable size. If not, skip this face.
        if 2*fs3d < self.min_real_face_size or 2*fs3d > self.max_real_face_size or iface > 1: #HACK: ONLY ALLOW ONE FACE
          self.faces.pop(iface)
          iface -= 1
          continue

        if DESCRIPTOR=='CALONDER':
          self.vo.collect_descriptors(ia)
        elif DESCRIPTOR=='SAD':
          self.vo.collect_descriptors_sad(ia)
        else:
          pass

        self.current_keyframes.append(0)
        self.keyframes.append(copy.copy(ia))

        self.feats_to_centers.append(self.make_face_model( cen, diff, ia.kp2d ))

        self.real_face_sizes_3d.append( copy.deepcopy(fs3d) )
        self.feats_to_centers_3d.append( self.make_face_model( cen3d, (fs3d,fs3d,fs3d), ia.kp3d) )
        self.face_centers_3d.append( copy.deepcopy(cen3d) )

        self.recent_good_frames.append(copy.copy(ia))
        self.recent_good_rects.append(copy.deepcopy([x,y,w,h]))
        self.recent_good_motion.append([0.0]*3) #dx,dy,dimfacesize
        self.recent_good_motion_3d.append([0.0]*3)

        self.same_key_rgfs.append(True)
        
        # End first frame

      # Later frames
      else :
        if DESCRIPTOR=='CALONDER':
          self.vo.collect_descriptors(ia)
        elif DESCRIPTOR=='SAD':
          self.vo.collect_descriptors_sad(ia)
        else:
          pass


        done_matching = False
        bad_frame = False
        while not done_matching:

          # Try matching to the keyframe
          keyframe = self.keyframes[self.current_keyframes[iface]]
          temp_match = self.vo.temporal_match(ia,keyframe,want_distances=True)
          ia.matches = [(m2,m1) for (m1,m2,m3) in temp_match]
          ia.desc_diffs = [m3 for (m1,m2,m3) in temp_match]
          print "Scores", ia.desc_diffs
          #ia.matches = self.vo.temporal_match(keyframe,ia,want_distances=True)
          #ia.desc_diffs = [(VO.sad(keyframe.descriptors[a], ia.descriptors[b])) for (a,b) in ia.matches]
          ia.good_matches = [s < self.desc_diff_thresh for s in ia.desc_diffs]

          n_good_matches = len([m for m in ia.desc_diffs if m < self.desc_diff_thresh])
        
          # Not enough matches, get a new keyframe
          if len(keyframe.kp)<2 or n_good_matches < len(keyframe.kp)/2.0 : 

            if DEBUG:
              print "New keyframe"

            # Make a new face model, either from a recent good frame, or from the current image
            if not self.same_key_rgfs[iface] :

              matched_z_list = [tz for ((tx,ty,tz),is_good) in zip(self.recent_good_frames[iface].kp,self.recent_good_frames[iface].good_matches) if is_good]
              if len(matched_z_list) == 0:
                matched_z_list = [tz for (tx,ty,tz) in self.recent_good_frames[iface].kp]
              avgd_goodmatches = sum(matched_z_list)/ len(matched_z_list)
              avg3d_goodmatches = self.cam.pix2cam(0.0,0.0,avgd_goodmatches)
              kp3d = [self.cam.pix2cam(kp[0],kp[1],kp[2]) for kp in self.recent_good_frames[iface].kp]
              print "kp ", self.recent_good_frames[iface].kp
              print "kp3d ",kp3d
              print avg3d_goodmatches
              kp3d_for_model = [this_kp3d for this_kp3d in kp3d if math.fabs(this_kp3d[2]-avg3d_goodmatches[2]) < 2.0*self.real_face_sizes_3d[iface] ]
              kp_for_model = [this_kp 
                              for (this_kp, this_kp3d) in zip(self.recent_good_frames[iface].kp, kp3d) 
                              if math.fabs(this_kp3d[2]-avg3d_goodmatches[2]) < 2.0*self.real_face_sizes_3d[iface] ]
              # If you're not left with enough points, just take all of them and don't worry about the depth constraints.
              if len(kp3d_for_model) < 2:
                kp3d_for_model = kp3d
                kp_for_model = copy.deepcopy(self.recent_good_frames[iface].kp)

              (cen, diff) = self.rect_to_center_diff(self.recent_good_rects[iface])
              self.feats_to_centers[iface] = self.make_face_model( cen, diff, [(kp0,kp1) for (kp0,kp1,kp2) in kp_for_model])

              avgd = sum([kp2 for (kp0,kp1,kp2) in kp_for_model])/len(kp_for_model)
              cen3d = self.cam.pix2cam(cen[0],cen[1],avgd)
              self.feats_to_centers_3d[iface] = self.make_face_model( cen3d, [self.real_face_sizes_3d[iface]]*3, kp3d_for_model)

              self.keyframes[self.current_keyframes[iface]] = copy.copy(self.recent_good_frames[iface])
              self.keyframes[self.current_keyframes[iface]].kp = kp_for_model
              self.keyframes[self.current_keyframes[iface]].kp2d = [(k0,k1) for (k0,k1,k2) in kp_for_model]
              self.keyframes[self.current_keyframes[iface]].kp3d = kp3d_for_model
              self.keyframes[self.current_keyframes[iface]].matches = [(i,i) for i in range(len(kp_for_model))]
              self.keyframes[self.current_keyframes[iface]].good_matches = [True]*len(kp_for_model)
              self.keyframes[self.current_keyframes[iface]].desc_diffs = [0]*len(kp_for_model)
              

              self.face_centers_3d[iface] = copy.deepcopy(cen3d)
              # Not changing the face size

              self.current_keyframes[iface] = 0 #### HACK: ONLY ONE KEYFRAME!!!

              self.same_key_rgfs[iface] = True
              # Don't need to change the recent good frame yet.

            else :

              # Making a new model off of the current frame but with the predicted new position. 
              # HACK: The displacement computation assumes that the robot/head is still, fix this.
              bad_frame = True
              #done_matching = True
              if DEBUG:
                print "Bad frame ", self.seq, " for face ", iface

              (cen,diff) = self.rect_to_center_diff(self.faces[iface])
              if DEBUG:
                print "Motion for bad frame ", self.recent_good_motion[iface], self.recent_good_motion_3d[iface]
              new_cen = [cen[0]+self.recent_good_motion[iface][0], cen[1]+self.recent_good_motion[iface][1]]
              diff = [diff[0]+self.recent_good_motion[iface][2], diff[1]+self.recent_good_motion[iface][2]]                 

              self.faces[iface] = (new_cen[0]-diff[0], new_cen[1]-diff[1], 2.0*diff[0], 2.0*diff[1])
              (x,y,w,h) = copy.deepcopy(self.faces[iface])

              pred_cen_3d = [o+n for (o,n) in zip(self.face_centers_3d[iface],self.recent_good_motion_3d[iface])]
              pred_cen_3d.append(1.0*self.real_face_sizes_3d[iface])  #### ZMULT
              self.get_features(ia, self.num_feats, (x,y,w,h), pred_cen_3d)
              if not ia.kp2d:
                break

              if DESCRIPTOR=='CALONDER':
                self.vo.collect_descriptors(ia)
              elif DESCRIPTOR=='SAD':
                self.vo.collect_descriptors_sad(ia)
              else:
                pass


              self.keyframes[self.current_keyframes[iface]] = copy.copy(ia)
              self.current_keyframes[iface] = 0
              (cen,diff) = self.rect_to_center_diff(self.faces[iface])
              self.feats_to_centers[iface] = self.make_face_model( cen, diff, ia.kp2d )
              cen3d = self.cam.pix2cam(cen[0],cen[1],ia.avgd)
              self.feats_to_centers_3d[iface] = self.make_face_model( cen3d, [self.real_face_sizes_3d[iface]]*3, ia.kp3d)
              self.face_centers_3d[iface] = copy.deepcopy(cen3d)
              self.same_key_rgfs[iface] = True

          # Good matches, mark this frame as good
          else:
            done_matching = True

          # END MATCHING


        # If we got enough matches for this frame, track.
        if ia.kp and ia.kp2d:

          # Track
          sparse_pred_list = []
          sparse_pred_list_2d = []
          probs = []
          bandwidths = []
          size_mult = 1.0
          for ((match1, match2), score) in zip(ia.matches, ia.desc_diffs):
            if score < self.desc_diff_thresh:
              kp3d = self.cam.pix2cam(ia.kp[match2][0],ia.kp[match2][1],ia.kp[match2][2])
              sparse_pred_list.append( (kp3d[0]+self.feats_to_centers_3d[iface][match1][0], 
                                        kp3d[1]+self.feats_to_centers_3d[iface][match1][1],
                                        kp3d[2]+self.feats_to_centers_3d[iface][match1][2]) )
              sparse_pred_list_2d.append( (ia.kp2d[match2][0]+self.feats_to_centers[iface][match1][0], ia.kp2d[match2][1]+self.feats_to_centers[iface][match1][1]) ) 
          probs = [1.0] * len(sparse_pred_list_2d)
          bandwidths = [size_mult*self.real_face_sizes_3d[iface]] * len(sparse_pred_list_2d)

          if DEBUG:
            print "Old center 3d ", self.face_centers_3d[iface]
            print "Old center 2d ",(x+(w-1)/2.0, y+(h-1)/2.0) 

          old_rect = self.faces[iface]
          (old_center, old_diff) = self.rect_to_center_diff(old_rect)
          new_center = self.mean_shift_sparse( self.face_centers_3d[iface], sparse_pred_list, probs, bandwidths, 10, 5.0 )
          new_center_2d = self.cam.cam2pix(new_center[0], new_center[1], new_center[2])
          ltf = self.cam.cam2pix( new_center[0]-self.real_face_sizes_3d[iface], new_center[1]-self.real_face_sizes_3d[iface], new_center[2])
          rbf = self.cam.cam2pix( new_center[0]+self.real_face_sizes_3d[iface], new_center[1]+self.real_face_sizes_3d[iface], new_center[2])
          w = rbf[0]-ltf[0]
          h = rbf[1]-ltf[1]       

          if DEBUG:
            print "new center 3d ", new_center
            print "new_center 2d ", new_center_2d

          (nx,ny,nw,nh) = (new_center_2d[0]-(w-1)/2.0, new_center_2d[1]-(h-1)/2.0, w, h)

          # Force the window back into the image.
          dx = max(0,0-nx) + min(0, im.width - nx+nw)
          dy = max(0,0-ny) + min(0, im.height - ny+nh)
          nx += dx
          ny += dy

          self.faces[iface] = [nx, ny, nw, nh]
          self.recent_good_rects[iface] = [nx,ny,nw,nh]
          if bad_frame:
            self.recent_good_motion[iface] = self.recent_good_motion[iface]
            self.recent_good_motion_3d[iface] = self.recent_good_motion_3d[iface]
          else:
            self.recent_good_motion[iface] = [new_center_2d[0]-old_center[0], new_center_2d[1]-old_center[1], ((nw-1.0)/2.0)-old_diff[0]]
            self.recent_good_motion_3d[iface] = [ new_center[i]-self.face_centers_3d[iface][i] for i in range(len(new_center))]
          self.face_centers_3d[iface] = copy.deepcopy(new_center)
          self.recent_good_frames[iface] = copy.copy(ia)
          self.same_key_rgfs[iface] = False


          if DEBUG:
            print "motion ", self.recent_good_motion[iface]
            print "face 2d ", self.faces[iface]
            print "face center 3d ", self.face_centers_3d[iface]


          # Output the location of this face center in the 3D camera frame (of the left camera), and rotate 
          # the coordinates to match the robot's idea of the 3D camera frame.
          center_uvd = (nx + (nw-1)/2.0, ny + (nh-1)/2.0, (numpy.average(ia.kp,0))[2] )
          center_camXYZ = self.cam.pix2cam(center_uvd[0], center_uvd[1], center_uvd[2])
          center_robXYZ = (center_camXYZ[2], -center_camXYZ[0], -center_camXYZ[1])

          ########### PUBLISH the face center for the head controller to track. ########
          if not self.usebag:
            stamped_point = PointStamped()
            (stamped_point.point.x, stamped_point.point.y, stamped_point.point.z) = center_robXYZ
            stamped_point.header.frame_id = "stereo"
            stamped_point.header.stamp = imarray.header.stamp
            self.pub.publish(stamped_point)
    

        # End later frames


      ############ DRAWING ################
      if SAVE_PICS:

        if not self.keyframes or len(self.keyframes) <= iface :
          bigim_py = im_py
          draw = ImageDraw.Draw(bigim_py)
        else :
          key_im = self.keyframes[self.current_keyframes[iface]]
          keyim_py = Image.fromstring("L", key_im.size, key_im.rawdata)
          bigim_py = Image.new("RGB",(im_py.size[0]+key_im.size[0], im_py.size[1]))
          bigim_py.paste(keyim_py.convert("RGB"),(0,0))
          bigim_py.paste(im_py,(key_im.size[0]+1,0))
          draw = ImageDraw.Draw(bigim_py)

          (x,y,w,h) = self.faces[iface]
          draw.rectangle((x,y,x+w,y+h),outline=(0,255,0))
          draw.rectangle((x+key_im.size[0],y,x+w+key_im.size[0],y+h),outline=(0,255,0))
          (x,y,w,h) = old_rect
          draw.rectangle((x,y,x+w,y+h),outline=(255,255,255))
          draw.rectangle((x+key_im.size[0],y,x+w+key_im.size[0],y+h),outline=(255,255,255))

          mstart = old_center
          mend = (old_center[0]+self.recent_good_motion[iface][0], old_center[1]+self.recent_good_motion[iface][1])
          draw.rectangle((mstart[0]-1,mstart[1]-1,mstart[0]+1,mstart[1]+1), outline=(255,255,255))
          draw.rectangle((mend[0]-1,mend[1]-1,mend[0]+1,mend[1]+1), outline=(0,255,0))
          draw.line(mstart+mend, fill=(255,255,255))

          for (x,y) in key_im.kp2d :
            draw_x(draw, (x,y), (1,1), (255,0,0))
          for (x,y) in ia.kp2d:
            draw_x(draw, (x+key_im.size[0],y), (1,1), (255,0,0))

          if self.seq > 0 :

            for (x,y) in sparse_pred_list_2d :
              draw_x(draw, (x,y), (1,1), (0,0,255))
              draw_x(draw, (x+key_im.size[0],y), (1,1), (0,0,255))

            if ia.matches:
              for ((m1,m2), score) in zip(ia.matches,ia.desc_diffs) :
                if score > self.desc_diff_thresh :
                  color = (255,0,0)
                else :
                  color = (0,255,0)
                draw.line((key_im.kp2d[m1][0], key_im.kp2d[m1][1], ia.kp2d[m2][0]+key_im.size[0], ia.kp2d[m2][1]), fill=color)
 

        bigim_py.save("/tmp/tiff/feats%06d_%03d.tiff" % (self.seq, iface))
        #END DRAWING


      # END FACE LOOP

    self.seq += 1
Пример #19
0
def load_from_dir(dir, selected_frames):
    afs = dict([(f,
                 SparseStereoFrame(Image.open("%s/left-%04d.ppm" % (dir, f)),
                                   Image.open("%s/right-%04d.ppm" % (dir, f))))
                for f in selected_frames])
    return afs
Пример #20
0
 def __init__(self, L, R, D, cam):
     SparseStereoFrame.__init__(self, L, R)
     self.D = D
     self.cam = cam
Пример #21
0
    else:
        fn = i
        im = Image.open("out%06d.png" % fn)
        imL, imR, _ = im.split()
        if use_magic_disparity:
            imD = [
                Image.open("out%06d-x.tiff" % fn),
                Image.open("out%06d-y.tiff" % fn),
                Image.open("out%06d-z.tiff" % fn)
            ]
        imL, imR = imR, imL
        imL = imL.transpose(Image.FLIP_LEFT_RIGHT)
        imR = imR.transpose(Image.FLIP_LEFT_RIGHT)
    if 1:
        for j, vo in enumerate(vos):
            f = SparseStereoFrame(imgStereo(imL), imgStereo(imR))
            #f = MagicStereoFrame(imgStereo(imL), imgStereo(imR), imD, stereo_cam)

            #f = PhonyFrame(~desired_pose, stereo_cam)
            #vo.lock_handle_frame(f)
            vo.handle_frame(f)
            #visualize.viz(vo, f)
            (x, y, z) = vo.pose.xform(0, 0, 0)
            if 0:
                print vo.name(), (x, y, z)
                (ex, ey, ez) = desired_pose.xform(0, 0, 0)
                Ys[j].append(z - ez)
            else:
                trajectory[j].append((x, y, z))

Пример #22
0
    from skeleton import Skeleton
    if 0:
        skel = Skeleton(cam)
        skel.node_vdist = 0
        skel.adaptive = False
    else:
        skel = None
    gt = []

    f = []
    for i in range(2100):  # range(1,146):
        dir = "/u/jamesb/ros/ros-pkg/vision/vslam/trial"
        L = Image.open("%s/%06dL.png" % (dir, i))
        R = Image.open("%s/%06dR.png" % (dir, i))
        nf = SparseStereoFrame(L, R)
        vo.setup_frame(nf)
        print i, "kp=", len(nf.kp)
        nf.id = len(f)
        if vt:
            vt.add(nf.lf, nf.descriptors)

        if skel:
            vo.handle_frame_0(nf)
            skel.add(vo.keyframe)
            vo.correct(skel.correct_frame_pose, nf)
            print len(gt), vo.inl
            gt.append(vo.pose.xform(0, 0, 0))
        else:
            pf = open("trial/%06d.pose.pickle" % i, "r")
            gt.append(pickle.load(pf))
Пример #23
0
    start, end = 0, 10

    if cam and topic.endswith("videre/images"):
        print framecounter
        if framecounter == end:
            break
        if start <= framecounter and (framecounter % 1) == 0:
            imgR = imgAdapted(msg.images[0])
            imgL = imgAdapted(msg.images[1])

            w, h = imgL.size
            comp = Image.new("RGB", (w * 2, h * 2))

            if 0:
                for i, vo in enumerate(vos):
                    af = SparseStereoFrame(imgL, imgR)
                    vo.handle_frame(af)
                    if 1:
                        leftframe = visualize.render_source_with_keypoints(
                            vo, af)
                        comp.paste(leftframe, (w * i, 0))
                        leftframe = visualize.render_text(vo, af)
                        comp.paste(leftframe, (w * i, h))
                    else:
                        if af.id == 0:
                            master_frame = af
                        else:
                            print "id", af.id, "inliers:", vo.inl, "proximity:", vo.proximity(
                                master_frame, af)
                        comp = visualize.render_source_with_keypoints_stats(
                            vo, af)
Пример #24
0
    ]
    vo_x = [ [] for i in vos]
    vo_y = [ [] for i in vos]
    vo_u = [ [] for i in vos]
    vo_v = [ [] for i in vos]
    trajectory = [ [] for i in vos]
    skel = Skeleton(cam)
    if skel_load_filename:
      skel.load(skel_load_filename)
      vos[0].num_frames = max(skel.nodes) + 1
      framecounter = max(skel.nodes) + 1
    oe_x = []
    oe_y = []
    oe_home = None
  for i,vo in enumerate(vos):
    af = SparseStereoFrame(l_image, r_image)
    vo.handle_frame(af)
    inl_history.append(vo.inl)
    inl_history = inl_history[-2:]
    af.connected = vo.inl > 7
    # Log keyframes into "pool_loop"
    if False and not vo.keyframe.id in keys:
      k = vo.keyframe
      Image.fromstring("L", (640,480), k.lf.tostring()).save("dump/%06dL.png" % len(keys))
      Image.fromstring("L", (640,480), k.rf.tostring()).save("dump/%06dR.png" % len(keys))
      print "saving frame", "id", k.id, "as key", len(keys), "inliers:", k.inl, "keypoints:", len(k.kp2d), len(k.kp)
      #vo.report_frame(k)
      keys.add(k.id)

    if max(inl_history) > 7:
      skel.setlabel(label)
Пример #25
0
    def frame(self, imarray):

        # No calibration params yet.
        if not self.vo:
            return

        if self.seq > 10000:
            sys.exit()
        if DEBUG:
            print ""
            print ""
            print "Frame ", self.seq
            print ""
            print ""

        im = imarray.images[1]
        im_r = imarray.images[0]
        if im.colorspace == "mono8":
            im_py = Image.fromstring("L", (im.width, im.height), im.data)
            im_r_py = Image.fromstring("L", (im_r.width, im_r.height),
                                       im_r.data)
        elif im.colorspace == "rgb24":
            use_color = True
            im_col_py = Image.fromstring("RGB", (im.width, im.height), im.data)
            im_py = im_col_py.convert("L")
            im_r_py = Image.fromstring("RGB", (im_r.width, im_r.height),
                                       im_r.data)
            im_r_py = im_r_py.convert("L")
        else:
            print "Unknown colorspace"
            return

        # Detect faces on the first frame
        if not self.current_keyframes:
            self.faces = self.p.detectAllFaces(im_py.tostring(), im.width,
                                               im.height, self.cascade_file,
                                               1.0, None, None, True)
            if DEBUG:
                print "Faces ", self.faces

        sparse_pred_list = []
        sparse_pred_list_2d = []
        old_rect = [0, 0, 0, 0]
        ia = SparseStereoFrame(im_py, im_r_py)
        ia.matches = []
        ia.desc_diffs = []
        ia.good_matches = []

        # Track each face
        iface = -1
        for face in self.faces:

            iface += 1

            (x, y, w, h) = copy.copy(self.faces[iface])
            if DEBUG:
                print "A face ", (x, y, w, h)

            (old_center, old_diff) = self.rect_to_center_diff((x, y, w, h))

            if self.face_centers_3d and iface < len(self.face_centers_3d):
                censize3d = list(copy.copy(self.face_centers_3d[iface]))
                censize3d.append(1.0 *
                                 self.real_face_sizes_3d[iface])  ###ZMULT
                self.get_features(ia, self.num_feats, (x, y, w, h), censize3d)
            else:
                self.get_features(ia, self.num_feats, (x, y, w, h),
                                  (0.0, 0.0, 0.0, 1000000.0))
            if not ia.kp2d:
                continue

            # First frame:
            if len(self.current_keyframes) < iface + 1:

                (cen, diff) = self.rect_to_center_diff((x, y, w, h))
                cen3d = self.cam.pix2cam(cen[0], cen[1], ia.avgd)
                ltf = self.cam.pix2cam(x, y, ia.avgd)
                rbf = self.cam.pix2cam(x + w, y + h, ia.avgd)
                fs3d = ((rbf[0] - ltf[0]) + (rbf[1] - ltf[1])) / 4.0

                # Check that the face is a reasonable size. If not, skip this face.
                if 2 * fs3d < self.min_real_face_size or 2 * fs3d > self.max_real_face_size or iface > 1:  #HACK: ONLY ALLOW ONE FACE
                    self.faces.pop(iface)
                    iface -= 1
                    continue

                if DESCRIPTOR == 'CALONDER':
                    self.vo.collect_descriptors(ia)
                elif DESCRIPTOR == 'SAD':
                    self.vo.collect_descriptors_sad(ia)
                else:
                    pass

                self.current_keyframes.append(0)
                self.keyframes.append(copy.copy(ia))

                self.feats_to_centers.append(
                    self.make_face_model(cen, diff, ia.kp2d))

                self.real_face_sizes_3d.append(copy.deepcopy(fs3d))
                self.feats_to_centers_3d.append(
                    self.make_face_model(cen3d, (fs3d, fs3d, fs3d), ia.kp3d))
                self.face_centers_3d.append(copy.deepcopy(cen3d))

                self.recent_good_frames.append(copy.copy(ia))
                self.recent_good_rects.append(copy.deepcopy([x, y, w, h]))
                self.recent_good_motion.append([0.0] * 3)  #dx,dy,dimfacesize
                self.recent_good_motion_3d.append([0.0] * 3)

                self.same_key_rgfs.append(True)

                # End first frame

            # Later frames
            else:
                if DESCRIPTOR == 'CALONDER':
                    self.vo.collect_descriptors(ia)
                elif DESCRIPTOR == 'SAD':
                    self.vo.collect_descriptors_sad(ia)
                else:
                    pass

                done_matching = False
                bad_frame = False
                while not done_matching:

                    # Try matching to the keyframe
                    keyframe = self.keyframes[self.current_keyframes[iface]]
                    temp_match = self.vo.temporal_match(ia,
                                                        keyframe,
                                                        want_distances=True)
                    ia.matches = [(m2, m1) for (m1, m2, m3) in temp_match]
                    ia.desc_diffs = [m3 for (m1, m2, m3) in temp_match]
                    print "Scores", ia.desc_diffs
                    #ia.matches = self.vo.temporal_match(keyframe,ia,want_distances=True)
                    #ia.desc_diffs = [(VO.sad(keyframe.descriptors[a], ia.descriptors[b])) for (a,b) in ia.matches]
                    ia.good_matches = [
                        s < self.desc_diff_thresh for s in ia.desc_diffs
                    ]

                    n_good_matches = len([
                        m for m in ia.desc_diffs if m < self.desc_diff_thresh
                    ])

                    # Not enough matches, get a new keyframe
                    if len(keyframe.kp) < 2 or n_good_matches < len(
                            keyframe.kp) / 2.0:

                        if DEBUG:
                            print "New keyframe"

                        # Make a new face model, either from a recent good frame, or from the current image
                        if not self.same_key_rgfs[iface]:

                            matched_z_list = [
                                tz for ((tx, ty, tz), is_good) in zip(
                                    self.recent_good_frames[iface].kp, self.
                                    recent_good_frames[iface].good_matches)
                                if is_good
                            ]
                            if len(matched_z_list) == 0:
                                matched_z_list = [
                                    tz
                                    for (tx, ty, tz
                                         ) in self.recent_good_frames[iface].kp
                                ]
                            avgd_goodmatches = sum(matched_z_list) / len(
                                matched_z_list)
                            avg3d_goodmatches = self.cam.pix2cam(
                                0.0, 0.0, avgd_goodmatches)
                            kp3d = [
                                self.cam.pix2cam(kp[0], kp[1], kp[2])
                                for kp in self.recent_good_frames[iface].kp
                            ]
                            print "kp ", self.recent_good_frames[iface].kp
                            print "kp3d ", kp3d
                            print avg3d_goodmatches
                            kp3d_for_model = [
                                this_kp3d for this_kp3d in kp3d
                                if math.fabs(this_kp3d[2] -
                                             avg3d_goodmatches[2]) < 2.0 *
                                self.real_face_sizes_3d[iface]
                            ]
                            kp_for_model = [
                                this_kp for (this_kp, this_kp3d) in zip(
                                    self.recent_good_frames[iface].kp, kp3d)
                                if math.fabs(this_kp3d[2] -
                                             avg3d_goodmatches[2]) < 2.0 *
                                self.real_face_sizes_3d[iface]
                            ]
                            # If you're not left with enough points, just take all of them and don't worry about the depth constraints.
                            if len(kp3d_for_model) < 2:
                                kp3d_for_model = kp3d
                                kp_for_model = copy.deepcopy(
                                    self.recent_good_frames[iface].kp)

                            (cen, diff) = self.rect_to_center_diff(
                                self.recent_good_rects[iface])
                            self.feats_to_centers[
                                iface] = self.make_face_model(
                                    cen, diff,
                                    [(kp0, kp1)
                                     for (kp0, kp1, kp2) in kp_for_model])

                            avgd = sum([
                                kp2 for (kp0, kp1, kp2) in kp_for_model
                            ]) / len(kp_for_model)
                            cen3d = self.cam.pix2cam(cen[0], cen[1], avgd)
                            self.feats_to_centers_3d[
                                iface] = self.make_face_model(
                                    cen3d,
                                    [self.real_face_sizes_3d[iface]] * 3,
                                    kp3d_for_model)

                            self.keyframes[
                                self.current_keyframes[iface]] = copy.copy(
                                    self.recent_good_frames[iface])
                            self.keyframes[self.current_keyframes[
                                iface]].kp = kp_for_model
                            self.keyframes[
                                self.current_keyframes[iface]].kp2d = [
                                    (k0, k1) for (k0, k1, k2) in kp_for_model
                                ]
                            self.keyframes[self.current_keyframes[
                                iface]].kp3d = kp3d_for_model
                            self.keyframes[
                                self.current_keyframes[iface]].matches = [
                                    (i, i) for i in range(len(kp_for_model))
                                ]
                            self.keyframes[
                                self.current_keyframes[iface]].good_matches = [
                                    True
                                ] * len(kp_for_model)
                            self.keyframes[self.current_keyframes[
                                iface]].desc_diffs = [0] * len(kp_for_model)

                            self.face_centers_3d[iface] = copy.deepcopy(cen3d)
                            # Not changing the face size

                            self.current_keyframes[
                                iface] = 0  #### HACK: ONLY ONE KEYFRAME!!!

                            self.same_key_rgfs[iface] = True
                            # Don't need to change the recent good frame yet.

                        else:

                            # Making a new model off of the current frame but with the predicted new position.
                            # HACK: The displacement computation assumes that the robot/head is still, fix this.
                            bad_frame = True
                            #done_matching = True
                            if DEBUG:
                                print "Bad frame ", self.seq, " for face ", iface

                            (cen, diff) = self.rect_to_center_diff(
                                self.faces[iface])
                            if DEBUG:
                                print "Motion for bad frame ", self.recent_good_motion[
                                    iface], self.recent_good_motion_3d[iface]
                            new_cen = [
                                cen[0] + self.recent_good_motion[iface][0],
                                cen[1] + self.recent_good_motion[iface][1]
                            ]
                            diff = [
                                diff[0] + self.recent_good_motion[iface][2],
                                diff[1] + self.recent_good_motion[iface][2]
                            ]

                            self.faces[iface] = (new_cen[0] - diff[0],
                                                 new_cen[1] - diff[1],
                                                 2.0 * diff[0], 2.0 * diff[1])
                            (x, y, w, h) = copy.deepcopy(self.faces[iface])

                            pred_cen_3d = [
                                o + n for (o, n) in zip(
                                    self.face_centers_3d[iface],
                                    self.recent_good_motion_3d[iface])
                            ]
                            pred_cen_3d.append(
                                1.0 *
                                self.real_face_sizes_3d[iface])  #### ZMULT
                            self.get_features(ia, self.num_feats, (x, y, w, h),
                                              pred_cen_3d)
                            if not ia.kp2d:
                                break

                            if DESCRIPTOR == 'CALONDER':
                                self.vo.collect_descriptors(ia)
                            elif DESCRIPTOR == 'SAD':
                                self.vo.collect_descriptors_sad(ia)
                            else:
                                pass

                            self.keyframes[
                                self.current_keyframes[iface]] = copy.copy(ia)
                            self.current_keyframes[iface] = 0
                            (cen, diff) = self.rect_to_center_diff(
                                self.faces[iface])
                            self.feats_to_centers[
                                iface] = self.make_face_model(
                                    cen, diff, ia.kp2d)
                            cen3d = self.cam.pix2cam(cen[0], cen[1], ia.avgd)
                            self.feats_to_centers_3d[
                                iface] = self.make_face_model(
                                    cen3d,
                                    [self.real_face_sizes_3d[iface]] * 3,
                                    ia.kp3d)
                            self.face_centers_3d[iface] = copy.deepcopy(cen3d)
                            self.same_key_rgfs[iface] = True

                    # Good matches, mark this frame as good
                    else:
                        done_matching = True

                    # END MATCHING

                # If we got enough matches for this frame, track.
                if ia.kp and ia.kp2d:

                    # Track
                    sparse_pred_list = []
                    sparse_pred_list_2d = []
                    probs = []
                    bandwidths = []
                    size_mult = 1.0
                    for ((match1, match2),
                         score) in zip(ia.matches, ia.desc_diffs):
                        if score < self.desc_diff_thresh:
                            kp3d = self.cam.pix2cam(ia.kp[match2][0],
                                                    ia.kp[match2][1],
                                                    ia.kp[match2][2])
                            sparse_pred_list.append(
                                (kp3d[0] +
                                 self.feats_to_centers_3d[iface][match1][0],
                                 kp3d[1] +
                                 self.feats_to_centers_3d[iface][match1][1],
                                 kp3d[2] +
                                 self.feats_to_centers_3d[iface][match1][2]))
                            sparse_pred_list_2d.append(
                                (ia.kp2d[match2][0] +
                                 self.feats_to_centers[iface][match1][0],
                                 ia.kp2d[match2][1] +
                                 self.feats_to_centers[iface][match1][1]))
                    probs = [1.0] * len(sparse_pred_list_2d)
                    bandwidths = [size_mult * self.real_face_sizes_3d[iface]
                                  ] * len(sparse_pred_list_2d)

                    if DEBUG:
                        print "Old center 3d ", self.face_centers_3d[iface]
                        print "Old center 2d ", (x + (w - 1) / 2.0,
                                                 y + (h - 1) / 2.0)

                    old_rect = self.faces[iface]
                    (old_center, old_diff) = self.rect_to_center_diff(old_rect)
                    new_center = self.mean_shift_sparse(
                        self.face_centers_3d[iface], sparse_pred_list, probs,
                        bandwidths, 10, 5.0)
                    new_center_2d = self.cam.cam2pix(new_center[0],
                                                     new_center[1],
                                                     new_center[2])
                    ltf = self.cam.cam2pix(
                        new_center[0] - self.real_face_sizes_3d[iface],
                        new_center[1] - self.real_face_sizes_3d[iface],
                        new_center[2])
                    rbf = self.cam.cam2pix(
                        new_center[0] + self.real_face_sizes_3d[iface],
                        new_center[1] + self.real_face_sizes_3d[iface],
                        new_center[2])
                    w = rbf[0] - ltf[0]
                    h = rbf[1] - ltf[1]

                    if DEBUG:
                        print "new center 3d ", new_center
                        print "new_center 2d ", new_center_2d

                    (nx, ny, nw, nh) = (new_center_2d[0] - (w - 1) / 2.0,
                                        new_center_2d[1] - (h - 1) / 2.0, w, h)

                    # Force the window back into the image.
                    dx = max(0, 0 - nx) + min(0, im.width - nx + nw)
                    dy = max(0, 0 - ny) + min(0, im.height - ny + nh)
                    nx += dx
                    ny += dy

                    self.faces[iface] = [nx, ny, nw, nh]
                    self.recent_good_rects[iface] = [nx, ny, nw, nh]
                    if bad_frame:
                        self.recent_good_motion[
                            iface] = self.recent_good_motion[iface]
                        self.recent_good_motion_3d[
                            iface] = self.recent_good_motion_3d[iface]
                    else:
                        self.recent_good_motion[iface] = [
                            new_center_2d[0] - old_center[0],
                            new_center_2d[1] - old_center[1],
                            ((nw - 1.0) / 2.0) - old_diff[0]
                        ]
                        self.recent_good_motion_3d[iface] = [
                            new_center[i] - self.face_centers_3d[iface][i]
                            for i in range(len(new_center))
                        ]
                    self.face_centers_3d[iface] = copy.deepcopy(new_center)
                    self.recent_good_frames[iface] = copy.copy(ia)
                    self.same_key_rgfs[iface] = False

                    if DEBUG:
                        print "motion ", self.recent_good_motion[iface]
                        print "face 2d ", self.faces[iface]
                        print "face center 3d ", self.face_centers_3d[iface]

                    # Output the location of this face center in the 3D camera frame (of the left camera), and rotate
                    # the coordinates to match the robot's idea of the 3D camera frame.
                    center_uvd = (nx + (nw - 1) / 2.0, ny + (nh - 1) / 2.0,
                                  (numpy.average(ia.kp, 0))[2])
                    center_camXYZ = self.cam.pix2cam(center_uvd[0],
                                                     center_uvd[1],
                                                     center_uvd[2])
                    center_robXYZ = (center_camXYZ[2], -center_camXYZ[0],
                                     -center_camXYZ[1])

                    ########### PUBLISH the face center for the head controller to track. ########
                    if not self.usebag:
                        stamped_point = PointStamped()
                        (stamped_point.point.x, stamped_point.point.y,
                         stamped_point.point.z) = center_robXYZ
                        stamped_point.header.frame_id = "stereo"
                        stamped_point.header.stamp = imarray.header.stamp
                        self.pub.publish(stamped_point)

                # End later frames

            ############ DRAWING ################
            if SAVE_PICS:

                if not self.keyframes or len(self.keyframes) <= iface:
                    bigim_py = im_py
                    draw = ImageDraw.Draw(bigim_py)
                else:
                    key_im = self.keyframes[self.current_keyframes[iface]]
                    keyim_py = Image.fromstring("L", key_im.size,
                                                key_im.rawdata)
                    bigim_py = Image.new(
                        "RGB", (im_py.size[0] + key_im.size[0], im_py.size[1]))
                    bigim_py.paste(keyim_py.convert("RGB"), (0, 0))
                    bigim_py.paste(im_py, (key_im.size[0] + 1, 0))
                    draw = ImageDraw.Draw(bigim_py)

                    (x, y, w, h) = self.faces[iface]
                    draw.rectangle((x, y, x + w, y + h), outline=(0, 255, 0))
                    draw.rectangle(
                        (x + key_im.size[0], y, x + w + key_im.size[0], y + h),
                        outline=(0, 255, 0))
                    (x, y, w, h) = old_rect
                    draw.rectangle((x, y, x + w, y + h),
                                   outline=(255, 255, 255))
                    draw.rectangle(
                        (x + key_im.size[0], y, x + w + key_im.size[0], y + h),
                        outline=(255, 255, 255))

                    mstart = old_center
                    mend = (old_center[0] + self.recent_good_motion[iface][0],
                            old_center[1] + self.recent_good_motion[iface][1])
                    draw.rectangle((mstart[0] - 1, mstart[1] - 1,
                                    mstart[0] + 1, mstart[1] + 1),
                                   outline=(255, 255, 255))
                    draw.rectangle(
                        (mend[0] - 1, mend[1] - 1, mend[0] + 1, mend[1] + 1),
                        outline=(0, 255, 0))
                    draw.line(mstart + mend, fill=(255, 255, 255))

                    for (x, y) in key_im.kp2d:
                        draw_x(draw, (x, y), (1, 1), (255, 0, 0))
                    for (x, y) in ia.kp2d:
                        draw_x(draw, (x + key_im.size[0], y), (1, 1),
                               (255, 0, 0))

                    if self.seq > 0:

                        for (x, y) in sparse_pred_list_2d:
                            draw_x(draw, (x, y), (1, 1), (0, 0, 255))
                            draw_x(draw, (x + key_im.size[0], y), (1, 1),
                                   (0, 0, 255))

                        if ia.matches:
                            for ((m1, m2),
                                 score) in zip(ia.matches, ia.desc_diffs):
                                if score > self.desc_diff_thresh:
                                    color = (255, 0, 0)
                                else:
                                    color = (0, 255, 0)
                                draw.line(
                                    (key_im.kp2d[m1][0], key_im.kp2d[m1][1],
                                     ia.kp2d[m2][0] + key_im.size[0],
                                     ia.kp2d[m2][1]),
                                    fill=color)

                bigim_py.save("/tmp/tiff/feats%06d_%03d.tiff" %
                              (self.seq, iface))
                #END DRAWING

            # END FACE LOOP

        self.seq += 1
Пример #26
0
    def display_array(self, iar):
        diag = ""
        af = None
        if self.vo:
            if not self.started:
                self.started = time.time()
            imgR = imgAdapted(iar.images[0])
            imgL = imgAdapted(iar.images[1])
            af = SparseStereoFrame(imgL, imgR)

            if 1:
                if self.mode == 'play':
                    pose = self.vo.handle_frame(af)
                if self.mode == 'learn':
                    pose = self.vo.handle_frame(af)
                    if (af.id != 0) and (self.vo.inl < 80):
                        print "*** LOST TRACK ***"
                        #sys.exit(1)
                    self.library.add(self.vo.keyframe)
                else:
                    #diag = "best match %d from %d in library" % (max(probes)[0], len(self.library))
                    pass
                diag = "%d/%d inliers, moved %.1f library size %d" % (
                    self.vo.inl, len(af.kp), pose.distance(), len(
                        self.library))

                if self.mode == 'play':
                    kf = self.vo.keyframe
                    if kf != self.previous_keyframe:
                        f = Frame()
                        f.id = kf.id
                        f.pose = Pose44(kf.pose.tolist())
                        f.keypoints = [
                            Keypoint(x, y, d) for (x, y, d) in kf.kp
                        ]
                        f.descriptors = [Descriptor(d) for d in kf.descriptors]
                        print "ASKING FOR MATCH AT", time.time()
                        self.vo_key_pub.publish(f)
                        self.previous_keyframe = kf
                        if kf.inl < 50 or self.vo.inl < 50:
                            self.know_state = 'lost'
                        else:
                            self.know_state = {
                                'lost': 'lost',
                                'uncertain': 'uncertain',
                                'corrected': 'uncertain'
                            }[self.know_state]

                result_pose = af.pose
                if self.mode == 'learn':
                    self.mymarker1.frompose(af.pose, self.vo.cam,
                                            (255, 255, 255))
                else:
                    if self.best_show_pose and self.know_state == 'lost':
                        inmap = self.best_show_pose
                    else:
                        Top = af.pose
                        Tmo = self.Tmo
                        inmap = Tmo * Top
                        if self.know_state != 'lost':
                            self.best_show_pose = inmap
                    if self.know_state != 'lost' or not self.best_show_pose:
                        color = {
                            'lost': (255, 0, 0),
                            'uncertain': (127, 127, 0),
                            'corrected': (0, 255, 0)
                        }[self.know_state]
                        self.mymarker1.frompose(inmap, self.vo.cam, color)
                        if 0:
                            self.trail.append(inmap)
                            self.trail = self.trail[-10:]
                            for i, p in enumerate(self.trail):
                                self.mymarkertrail[i].frompose(p, color)
                #print af.diff_pose.xform(0,0,0), af.pose.xform(0,0,0)

                if self.frame > 5 and ((self.frame % 10) == 0):
                    inliers = self.vo.pe.inliers()
                    pts = [(1, int(x0), int(y0))
                           for ((x0, y0, d0), (x1, y1, d1)) in inliers]
                    self.vis.show(iar.images[1].data, pts)

                if False and self.vo.pairs != []:
                    ls = Lines()
                    inliers = self.vo.pe.inliers()
                    lr = "left_rectified"
                    ls.lines = [
                        Line(lr, 0, 255, 0, x0, y0 - 2, x0, y0 + 2)
                        for ((x0, y0, d0), (x1, y1, d1)) in inliers
                    ]
                    ls.lines += [
                        Line(lr, 0, 255, 0, x0 - 2, y0, x0 + 2, y0)
                        for ((x0, y0, d0), (x1, y1, d1)) in inliers
                    ]
                    rr = "right_rectified"
                    #ls.lines += [ Line(rr, 0,255,0,x0-d0,y0-2,x0-d0,y0+2) for ((x0,y0,d0), (x1,y1,d1)) in inliers]
                    #ls.lines += [ Line(rr, 0,255,0,x0-2-d0,y0,x0+2-d0,y0) for ((x0,y0,d0), (x1,y1,d1)) in inliers]
                    self.viz_pub.publish(ls)

                if (self.frame % 30) == 0:
                    took = time.time() - self.started
                    print "%4d: %5.1f [%f fps]" % (self.frame, took,
                                                   self.frame / took), diag
                self.frame += 1

        #print "got message", len(iar.images)
        #print iar.images[0].width
        if SEE:
            right = ut.ros2cv(iar.images[0])
            left = ut.ros2cv(iar.images[1])
            hg.cvShowImage('channel L', left)
            hg.cvShowImage('channel R', right)
            hg.cvWaitKey(5)
Пример #27
0
    trajectory = [ [] for i in vos]

  start,end = 941,1000
  start,end = 0,2000

  if cam and topic.endswith("videre/images"):
    if framecounter == end:
      break
    if start <= framecounter and (framecounter % 1) == 0:
      imgR = imgAdapted(msg.images[0])
      imgL = imgAdapted(msg.images[1])
      if not first_pair:
        first_pair = (imgL, imgR)

      for i,vo in enumerate(vos):
        af = SparseStereoFrame(imgL, imgR)
        vo.handle_frame(af)
        x,y,z = vo.pose.xform(0,0,0)
        assert abs(x) < 20.0
        trajectory[i].append((x,y,z))
        vo_x[i].append(x)
        vo_y[i].append(z)
        x1,y1,z1 = vo.pose.xform(0,0,1)
        vo_u[i].append(x1 - x)
        vo_v[i].append(z1 - z)
      print framecounter
    framecounter += 1
  if topic.endswith("odom_estimation"):
    oe_x.append(-msg.pose.position.y)
    oe_y.append(msg.pose.position.x)
Пример #28
0
  def test_sim(self):
    # Test process with one 'ideal' camera, one real-world Videre
    camera_param_list = [
      # (200.0, 200.0, 3.00,  320.0, 320.0, 240.0),
      (389.0, 389.0, 1e-3 * 89.23, 323.42, 323.42, 274.95)
    ]
    def move_forward(i, prev):
      """ Forward 1 meter, turn around, Back 1 meter """
      if i == 0:
        return Pose(rotation(0,0,1,0), (0,0,0))
      elif i < 10:
        return prev * Pose(rotation(0,0,1,0), (0,0,.1))
      elif i < 40:
        return prev * Pose(rotation(math.pi / 30, 0, 1, 0), (0, 0, 0))
      elif i < 50:
        return prev * Pose(rotation(0,0,1,0), (0,0,.1))

    for movement in [ move_forward ]: # move_combo, move_Yrot ]:
      for cam_params in camera_param_list:
        cam = camera.Camera(cam_params)

        random.seed(0)
        def rr():
          return 2 * random.random() - 1.0
        model = [ (3 * rr(), 1 * rr(), 3 * rr()) for i in range(300) ]
        def rndimg():
          b = "".join(random.sample([ chr(c) for c in range(256) ], 64))
          return Image.fromstring("L", (8,8), b)
        def sprite(dst, x, y, src):
          try:
            dst.paste(src, (int(x)-4,int(y)-4))
          except:
            print "paste failed", x, y
        palette = [ rndimg() for i in model ]
        expected = []
        afs = []
        P = None
        for i in range(50):
          P = movement(i, P)
          li = Image.new("L", (640, 480))
          ri = Image.new("L", (640, 480))
          q = 0
          for (mx,my,mz) in model:
            pp = None
            pt_camera = (numpy.dot(P.M.I, numpy.array([mx,my,mz,1]).T))
            (cx,cy,cz,cw) = numpy.array(pt_camera).ravel()
            if cz > .100:
              ((xl,yl),(xr,yr)) = cam.cam2pixLR(cx, cy, cz)
              if 0 <= xl and xl < 640 and 0 <= yl and yl < 480:
                sprite(li, xl, yl, palette[q])
                sprite(ri, xr, yr, palette[q])
            q += 1
          expected.append(P)
          afs.append(SparseStereoFrame(imgStereo(li), imgStereo(ri)))

      vo = VisualOdometer(cam)
      for i,(af,ep) in enumerate(zip(afs, expected)):
        vo.handle_frame(af)
        if 0:
          print vo.pose.xform(0,0,0)
          print "expected", ep.M
          print "vo.pose", vo.pose.M
          print numpy.abs((ep.M - vo.pose.M))
        self.assert_(numpy.alltrue(numpy.abs((ep.M - vo.pose.M)) < 0.2))

      def run(vos):
        for af in afs:
          for vo in vos:
            vo.handle_frame(af)

      # Check that the pose estimators are truly independent

      v1 = VisualOdometer(cam, feature_detector = FeatureDetectorFast(), descriptor_scheme = DescriptorSchemeSAD(), inlier_error_threshold=1.0)
      v2 = VisualOdometer(cam, feature_detector = FeatureDetectorFast(), descriptor_scheme = DescriptorSchemeSAD(), inlier_error_threshold=2.0)
      v8 = VisualOdometer(cam, feature_detector = FeatureDetectorFast(), descriptor_scheme = DescriptorSchemeSAD(), inlier_error_threshold=8.0)
      v1a = VisualOdometer(cam, feature_detector = FeatureDetectorFast(), descriptor_scheme = DescriptorSchemeSAD(), inlier_error_threshold=1.0)
      run([v1])
      run([v2,v8,v1a])
      self.assert_(v1.pose.xform(0,0,0) == v1a.pose.xform(0,0,0))
      for a,b in [ (v1,v2), (v2,v8), (v1, v8) ]:
        self.assert_(a.pose.xform(0,0,0) != b.pose.xform(0,0,0))

      return