Exemple #1
0
 def __init__(self, board_width, resource_path, start_path):
     self.board_width = board_width
     self.cube_size = 1
     self.start_path = start_path
     self.resource_path = resource_path
     optional_path = "3d_cube_with_ar/"
     required_path = "font/white_rabbit_numbers.jpg"
     self.font = cv.imread("%s%s%s" %
                           (start_path, optional_path, required_path))
     font_six_points = [[16, 20], [80, 80]]
     blue_tint = np.empty(self.font.shape, dtype=np.uint8)
     blue_tint[:, :] = (155, 155, 0)
     self.font[16:16 + 80,
               20:20 + 80] = cv.subtract(self.font[16:16 + 80, 20:20 + 80],
                                         blue_tint[16:16 + 80, 20:20 + 80])
     self.font_inv = cv.bitwise_not(self.font)
     font_one_points = [[16, 155], [80, 80]]
     font_two_points = [[20, 155 + 80 + 50], [80, 80]]
     font_three_points = [[20, 155 + (80 + 50) * 2], [80, 80]]
     font_four_points = [[22, 155 + (80 + 50) * 3 - 5], [80, 80]]
     font_five_points = [[22, 155 + (80 + 50) * 4 - 10], [80, 80]]
     self.font_point = np.array([
         font_one_points, font_two_points, font_three_points,
         font_four_points, font_five_points, font_six_points
     ])
     self.draw_cube = DrawCube(resource_path)
     self.common_core = CommonCore(None)
Exemple #2
0
  def GET(self, grade):
    grade = parse_int_param(grade, 5)
    common_core = CommonCore()
    data = common_core.get_grade(grade)
    if not data:
      logging.warn('Cannot find data for grade %d' % grade)
      return error_response(404)

    try:
      grade_json = encode_json(data)
      return grade_json
    except Exception, e:
      logging.error(e)
      return error_response(500)
Exemple #3
0
# 2 should work and disagree with 3
# 3 should work and disagree with 2
# 4 should work and disagree with 5
# 5 should work and disagree with 4
# 6 should work and agree with 7
# 7 should work and agree with 6
pictures = [['opencv_frame_0_0.png', 'opencv_frame_0_1.png'],
            ['opencv_frame_7_0.png', 'opencv_frame_7_1.png'],
            ['opencv_frame_7_1.png', 'opencv_frame_7_0.png'],
            ['opencv_frame_5_0.png', 'opencv_frame_5_1.png']]

board_width = 7
board_size = (board_width, board_width)

draw_cube = DrawCube(resources_path)
common_core = CommonCore(board_size)
ar_input = ArInput(board_width, resources_path, '')
board_rotation_f1 = BoardRotation()
board_rotation_f2 = BoardRotation()


def analyze_image_and_add_ar(frame_1, frame_2):
    # frame_1 is suggestion and display frame, frame_2 is confirm frame
    img_1 = frame_1
    chessboard_img_1, corners1_1, ret_1 = common_core.find_chessboard_corners_1(
        img_1)

    # fail program if points not found
    if not ret_1:
        frame_wait_cnt = 10
        print('1st checkerboard NOT detected, wait %s frames' %
Exemple #4
0
class ArInput:
    def __init__(self, board_width, resource_path, start_path):
        self.board_width = board_width
        self.cube_size = 1
        self.start_path = start_path
        self.resource_path = resource_path
        optional_path = "3d_cube_with_ar/"
        required_path = "font/white_rabbit_numbers.jpg"
        self.font = cv.imread("%s%s%s" %
                              (start_path, optional_path, required_path))
        font_six_points = [[16, 20], [80, 80]]
        blue_tint = np.empty(self.font.shape, dtype=np.uint8)
        blue_tint[:, :] = (155, 155, 0)
        self.font[16:16 + 80,
                  20:20 + 80] = cv.subtract(self.font[16:16 + 80, 20:20 + 80],
                                            blue_tint[16:16 + 80, 20:20 + 80])
        self.font_inv = cv.bitwise_not(self.font)
        font_one_points = [[16, 155], [80, 80]]
        font_two_points = [[20, 155 + 80 + 50], [80, 80]]
        font_three_points = [[20, 155 + (80 + 50) * 2], [80, 80]]
        font_four_points = [[22, 155 + (80 + 50) * 3 - 5], [80, 80]]
        font_five_points = [[22, 155 + (80 + 50) * 4 - 10], [80, 80]]
        self.font_point = np.array([
            font_one_points, font_two_points, font_three_points,
            font_four_points, font_five_points, font_six_points
        ])
        self.draw_cube = DrawCube(resource_path)
        self.common_core = CommonCore(None)

    def update_cube_size(self, new_cube_size):
        self.cube_size = new_cube_size

    def look_for_cube_size_v1(self, img, corners):
        cube_return = self.cube_size
        self.cube_size = (self.cube_size % 6) + 1
        return cube_return

    def look_for_cube_size_v2(self, img, corners2, draw_buttons=True):

        hue, sat, val = cv.split(cv.cvtColor(img, cv.COLOR_BGR2HSV))
        image_sums = np.zeros((6, 2), dtype=np.int32)

        greatest_sum = 0
        greatest_sum_roi_corners = -1

        for square in range(6):
            # acquire points from corners to use for ar buttons
            first_bad_format = corners2[self.board_width * square, 0]
            second_bad_format = corners2[self.board_width * square + 1, 0]
            third_bad_format = corners2[self.board_width * (square + 1) + 1, 0]
            fourth_bad_format = corners2[self.board_width * (square + 1), 0]
            first = (first_bad_format[0], first_bad_format[1])
            fourth = (fourth_bad_format[0], fourth_bad_format[1])
            second = (int(first[0] * 2 - second_bad_format[0]),
                      int(first[1] * 2 - second_bad_format[1]))
            third = (int(fourth[0] * 2 - third_bad_format[0]),
                     int(fourth[1] * 2 - third_bad_format[1]))

            # put points into arrays for use below
            roi_corners_for_mask = np.array([[first, second, third, fourth]],
                                            dtype=np.int32)
            roi_corners = np.array([[third], [second], [first], [fourth]],
                                   dtype=np.int32)

            # create mask with polygon
            mask = np.zeros(sat.shape, dtype=np.uint8)
            # channel_count = sat.shape[2]
            channel_count = 1
            ignore_mask_color = (255, ) * channel_count
            cv.fillPoly(mask, roi_corners_for_mask, ignore_mask_color)

            x_min, y_min, x_max, y_max = self.common_core.sort_points_for_extremes(
                roi_corners_for_mask)
            # smooth image
            sat[y_min:y_max,
                x_min:x_max] = cv.medianBlur(sat[y_min:y_max, x_min:x_max], 9)
            val[y_min:y_max,
                x_min:x_max] = cv.medianBlur(val[y_min:y_max, x_min:x_max], 9)

            # black out all area outside roi_corners
            masked_val_img = np.zeros(sat.shape, dtype=np.uint8)
            masked_sat_img = np.zeros(sat.shape, dtype=np.uint8)
            masked_val_img[y_min:y_max, x_min:x_max] = cv.bitwise_and(
                val[y_min:y_max, x_min:x_max], mask[y_min:y_max, x_min:x_max])
            masked_sat_img[y_min:y_max, x_min:x_max] = cv.bitwise_and(
                sat[y_min:y_max, x_min:x_max], mask[y_min:y_max, x_min:x_max])

            # threshold for high val and high sat
            _, masked_val_img[y_min:y_max, x_min:x_max] = cv.threshold(
                masked_val_img[y_min:y_max, x_min:x_max], 70, 255,
                cv.THRESH_BINARY)
            _, masked_sat_img[y_min:y_max, x_min:x_max] = cv.threshold(
                masked_sat_img[y_min:y_max, x_min:x_max], 40, 255,
                cv.THRESH_BINARY)

            # combine high val and high sat
            masked_val_sat_bin = masked_val_img
            masked_val_sat_bin[y_min:y_max, x_min:x_max] = cv.bitwise_and(
                masked_val_img[y_min:y_max, x_min:x_max],
                masked_sat_img[y_min:y_max, x_min:x_max])

            # count high val and high sat pixels
            image__sum = (masked_val_sat_bin > 60).sum()
            image_sums[square] = (square, image__sum)

            # keep track of greatest sum roi_corners
            if (image_sums[square][1] > greatest_sum):
                greatest_sum = image_sums[square][1]
                greatest_sum_roi_corners = roi_corners
                greatest_masked_val_sat_bin = masked_val_sat_bin

            # place button on square
            if draw_buttons:
                img = self.place_button_on_checkerboard(
                    img,
                    self.font,
                    self.font_point[square],
                    roi_corners,
                    mask=masked_val_sat_bin)

        # sort sums
        image_sums = sorted(image_sums, key=itemgetter(1))
        # TODO unhard-code pixels of finger minimum
        is_finger_detected = image_sums[-1][
            1] > image_sums[-2][1] * 2 and image_sums[-1][1] > 500
        square_with_greatest_detection = image_sums[-1][0]
        if is_finger_detected:
            button_pressed = square_with_greatest_detection + 1
            return img, button_pressed, greatest_sum_roi_corners, greatest_masked_val_sat_bin
        else:
            return img, -1, None, None

    def place_inverted_button_on_checkerboard(self, img, font_square,
                                              greatest_masked_val_sat_bin,
                                              greatest_sum_roi_corners):
        img = self.place_button_on_checkerboard(
            img,
            self.font_inv,
            self.font_point[font_square],
            greatest_sum_roi_corners,
            mask=greatest_masked_val_sat_bin)
        return img

    def place_button_on_checkerboard(self, img, font_img, font_point_square,
                                     roi_corners, mask):
        roi_corners_float = roi_corners.astype(np.float32)
        img = self.draw_cube.add_image_to_base(img,
                                               font_img,
                                               roi_corners_float,
                                               font_point_square[0],
                                               font_point_square[1][0],
                                               font_point_square[1][1],
                                               mask=mask)
        return img

    def get_cube_size(self):
        return self.cube_size
 def __init__(self):
     self.last_0th_checkerboard_point = [-1, -1]
     self.common_core = CommonCore(None)
class BoardRotation:
    def __init__(self):
        self.last_0th_checkerboard_point = [-1, -1]
        self.common_core = CommonCore(None)

    def update_rotation(self, last_point):
        self.last_0th_checkerboard_point = last_point

    def get_rotated_corners(self, points):
        rotation = 0
        new_points = points
        x_min, y_min, x_max, y_max = self.common_core.sort_points_for_extremes(
            new_points)
        distance_between_checkerboard_extremes = self.distance_between_points(
            [x_min, y_min], [x_max, y_max])
        if self.relative_0th_change(distance_between_checkerboard_extremes,
                                    new_points[0, 0],
                                    self.last_0th_checkerboard_point) > .2:
            if self.relative_0th_change(distance_between_checkerboard_extremes,
                                        new_points[6, 0],
                                        self.last_0th_checkerboard_point) < .2:
                rotation = 1
            elif self.relative_0th_change(
                    distance_between_checkerboard_extremes, new_points[7 * 6,
                                                                       0],
                    self.last_0th_checkerboard_point) < .2:
                rotation = 3
            elif self.relative_0th_change(
                    distance_between_checkerboard_extremes,
                    new_points[7 * 6 + 6,
                               0], self.last_0th_checkerboard_point) < .2:
                rotation = 2

        # TODO make these rearranges more efficient
        if rotation == 1:
            new_points = np.empty((49, 1, 2))
            for i in range(7):
                for k in range(7):
                    new_points[i + (6 - k) * 7] = points[i * 7 + k]
            # 42, 35, 28, 21, 14, 7, 0, 43, 36

        if rotation == 2:
            new_points = np.empty((49, 1, 2))
            for i in range(7):
                for k in range(7):
                    new_points[(6 - i) * 7 + 6 - k] = points[i * 7 + k]
            # 48, 47, 46

        if rotation == 3:
            new_points = np.empty((49, 1, 2))
            for i in range(7):
                for k in range(7):
                    new_points[6 + (k * 7) - i] = points[i * 7 + k]
            # 6, 13, 20, 27, 34, 41, 48, 5, 12

        self.last_0th_checkerboard_point = new_points[0, 0]

        return new_points

    def relative_0th_change(self, distance_between_checkerboard_extremes,
                            this_0th, last_0th):
        distance_between_start_points = self.distance_between_points(
            last_0th, this_0th)
        relative_0th_change = distance_between_start_points / distance_between_checkerboard_extremes
        return relative_0th_change

    def distance_between_points(self, point_1, point_2):

        distance_between_start_points = ((point_1[0] - point_2[0])**2 +
                                         (point_1[1] - point_2[1])**2)**0.5
        return distance_between_start_points
Exemple #7
0
 def __init__(self, resources_path):
     self.bottom_cube_img = cv.imread(resources_path +
                                      "to_project/devel_square.jpg")
     self.common_core = CommonCore(None)
Exemple #8
0
class DrawCube:
    def __init__(self, resources_path):
        self.bottom_cube_img = cv.imread(resources_path +
                                         "to_project/devel_square.jpg")
        self.common_core = CommonCore(None)

    def draw_cube_pieces(self, corners, corners2, img, board_size, cube_size):
        # prepare object points, like (0,0,0), (1,0,0), (2,0,0) ....,(6,5,0)
        # Arrays to store object points and image points from all the images.
        objp = np.zeros((board_size[1] * board_size[0], 3), np.float32)
        objp[:, :2] = np.mgrid[0:board_size[0],
                               0:board_size[1]].T.reshape(-1, 2)
        objpoints = []  # 3d point in real world space
        imgpoints = []  # 2d points in image plane.
        objpoints.append(objp)
        imgpoints.append(corners)

        _, mtx, dist, _, _ = cv.calibrateCamera(objpoints, imgpoints,
                                                (img.shape[1], img.shape[0]),
                                                None, None)
        # 3d Time
        objp2 = np.zeros((board_size[1] * board_size[0], 3), np.float32)
        objp2[:, :2] = np.mgrid[0:board_size[0],
                                0:board_size[1]].T.reshape(-1, 2)
        edge_size = cube_size
        x_offset = 0
        y_offset = 0
        z_offset = -0
        axis3 = np.float32([
            [x_offset, y_offset, z_offset],
            [x_offset, y_offset + edge_size, z_offset],
            [x_offset + edge_size, y_offset + edge_size, z_offset],
            [x_offset + edge_size, y_offset, z_offset],
            [x_offset, y_offset, z_offset - edge_size],
            [x_offset, y_offset + edge_size, z_offset - edge_size],
            [x_offset + edge_size, y_offset + edge_size, z_offset - edge_size],
            [x_offset + edge_size, y_offset, z_offset - edge_size]
        ])
        _, rvecs2, tvecs2 = cv.solvePnP(objp2, corners2, mtx, dist)
        imgpts3, jac3 = cv.projectPoints(axis3, rvecs2, tvecs2, mtx, dist)

        destination_points = np.array(
            [imgpts3[0], imgpts3[3], imgpts3[2], imgpts3[1]])

        # Read image to project and put it on image with same size as image to project to
        project_img = self.bottom_cube_img
        dev_rows, dev_cols, _ = project_img.shape

        img = self.add_image_to_base(img, project_img, destination_points,
                                     [0, 0], dev_cols, dev_rows)
        img = self.draw_cube(img, imgpts3)
        return img

    def add_image_to_base(self,
                          img,
                          project_img,
                          dst_pts,
                          src_start_point,
                          src_width,
                          src_height,
                          mask=None):

        # Put image passed in onto black image
        img_to_use = np.zeros((img.shape[0], img.shape[1], 3), dtype=np.uint8)
        mask_to_use = np.zeros((img.shape[0], img.shape[1], 1), dtype=np.uint8)
        img_to_use[0:src_width, 0:src_height] = \
            project_img[src_start_point[0]:src_start_point[0] + src_width, src_start_point[1]:src_start_point[1] + src_height]

        # Create matrix to transform then warp
        src_pts = np.array(
            [[0, 0], [src_width, 0], [src_width, src_height], [0, src_height]],
            dtype="float32")

        matrix = cv.getPerspectiveTransform(src_pts, dst_pts)
        warped_img = cv.warpPerspective(img_to_use, matrix,
                                        (img.shape[1], img.shape[0]))

        dst_pts_int = dst_pts.astype(int)
        dst_pts_int[2][0][0] = math.ceil(dst_pts[2][0][0])
        dst_pts_int[2][0][1] = math.ceil(dst_pts[2][0][1])
        dst_pts_int[3][0][0] = math.ceil(dst_pts[3][0][0])
        dst_pts_int[3][0][1] = math.ceil(dst_pts[3][0][1])

        # Points for roi
        x_min, y_min, x_max, y_max = self.common_core.sort_points_for_extremes(
            dst_pts_int)

        # create mask with white quadrangle around destination points
        cv.fillConvexPoly(mask_to_use, dst_pts_int, 255)
        mask_to_use_inv = cv.bitwise_not(mask_to_use)

        if type(mask) != type(None):
            mask_to_use_inv[y_min:y_max, x_min:x_max] = cv.bitwise_or(
                mask[y_min:y_max, x_min:x_max], mask_to_use_inv[y_min:y_max,
                                                                x_min:x_max])

        img[y_min:y_max,
            x_min:x_max] = cv.bitwise_and(img[y_min:y_max, x_min:x_max],
                                          img[y_min:y_max, x_min:x_max],
                                          mask=mask_to_use_inv[y_min:y_max,
                                                               x_min:x_max])
        mask_to_use_inv_inv = cv.bitwise_not(mask_to_use_inv)
        warped_img[y_min:y_max, x_min:x_max] = cv.bitwise_and(
            warped_img[y_min:y_max, x_min:x_max],
            warped_img[y_min:y_max, x_min:x_max],
            mask=mask_to_use_inv_inv[y_min:y_max, x_min:x_max])
        img[y_min:y_max,
            x_min:x_max] = cv.add(img[y_min:y_max, x_min:x_max],
                                  warped_img[y_min:y_max, x_min:x_max])

        return img

    def draw_cube(self, img, imgpts):
        imgpts = np.int32(imgpts).reshape(-1, 2)

        # draw back left wall
        back_pts_2 = np.empty((0, 2), dtype=int)
        back_pts_2 = np.append(back_pts_2, [imgpts[0]], axis=0)
        back_pts_2 = np.append(back_pts_2, [imgpts[4]], axis=0)
        back_pts_2 = np.append(back_pts_2, [imgpts[5]], axis=0)
        back_pts_2 = np.append(back_pts_2, [imgpts[1]], axis=0)
        img = cv.drawContours(img, [back_pts_2], -1, (100, 100, 255), 10)

        # draw back right wall
        back_pts_2 = np.empty((0, 2), dtype=int)
        back_pts_2 = np.append(back_pts_2, [imgpts[0]], axis=0)
        back_pts_2 = np.append(back_pts_2, [imgpts[4]], axis=0)
        back_pts_2 = np.append(back_pts_2, [imgpts[7]], axis=0)
        back_pts_2 = np.append(back_pts_2, [imgpts[3]], axis=0)
        img = cv.drawContours(img, [back_pts_2], -1, (255, 100, 100), -1)

        # draw pillars in blue color
        for i, j in zip(range(0, 4), range(4, 8)):
            img = cv.line(img, tuple(imgpts[i]), tuple(imgpts[j]), (255, 0, 0),
                          3)

        # draw top layer in red color
        img = cv.drawContours(img, [imgpts[4:]], -1, (0, 0, 255), 3)

        return img