def METHOD_NAME(self, msg: Image):
    # webots: 480x640x4pixels
    if self.robot_state.status not in [
        RobotState.STATUS_LOCALIZING,
        RobotState.STATUS_READY,
        RobotState.ROLE_UNASSIGNED,
    ]:
        return
    if self.game_state.gameState != GameState.GAMESTATE_PLAYING:
        return
    rospy.loginfo_once("Object Detection Receiving image")
    # width x height x channels (bgra8)
    image = self.br.imgmsg_to_cv2(msg)
    self.camera.reset_position(timestamp=msg.header.stamp)
    # cover horizon to help robot ignore things outside field
    cover_horizon_up_threshold = rospy.get_param("cover_horizon_up_threshold", 30)
    h = max(self.camera.calculateHorizonCoverArea() - cover_horizon_up_threshold, 0)
    if image is not None:
        # 1. preprocess image
        img = image[:, :, :3]  # get rid of alpha channel
        img = img[..., ::-1]  # convert bgr to rgb
        img = img[max(0, h + 1) :, :]
        # 2. inference
        results = self.model(img)
        bbs_msg = BoundingBoxes()
        id = 0
        for prediction in results.xyxy[0]:
            x1, y1, x2, y2, confidence, img_class = prediction.cpu().numpy()
            y1 += h + 1
            y2 += h + 1
            if img_class in [label.value for label in Label] and confidence > self.CONFIDENCE_THRESHOLD:
                bb_msg = BoundingBox()
                bb_msg.xmin = round(x1)  # top left of bounding box
                bb_msg.ymin = round(y1)
                bb_msg.xmax = round(x2)  # bottom right of bounding box
                bb_msg.ymax = round(y2)
                bb_msg.probability = confidence
                bb_msg.id = id
                bb_msg.Class = str(int(img_class))
                # TODO Joanne look the pixels of the image in addition to the bounding box,
                #  calculate likely foot coordinate xy
                if bb_msg.Class == "2":
                    # --- simple version just draw the box in bottom ratio of box to detect feet position---
                    # only look at bottom 1/3 of bounding box (assumption: bounding box is of a standing robot)
                    # Calculate ymin value to start checking for black pixels
                    if bb_msg.ymax < self.camera.resolution_y - 5:
                        temp_ymin = round(bb_msg.ymax * 0.85 + bb_msg.ymin * 0.15)
                        midpoint = [(bb_msg.xmax + bb_msg.xmin) / 2, (bb_msg.ymax + temp_ymin) / 2]
                        bb_msg.ybase = round(midpoint[1])
                        bb_msg.xbase = round(midpoint[0])
                        bb_msg.obstacle_detected = True
                bbs_msg.bounding_boxes.append(bb_msg)
                id += 1
        bbs_msg.header = msg.header
        try:
            if self.pub_detection.get_num_connections() > 0:
                detection_image = np.squeeze(results.render())
                detection_image = np.concatenate((np.zeros((h + 1, msg.width, 3), detection_image.dtype), detection_image))
                detection_image = detection_image[..., ::-1]  # convert rgb to bgr
                self.pub_detection.publish(self.br.cv2_to_imgmsg(detection_image, encoding="bgr8"))
            if self.pub_boundingbox.get_num_connections() > 0 and len(bbs_msg.bounding_boxes) > 0:
                self.pub_boundingbox.publish(bbs_msg)
        except ROSException as re:
            print(re)
            exit(0)