Пример #1
0
class DetectorNode:
    def __init__(self):
        self.posePublisher_front = rospy.Publisher('/pose_estimator/charger_pose/detection_front', PoseStamped,
                                                   queue_size=1)
        self.posePublisher_back = rospy.Publisher('/pose_estimator/charger_pose/detection_back', PoseStamped,
                                                  queue_size=1)
        self.keypointsPublisher = rospy.Publisher('/pose_estimator/keypoints', KeypointsWithCovarianceStamped,
                                                  queue_size=1)
        self.blackfly_topic = '/blackfly/camera/image_color/compressed'
        self.pointgrey_topic = '/pointgrey/camera/image_color/compressed'
        # self.camera_topic = '/video_player/compressed'
        self.imu_topic = '/xsens/data'
        self.gt_pose_topic = '/pose_estimator/charger_pose/location_gps'
        rospy.init_node('deep_pose_estimator', log_level=rospy.DEBUG)
        # path_to_model_bottom = "/root/share/tf/Keras/09_05_bottom_PP"
        path_to_model_bottom = "/root/share/tf/Keras/18_06_PP_4_wo_mask_bigger_head"
        # path_to_model_front = "/root/share/tf/Keras/24_08_4pts_1280_ROI560_5plus"
        # path_to_model_front = "/root/share/tf/Keras/07_08_4pts_960"
        path_to_model_front = "/root/share/tf/Keras/27_08_4pts_960_ROI960_pool_36"
        # path_to_model_front = "/root/share/tf/Keras/28_07_aug_960_blob"
        path_to_pole_model = os.path.join("/root/share/tf/Faster/pole/model_Inea_3", 'frozen_inference_graph.pb')
        self.equalize_histogram = False
        self.blackfly_camera_matrix = np.array([[4885.3110509, 0, 2685.5111516],
                                                [0, 4894.72687634, 2024.08742622],
                                                [0, 0, 1]]).astype(np.float64)
        # self.blackfly_camera_matrix = np.array([[ 4921.3110509, 0, 2707.5111516],
        #                                         [0, 4925.72687634, 1896.08742622],
        #                                         [0, 0, 1]]).astype(np.float64)
        self.blackfly_camera_distortion = (-0.14178835, 0.09305661, 0.00205776, -0.00133743)
        self.pointgrey_camera_matrix = np.array([[671.18360957, 0, 662.70347005],
                                                 [0, 667.94555172, 513.26149201],
                                                 [0, 0, 1]]).astype(np.float64)
        self.pointgrey_camera_distortion = (-0.04002205, 0.04100822, 0.00137423, 0.00464031, 0.0)

        # self.pitch = None
        # self.frame_pitch = None
        self.keypoints = None
        self.gt_keypoints = []
        # self.gt_keypoints_slice = []
        self.blackfly_image_msg = None
        self.blackfly_image = None
        self.pointgrey_image_msg = None
        self.pointgrey_image = None
        self.gt_pose = None
        # self.gt_mat = None
        self.frame_gt = None
        # self.frame_scale = None
        # Detection performance
        self.all_frames = 0
        self.frames_sent_to_detector = 0
        self.detected_frames = 0
        # Uncertainty estimation
        self.total_kp = 0
        self.prediction_errors = []
        # self.cov_matrices = np.empty((10, 10, 0), np.float)
        self.cov_matrices = np.empty((8, 8, 0), np.float)

        # Initialize detector
        self.pointgrey_frame_shape = (5, 5)  # self.get_image_shape(self.pointgrey_topic)
        # self.frame_shape = self.get_image_shape(self.blackfly_topic)
        # self.frame_shape = (1280, 1280)
        self.frame_shape = (960, 960)
        self.detector = Detector(path_to_model_front,
                                 path_to_pole_model)  # , path_to_model_bottom=path_to_model_bottom)
        self.detector.init_size(self.frame_shape)
        # self.detector.init_size((5000,5000))
        self.pose_estimator = PoseEstimator(self.blackfly_camera_matrix)

    def get_image_shape(self, camera_topic):
        im = rospy.wait_for_message(camera_topic, CompressedImage)
        np_arr = np.fromstring(im.data, np.uint8)
        image_shape = cv2.imdecode(np_arr, -1).shape[:2]
        return list(image_shape)

    def start(self):
        # rospy.Subscriber(self.blackfly_topic, CompressedImage, self.update_blackfly_image, queue_size=1)
        # rospy.Subscriber(self.pointgrey_topic, CompressedImage, self.update_pointgrey_image, queue_size=1)
        # rospy.Subscriber(self.imu_topic, Imu, self.get_pitch, queue_size=1)
        rospy.Subscriber(self.gt_pose_topic, PoseStamped, self.update_gt, queue_size=1)
        # rospy.wait_for_message(self.pointgrey_topic, CompressedImage)
        # rospy.wait_for_message(self.blackfly_topic, CompressedImage)
        # base_path = '/root/share/tf/dataset/14_08_4pts_960_ROI_448'
        base_path = '/root/share/tf/dataset/4_point_aug_960_centered/val/'
        # base_path = '/root/share/tf/dataset/4_point_aug_1280_centered/val/'
        images = os.listdir(os.path.join(base_path, 'annotations'))
        random.shuffle(images)
        # images.sort(reverse=False)
        images = iter(images)
        while not rospy.is_shutdown():
            self.gt_keypoints = []
            try:
                fname = next(images)
                # if 'train1' in fname:
                img_fname = base_path + 'images/' + fname[:-4] + '.png'
                ann_fname = base_path + 'annotations/' + fname
                # print(img_fname)

                tree = ET.parse(ann_fname)
                root = tree.getroot()
                if not os.path.exists(img_fname):
                    continue
                self.blackfly_image = cv2.imread(img_fname)
                # self.image = cv2.resize(image, None, fx=self.detector.scale, fy=self.detector.scale)
                # self.frame_shape = self.blackfly_image.shape[:2]
                # self.detector.init_size(self.frame_shape)
                # print("fr_sh", self.frame_shape)
                # label = cv2.imread(label_fname) * 255
                size = root.find('size')
                w = int(size.find('width').text)
                h = int(size.find('height').text)
                offset_x = int(root.find('offset_x').text)
                offset_y = int(root.find('offset_y').text)
                # print("offsets", offset_y, offset_x)
                for object in root.findall('object'):
                    scale = float(object.find('scale').text)
                    # print("scale", scale)
                    bbox = object.find('bndbox')
                    kps = object.find('keypoints')
                    # keypoints = []
                    # print(kps.find('keypoint6'))
                    for i in range(4):
                        kp = kps.find('keypoint' + str(i))
                        self.gt_keypoints.append(
                            (int(float(kp.find('x').text) * w), int((float(kp.find('y').text) * h))))
                    # for i, kp in enumerate(keypoints):
                    #     self.gt_keypoints.append(
                    #         ((int(kp[0] * w)), (int(kp[1] * h))))
            except StopIteration:
                # sum_cov_mtx = np.zeros((10, 10))
                sum_cov_mtx = np.zeros((8, 8))
                for single_img_pred in self.prediction_errors:
                    # print(np.average(self.kp_predictions, axis=0))
                    # single_img_error = single_img_pred - np.average(self.prediction_errors)
                    # print(single_img_pred.shape)
                    # print(np.transpose(single_img_pred).shape)
                    cov_matrix = np.matmul(single_img_pred, np.transpose(single_img_pred))
                    sum_cov_mtx += cov_matrix
                print(sum_cov_mtx / len(self.prediction_errors))
                break



            if self.blackfly_image is not None:  # and self.pointgrey_image is not None:
                self.frame_gt = self.gt_pose
                # self.frame_pitch = self.pitch
                # self.frame_scale = self.detector.scale
                k = cv2.waitKey(500)
                if k == ord('q') or k == 27:
                    exit(0)
                if k == ord('z'):
                    # sum_cov_mtx = np.zeros((10, 10))
                    sum_cov_mtx = np.zeros((8, 8))
                    for single_img_pred in self.prediction_errors:
                        # print("avg", np.average(self.prediction_errors, axis=0).shape, "\n",  np.average(self.prediction_errors, axis=0))
                        # single_img_error = single_img_pred - np.average(self.prediction_errors, axis=0)
                        # print("single_img_pred", single_img_pred.shape)
                        # print("single_img_error", single_img_error.shape)
                        # cov_matrices = np.matmul(single_img_error, np.transpose(single_img_error))
                        cov_matrices = np.matmul(single_img_pred, np.transpose(single_img_pred))
                        sum_cov_mtx += cov_matrices
                    print(sum_cov_mtx / len(self.prediction_errors))
                if self.detector.bottom:
                    self.detect(self.pointgrey_image, self.pointgrey_image_msg.header.stamp, self.frame_gt)
                else:
                    self.detect(self.blackfly_image, None, self.frame_gt)
                    # self.detect(self.blackfly_image, self.blackfly_image_msg.header.stamp, self.frame_gt)

        rospy.spin()

    # def get_pitch(self, imu_msg):
    #     quat = imu_msg.orientation
    #     quat = np.array([quat.x, quat.y, quat.z, quat.w], dtype=np.float64)
    #     r = Rotation.from_quat(quat)
    #     euler = r.as_euler('xyz')
    #     self.pitch = euler[1]

    def update_gt(self, gt_msg):
        self.gt_pose = gt_msg
        # self.gt_mat = np.identity(4)
        # self.gt_mat[0, 3] = self.gt_pose.pose.position.x
        # self.gt_mat[1, 3] = self.gt_pose.pose.position.y
        # self.gt_mat[2, 3] = self.gt_pose.pose.position.z

    def update_blackfly_image(self, image_msg):
        self.all_frames += 1
        self.blackfly_image_msg = image_msg
        self.frame_gt = self.gt_pose
        # self.frame_pitch = self.pitch
        np_arr = np.fromstring(image_msg.data, np.uint8)
        image = cv2.imdecode(np_arr, -1)
        image = cv2.undistort(image, self.blackfly_camera_matrix, self.blackfly_camera_distortion)
        # cv2.imwrite("/root/share/tf/image.png", image)
        # self.frame_shape = list(image.shape[:2])
        if self.equalize_histogram:
            img_yuv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
            img_yuv[:, :, 2] = cv2.equalizeHist(img_yuv[:, :, 2])
            image = cv2.cvtColor(img_yuv, cv2.COLOR_HSV2BGR)
        self.blackfly_image = image
        # self.blackfly_image = cv2.resize(image, None, fx=self.detector.scale, fy=self.detector.scale)

    def update_pointgrey_image(self, image_msg):
        self.pointgrey_image_msg = image_msg
        self.frame_gt = self.gt_pose
        # self.frame_pitch = self.pitch
        np_arr = np.fromstring(image_msg.data, np.uint8)
        image = cv2.imdecode(np_arr, -1)
        # print(image.shape)
        image = cv2.undistort(image, self.pointgrey_camera_matrix, self.pointgrey_camera_distortion)
        # self.pointgrey_frame_shape = list(image.shape[:2])
        self.pointgrey_image = cv2.rotate(image, cv2.ROTATE_90_CLOCKWISE)  # cv2.resize(image, None, fx=0.7, fy=0.7)

    def detect(self, frame, stamp, gt_pose):
        start_time = time.time()
        disp = np.copy(frame)
        working_copy = np.copy(frame)
        self.detector.detect(working_copy, gt_pose, self.gt_keypoints)
        self.frames_sent_to_detector += 1
        if self.detector.best_detection is not None:
            self.keypoints = self.detector.best_detection['keypoints']
            # color = (255, 255, 255)
            for i, pt in enumerate(self.gt_keypoints):
            #     if i == 0:
            #         color = (255, 255, 255)
            #     elif i == 1:
            #         color = (255, 0, 0)
            #     elif i == 2:
            #         color = (0, 255, 0)
            #     elif i == 3:
            #         color = (0, 255, 255)
            #     else:
            #         color = (255, 0, 255)
            cv2.circle(disp, (int(pt[0]), int(pt[1])), 10, (255, 255, 255), -1)
            # cv2.imshow("GT", disp)
            cv2.waitKey(10)
            self.detected_frames += 1
            if self.detector.bottom:
                camera_matrix = self.pointgrey_camera_matrix
            else:
                camera_matrix = self.blackfly_camera_matrix
            if self.detector.best_detection['score'] > 0.5:
                # self.keypoints = np.multiply(self.keypoints, 1 / self.detector.scale)
                self.publish_keyponts(stamp)
                # self.publish_pose(stamp, camera_matrix)
                # self.detector.scale = 1.0
        self.blackfly_image = None
        print("detection time:", time.time() - start_time)

    def publish_pose(self, stamp, camera_matrix):
        tvec, rvec = self.pose_estimator.calc_PnP_pose(self.keypoints, camera_matrix)
        rot = Rotation.from_rotvec(np.squeeze(rvec))
        out_msg = PoseStamped()
        out_msg.header.stamp = stamp
        out_msg.header.frame_id = "camera"
        out_msg.pose.position.x = tvec[0]
        out_msg.pose.position.y = tvec[1]
        out_msg.pose.position.z = tvec[2]
        np_quat = rot.as_quat()
        ros_quat = Quaternion(np_quat[0], np_quat[1], np_quat[2], np_quat[3])

        out_msg.pose.orientation = ros_quat
        if self.detector.bottom:
            self.posePublisher_back.publish(out_msg)
        else:
            self.posePublisher_front.publish(out_msg)

    def publish_keyponts(self, stamp):
        # out_msg = KeypointsWithCovarianceStamped()
        # out_msg.header.stamp = stamp
        # out_msg.keypoints = []
        # out_msg.covariance = []
        # for idx, kp in enumerate(self.keypoints):
        #     if idx == 2:
        #         out_msg.keypoints.append(self.keypoints[4][0])
        #         out_msg.keypoints.append(self.keypoints[4][1])
        #     if idx == 4:
        #         continue
        #     out_msg.keypoints.append(kp[0])
        #     out_msg.keypoints.append(kp[1])
        # cov_mx = np.array(self.detector.best_detection["uncertainty"])
        # for idx, cm in enumerate(cov_mx):
        #     if idx == 2:
        #         for itm in cm.flatten():
        #             out_msg.covariance.append(itm)
        #     if idx == 4:
        #         continue
        #     for itm in cm.flatten():
        #         out_msg.covariance.append(itm)
        # print(out_msg.keypoints)
        # self.keypointsPublisher.publish(out_msg)

        # out_msg = Float64MultiArray()
        # for idx, kp in enumerate(self.keypoints):
        #     if idx == 2:
        #         out_msg.data.append(self.keypoints[4][0])
        #         out_msg.data.append(self.keypoints[4][1])
        #     if idx == 4:
        #         continue
        #     out_msg.data.append(kp[0])
        #     out_msg.data.append(kp[1])
        # cov_mx = np.array(self.detector.best_detection["uncertainty"])
        # for idx, cm in enumerate(cov_mx):
        #     if idx == 2:
        #         for itm in cm.flatten():
        #             out_msg.data.append(itm)
        #     if idx == 4:
        #         continue
        #     for itm in cm.flatten():
        #         out_msg.data.append(itm)
        # print(out_msg.data)
        # self.keypointsPublisher.publish(out_msg)

        def calc_dist(x, z):
            # return math.sqrt((x[0]-z[0]) ** 2 + (x[1]-z[1]) ** 2)
            return abs(x[0] - z[0]), abs(x[1] - z[1])

        single_img_pred = []
        for idx, kp in enumerate(self.keypoints):
            # print(len(self.gt_keypoints))
            # print("kp", len(self.keypoints))
            if calc_dist(kp, self.gt_keypoints[idx])[1] > 150:
                return
            single_img_pred.append(calc_dist(kp, self.gt_keypoints[idx]))
        self.prediction_errors.append(
            np.array(single_img_pred).reshape((8, 1)))  # calc_dist(kp, self.gt_keypoints[idx]))


if __name__ == '__main__':
    det_node = DetectorNode()
    det_node.start()