示例#1
0
class CameraSensor:
    def __init__(self, cli):
        #self.yolo = YOLO("./yolo-coco/coco.names","./yolo-coco/yolov3.weights",
        self.yolo = YOLO("./yolo-coco/coco.names","./yolo-coco/yolov3.weights",
        "./yolo-coco/yolov3.cfg",0.5,0.3)
        self.last_im = np.zeros((320,240,3), np.uint8)
        self.updated = False
        self.cli = cli
        self.cli.add_handler(pycozmo.event.EvtNewRawCameraImage, self.on_camera_image)
        #self.target = target


    def on_camera_image(self, cli, new_im):
        """ Handle new images, coming from the robot. """
        del cli

        # from: https://stackoverflow.com/a/14140796
        open_cv_image = np.array(new_im) 
        # Convert RGB to BGR 
        self.last_im = open_cv_image[:, :, ::-1].copy()

        self.updated = True

    def find_target(self):
        if self.updated:
            # Get last image.
            self.updated = False
            # YOLO
            detect_im = self.yolo.analyze_image(self.last_im.copy())

            # TODO: understand the yolo enough to know if it actually found our target in the image...
            # If the target is in the image...
            # if ()
            #     return True
            # else:
            #     return False

        else:
            return False


    def get_offset(self):
        # TODO: calculate some kind of offset for the target from center of image
        # Do the stuff to get the offset from center 
        # Positive => right of center, negative => left of center
        return 1.0
示例#2
0
def pycozmo_program(cli: pycozmo.client.Client):

    global last_im, updated, analysis_method

    if (analysis_method == "yolo"):
        yolo = YOLO("./yolo-coco/coco.names", "./yolo-coco/yolov3.weights",
                    "./yolo-coco/yolov3.cfg", 0.5, 0.3)

    # activate the pygame library .
    # initiate pygame and give permission
    # to use pygame's functionality.
    pygame.init()

    # define the RGB value
    # for white colour
    white = (255, 255, 255)

    # assigning values to X and Y variable
    X = 320
    Y = 480

    # create the display surface object
    # of specific dimension..e(X, Y).
    display_surface = pygame.display.set_mode((X, Y))

    # set the pygame window name
    pygame.display.set_caption('Image')

    # Raise head.
    angle = (pycozmo.robot.MAX_HEAD_ANGLE.radians -
             pycozmo.robot.MIN_HEAD_ANGLE.radians) / 2.0
    cli.set_head_angle(0)  #angle)

    pkt = pycozmo.protocol_encoder.EnableCamera()
    cli.conn.send(pkt)
    pkt = pycozmo.protocol_encoder.EnableColorImages(enable=True)
    cli.conn.send(pkt)

    # Wait for image to stabilize.
    time.sleep(2.0)

    # Register to receive new camera images.
    cli.add_handler(pycozmo.event.EvtNewRawCameraImage, on_camera_image)

    # Enable camera.
    #pkt = pycozmo.protocol_encoder.EnableCamera()
    #cli.conn.send(pkt)

    # MANUAL DISTANCE CALIBRATIONS
    calibrated = False
    # calibration: distance from cozmo to object (inches)
    KNOWN_DISTANCE = 12.0
    # calibration: width of your object of interest (inches)
    KNOWN_WIDTH = 1.0

    fgbg = cv2.createBackgroundSubtractorMOG2(history=10,
                                              varThreshold=2,
                                              detectShadows=False)

    while True:

        if updated:

            # Get last image.
            im = last_im
            updated = False

            # completely fill the surface object
            # with white colour
            display_surface.fill(white)

            if (analysis_method == "yolo"):
                grnd, edges = CheckGround(last_im.copy())
                detect_im = yolo.analyze_image(grnd.copy())
                im_both = np.vstack((last_im, detect_im))

            elif (analysis_method == "ground"):
                grnd, edges = CheckGround(last_im.copy())
                im_both = np.vstack((last_im, grnd))

                im2 = last_im.copy()
                gray = cv2.cvtColor(im2, cv2.COLOR_BGR2GRAY)

                # filtering https://www.sicara.ai/blog/2019-03-12-edge-detection-in-opencv
                filtered = cv2.bilateralFilter(gray, 7, 50, 50)
                foreground = fgbg.apply(filtered)

                kernel = np.ones((50, 50), np.uint8)
                foreground = cv2.morphologyEx(foreground, cv2.MORPH_CLOSE,
                                              kernel)

                # edge detection
                edges = cv2.Canny(filtered, 100, 200)

                # Crop off moving area
                cropped = (foreground // 255) * edges

                # convex hull from edge detection
                contours, hierarchy = cv2.findContours(edges, cv2.RETR_LIST,
                                                       cv2.CHAIN_APPROX_SIMPLE)
                for c in contours:
                    hull = cv2.convexHull(c)
                    cv2.drawContours(im2, [hull], 0, (0, 255, 0), 2)

                im_both = np.vstack((last_im, im2))

                # DISTANCE DETECTION
                # referenced https://www.pyimagesearch.com/2015/01/19/find-distance-camera-objectmarker-using-python-opencv/
                # create a list of contours to work with
                boxContours = cv2.findContours(edges.copy(), cv2.RETR_LIST,
                                               cv2.CHAIN_APPROX_SIMPLE)
                boxContours = imutils.grab_contours(boxContours)

                # try finding the contour with the largest area
                try:
                    # using the boxContours list, finds biggest in terms of area, fits rect to that area
                    target = max(boxContours, key=cv2.contourArea)
                    targetBox = cv2.minAreaRect(target)

                    # get a calibrated focal length for cozmo camera, first pass only
                    if calibrated == False:
                        focalLength = (targetBox[1][0] *
                                       KNOWN_DISTANCE) / KNOWN_WIDTH
                        calibrated = True

                    # find distance to object based on:
                    # manually set KNOWN_WIDTH (earlier in code, starting contour width)
                    # focalLength (calculated on the first pass, scale factor)
                    # targetBox[1][0], which is this frame's contour width
                    # scale factor * (starting width / current width)
                    currentDistance = focalLength * (KNOWN_WIDTH /
                                                     targetBox[1][0])

                    # draw bounding box
                    box = cv2.boxPoints(targetBox)
                    box = np.int0(box)
                    boxImg = cv2.drawContours(grnd.copy(), [box], -1,
                                              (255, 255, 150), 2)

                    # add text below the bounding box
                    cv2.putText(boxImg, "%.2fin" % (currentDistance),
                                (boxImg.shape[1] - 200, boxImg.shape[0] - 20),
                                cv2.FONT_HERSHEY_SIMPLEX, 1.0, (255, 255, 150),
                                2)

                    im_both = np.vstack((last_im, boxImg))

                # if no contours are available
                except ValueError:
                    print("No object detected")

            # copying the image surface object
            # to the display surface object at
            # (0, 0) coordinate.
            display_surface.blit(cv2ImageToSurface(im_both), (0, 0))
            #display_surface.blit(cv2ImageToSurface(grnd), (0,240))
            # Draws the surface object to the screen.
            pygame.display.update()

        # iterate over the list of Event objects
        # that was returned by pygame.event.get() method.
        for event in pygame.event.get():

            # if event object type is QUIT
            # then quitting the pygame
            # and program both.
            if event.type == pygame.QUIT:

                # deactivates the pygame library
                pygame.quit()

                # quit the program.
                quit()

        # Run with 25 FPS.
        time.sleep(1 / 25)
def pycozmo_program(cli: pycozmo.client.Client):

    global last_im, updated

    yolo = YOLO("./yolo-coco/coco.names", "./yolo-coco/yolov3.weights",
                "./yolo-coco/yolov3.cfg", 0.5, 0.3)

    # activate the pygame library .
    # initiate pygame and give permission
    # to use pygame's functionality.
    pygame.init()

    # define the RGB value
    # for white colour
    white = (255, 255, 255)

    # assigning values to X and Y variable
    X = 320
    Y = 480

    # create the display surface object
    # of specific dimension..e(X, Y).
    display_surface = pygame.display.set_mode((X, Y))

    # set the pygame window name
    pygame.display.set_caption('Image')

    # Raise head.
    angle = (pycozmo.robot.MAX_HEAD_ANGLE.radians -
             pycozmo.robot.MIN_HEAD_ANGLE.radians) / 4.0
    cli.set_head_angle(angle)

    pkt = pycozmo.protocol_encoder.EnableCamera()
    cli.conn.send(pkt)
    pkt = pycozmo.protocol_encoder.EnableColorImages(enable=True)
    cli.conn.send(pkt)

    # Wait for image to stabilize.
    time.sleep(2.0)

    # Register to receive new camera images.
    cli.add_handler(pycozmo.event.EvtNewRawCameraImage, on_camera_image)

    while True:

        if updated:

            # Get last image.
            #im = last_im.copy()
            updated = False

            #cv2.imshow('Frame',im)
            detect_im = yolo.analyze_image(last_im.copy())
            #cv2.imshow('Found',detect_im)
            im_both = np.vstack((last_im, detect_im))
            # completely fill the surface object
            # with white colour
            display_surface.fill(white)

            # copying the image surface object
            # to the display surface object at
            # (0, 0) coordinate.
            display_surface.blit(cv2ImageToSurface(im_both), (0, 0))
            #display_surface.blit(cv2ImageToSurface(im), (0,240))
            # Draws the surface object to the screen.
            pygame.display.update()

        # iterate over the list of Event objects
        # that was returned by pygame.event.get() method.
        for event in pygame.event.get():

            # if event object type is QUIT
            # then quitting the pygame
            # and program both.
            if event.type == pygame.QUIT:

                # deactivates the pygame library
                pygame.quit()

                # quit the program.
                quit()

        # Run with 25 FPS.
        time.sleep(1 / 25)