def get_part_rotated_verts(ibs, part_rowid_list):
    r"""
    Returns:
        rotated_vert_list (list): verticies after rotation by theta.

    RESTful:
        Method: GET
        URL:    /api/part/vert/rotated/
    """
    import vtool as vt

    vert_list = ibs.get_part_verts(part_rowid_list)
    theta_list = ibs.get_part_thetas(part_rowid_list)
    # Convex bounding boxes for verticies
    bbox_list = vt.geometry.bboxes_from_vert_list(vert_list)
    rot_list = [
        vt.rotation_around_bbox_mat3x3(theta, bbox)
        for theta, bbox in zip(theta_list, bbox_list)
    ]
    rotated_vert_list = [
        vt.transform_points_with_homography(rot,
                                            np.array(verts).T).T.tolist()
        for rot, verts in zip(rot_list, vert_list)
    ]
    # vert_list = [eval(vertstr, {}, {}) for vertstr in vertstr_list]
    return rotated_vert_list
Пример #2
0
 def transform_non_affine(self, input_xy):
     """
     The input and output are Nx2 numpy arrays.
     """
     import vtool as vt
     _xys = input_xy.T
     xy_t = vt.transform_points_with_homography(self.H, _xys)
     output_xy = xy_t.T
     return output_xy
Пример #3
0
    def transform_non_affine(self, input_xy):
        """
        The input and output are Nx2 numpy arrays.
        """
        import vtool as vt

        _xys = input_xy.T
        xy_t = vt.transform_points_with_homography(self.H, _xys)
        output_xy = xy_t.T
        return output_xy
Пример #4
0
def draw_keypoints(ax,
                   kpts_,
                   scale_factor=1.0,
                   offset=(0.0, 0.0),
                   rotation=0.0,
                   ell=True,
                   pts=False,
                   rect=False,
                   eig=False,
                   ori=False,
                   sifts=None,
                   siftkw={},
                   H=None,
                   **kwargs):
    """
    draws keypoints extracted by pyhesaff onto a matplotlib axis

    FIXME: There is probably a matplotlib bug here. If you specify two different
    alphas in a collection, whatever the last alpha was gets applied to
    everything

    Args:
        ax (mpl.Axes):
        kpts (ndarray): keypoints [[x, y, a, c, d, theta], ...]
        scale_factor (float):
        offset (tuple):
        rotation (float):
        ell (bool):
        pts (bool):
        rect (bool):
        eig (bool):
        ori (bool):
        sifts (None):

    References:
        http://stackoverflow.com/questions/28401788/transforms-non-affine-patch

    CommandLine:
        python -m wbia.plottool.mpl_keypoint draw_keypoints --show

    Example:
        >>> # ENABLE_DOCTEST
        >>> from wbia.plottool.mpl_keypoint import *  # NOQA
        >>> from wbia.plottool.mpl_keypoint import _draw_patches, _draw_pts  # NOQA
        >>> import wbia.plottool as pt
        >>> import vtool as vt
        >>> imgBGR = vt.get_star_patch(jitter=True)
        >>> H = np.array([[1, 0, 0], [.5, 2, 0], [0, 0, 1]])
        >>> H = np.array([[.8, 0, 0], [0, .8, 0], [0, 0, 1]])
        >>> H = None
        >>> TAU = 2 * np.pi
        >>> kpts_ = vt.make_test_image_keypoints(imgBGR, scale=.5, skew=2, theta=TAU / 8.0)
        >>> scale_factor=1.0
        >>> #offset=(0.0, -4.0)
        >>> offset=(0.0, 0.0)
        >>> rotation=0.0
        >>> ell=True
        >>> pts=True
        >>> rect=True
        >>> eig=True
        >>> ori=True
        >>> # make random sifts
        >>> sifts = mpl_sift.testdata_sifts()
        >>> siftkw = {}
        >>> kwargs = dict(ori_color=[0, 1, 0], rect_color=[0, 0, 1],
        >>>               eig_color=[1, 1, 0], pts_size=.1)
        >>> w, h = imgBGR.shape[0:2][::-1]
        >>> imgBGR_ = imgBGR if H is None else vt.warpAffine(
        >>>     imgBGR, H, (int(w * .8), int(h * .8)))
        >>> fig, ax = pt.imshow(imgBGR_ * 255)
        >>> draw_keypoints(ax, kpts_, scale_factor, offset, rotation, ell, pts,
        ...                rect, eig, ori, sifts, siftkw, H=H, **kwargs)
        >>> pt.iup()
        >>> pt.show_if_requested()
    """
    import vtool.keypoint as ktool

    if kpts_.shape[1] == 2:
        # pad out structure if only xy given
        kpts = np.zeros((len(kpts_), 6))
        kpts[:, 0:2] = kpts_
        kpts[:, 2] = 1
        kpts[:, 4] = 1
        kpts_ = kpts

    if scale_factor is None:
        scale_factor = 1.0
    # print('[mpl_keypoint.draw_keypoints] kwargs = ' + ut.repr2(kwargs))
    # ellipse and point properties
    pts_size = kwargs.get('pts_size', 2)
    pts_alpha = kwargs.get('pts_alpha', 1.0)
    ell_alpha = kwargs.get('ell_alpha', 1.0)
    ell_linewidth = kwargs.get('ell_linewidth', 2)
    ell_color = kwargs.get('ell_color', None)
    if ell_color is None:
        ell_color = [1, 0, 0]
    # colors
    pts_color = kwargs.get('pts_color', ell_color)
    rect_color = kwargs.get('rect_color', ell_color)
    eig_color = kwargs.get('eig_color', ell_color)
    ori_color = kwargs.get('ori_color', ell_color)
    # linewidths
    eig_linewidth = kwargs.get('eig_linewidth', ell_linewidth)
    rect_linewidth = kwargs.get('rect_linewidth', ell_linewidth)
    ori_linewidth = kwargs.get('ori_linewidth', ell_linewidth)
    # Offset keypoints
    assert len(kpts_) > 0, 'cannot draw no keypoints1'
    kpts = ktool.offset_kpts(kpts_, offset, scale_factor)
    assert len(kpts) > 0, 'cannot draw no keypoints2'
    # Build list of keypoint shape transforms from unit circles to ellipes
    invVR_aff2Ds = get_invVR_aff2Ds(kpts, H=H)
    try:
        if sifts is not None:
            # SIFT descriptors
            pass_props(
                kwargs,
                siftkw,
                'bin_color',
                'arm1_color',
                'arm2_color',
                'arm1_lw',
                'arm2_lw',
                'stroke',
                'arm_alpha',
                'arm_alpha',
                'multicolored_arms',
            )
            mpl_sift.draw_sifts(ax, sifts, invVR_aff2Ds, **siftkw)
        if rect:
            # Bounding Rectangles
            rect_patches = rectangle_actors(invVR_aff2Ds)
            _draw_patches(ax, rect_patches, rect_color, ell_alpha,
                          rect_linewidth)
        if ell:
            # Keypoint shape
            ell_patches = ellipse_actors(invVR_aff2Ds)
            _draw_patches(ax, ell_patches, ell_color, ell_alpha, ell_linewidth)
        if eig:
            # Shape eigenvectors
            eig_patches = eigenvector_actors(invVR_aff2Ds)
            _draw_patches(ax, eig_patches, eig_color, ell_alpha, eig_linewidth)
        if ori:
            # Keypoint orientation
            ori_patches = orientation_actors(kpts, H=H)
            _draw_patches(ax, ori_patches, ori_color, ell_alpha, ori_linewidth,
                          ori_color)
        if pts:
            # Keypoint locations
            _xs, _ys = ktool.get_xys(kpts)
            if H is not None:
                # adjust for homogrpahy
                import vtool as vt

                _xs, _ys = vt.transform_points_with_homography(
                    H, np.vstack((_xs, _ys)))

            pts_patches = _draw_pts(ax, _xs, _ys, pts_size, pts_color,
                                    pts_alpha)
            if pts_patches is not None:
                _draw_patches(ax, pts_patches, 'none', pts_alpha, pts_size,
                              pts_color)
    except ValueError as ex:
        ut.printex(ex, '\n[mplkp] !!! ERROR')
        # print('_oris.shape = %r' % (_oris.shape,))
        # print('_xs.shape = %r' % (_xs.shape,))
        # print('_iv11s.shape = %r' % (_iv11s.shape,))
        raise
Пример #5
0
def preproc_cropped_chips(depc, cid_list, tipid_list, config=None):
    """
    CommandLine:
        python -m ibeis_flukematch.plugin --exec-preproc_cropped_chips --show

    Example:
        >>> # DISABLE_DOCTEST
        >>> from ibeis_flukematch.plugin import *  # NOQA
        >>> ibs, aid_list = testdata_humpbacks()
        >>> config = CropChipConfig(crop_enabled=True)
        >>> cid_list = ibs.depc.get_rowids('chips', aid_list, config)
        >>> tipid_list = ibs.depc.get_rowids('Notch_Tips', aid_list, config)
        >>> depc = ibs.depc
        >>> list(preproc_cropped_chips(depc, cid_list, tipid_list, config))
        >>> #cpid_list = ibs.depc.d.get_Cropped_Chips_rowids(aid_list, config)
        >>> #cpid_list = ibs.depc.w.Cropped_Chips.get_rowids(aid_list, config)
        >>> chip_list = ibs.depc.get('Cropped_Chips', aid_list, 'img', config)
        >>> notch_tips = ibs.depc.get('Cropped_Chips', aid_list, ('notch', 'left', 'right'), config)
        >>> import plottool as pt
        >>> ut.ensure_pylab_qt4()
        >>> for notch, chip, aid in ut.InteractiveIter(zip(notch_tips, chip_list, aid_list)):
        >>>     pt.reset()
        >>>     pt.imshow(chip)
        >>>     print(ibs.depc.get('Cropped_Chips', [aid], 'img', config, read_extern=False)[0])
        >>>     kpts_ = np.array(notch)
        >>>     pt.draw_kpts2(kpts_, pts=True, ell=False, pts_size=20)
        >>>     pt.update()
        >>> ut.show_if_requested()
    """
    # crop first
    img_list = depc.get_native_property(const.CHIP_TABLE, cid_list, 'img')
    tips_list = depc.get_native_property('Notch_Tips', tipid_list,
                                         ('left', 'notch', 'right'))

    #imgpath_list = depc.get_native_property(const.CHIP_TABLE, cid_list, 'img',
    #                                        read_extern=False)

    cropped_chip_dpath = depc.controller.get_chipdir() + '_crop'
    ut.ensuredir(cropped_chip_dpath)
    #crop_path_list = [ut.augpath(path, '_crop' + config.get_hashid())
    #                  for path in imgpath_list]

    #for img, tips, path in zip(img_list, tips_list, crop_path_list):
    for img, tips in zip(img_list, tips_list):
        left, notch, right = tips
        bbox = (0, 0, img.shape[1], img.shape[0]
                )  # default to bbox being whole image
        chip_size = (img.shape[1], img.shape[0])
        if left[0] > right[0]:
            # HACK: Ugh, I don't like this
            # TODO: maybe move this to infer_kp?
            right, left = (left, right)
        if config['crop_enabled']:
            # figure out bbox (x, y, w, h) w/x, y on top left
            # assume left is on the left note: this may not be a good assumption
            # note: lol that's not a good assumption
            # what do when network predicts left on right and right on left?
            bbox = (
                left[0],  # leftmost x value
                0,  # top of the image
                (right[0] - left[0]),  # width
                img.shape[0],  # height
            )
        if config['crop_dim_size'] is not None:
            # we're only resizing in x, but after the crop
            # as a result we need to make sure we use the image dimensions apparent to get the chip size
            # we want to preserve the aspect ratio of the crop, not the whole image
            new_x = config['crop_dim_size']
            #ratio = bbox[2] / bbox[3]  # w/h
            #new_y = int(new_x / ratio)
            #chip_size = (new_x, new_y)
            try:
                #print("[cropped-chips] %s: bbox: %r, l/n/r %r" % (path, bbox,tips))
                chip_size = vt.get_scaled_size_with_width(
                    new_x, bbox[2], bbox[3])
            except OverflowError:
                print(
                    "[cropped chip] WARNING: Probably got a bad keypoint prediction: bbox: %r"
                    % (bbox, ))
                yield None
        M = vt.get_image_to_chip_transform(bbox, chip_size, 0)
        with ut.embed_on_exception_context:
            new_img = cv2.warpAffine(img, M[:-1, :], chip_size)

        notch_, left_, right_ = vt.transform_points_with_homography(
            M,
            np.array([notch, left, right]).T).T

        notch_ = bound_point(notch_, chip_size)
        left_ = bound_point(left_, chip_size)
        right_ = bound_point(right_, chip_size)
        #vt.imwrite(path, new_img)
        yield (new_img, bbox[2], bbox[3], M, notch_, left_, right_)
Пример #6
0
def wbia_plugin_kaggle7_chip_depc(depc, aid_list, config):
    r"""
    Refine localizations for CurvRank with Dependency Cache (depc)

    CommandLine:
        python -m wbia_kaggle7._plugin --test-wbia_plugin_kaggle7_chip_depc
        python -m wbia_kaggle7._plugin --test-wbia_plugin_kaggle7_chip_depc:0

    Example:
        >>> # DISABLE_DOCTEST
        >>> from wbia_kaggle7._plugin import *  # NOQA
        >>> import wbia
        >>> from wbia.init import sysres
        >>> dbdir = sysres.ensure_testdb_kaggle7()
        >>> ibs = wbia.opendb(dbdir=dbdir, allow_newdir=True)
        >>> aid_list = ibs.get_image_aids(1)
        >>> images = ibs.depc_annot.get('KaggleSevenChip', aid_list, 'image')
        >>> image = images[0]
        >>> assert ut.hash_data(image) in ['imlkoiskkykpbwozghmpidlqwbmglzhw']
    """
    padding = config['chip_padding']

    tips_list = depc.get('Notch_Tips', aid_list)
    size_list = depc.get('chips', aid_list, ('width', 'height'))
    config_ = {
        'dim_size': 1550,
        'resize_dim': 'width',
        'ext': '.jpg',
    }
    chip_list = depc.get('chips', aid_list, 'img', config=config_, ensure=True)

    tps = cv2.createThinPlateSplineShapeTransformer()

    zipped = list(zip(aid_list, tips_list, size_list, chip_list))
    for aid, tip_list, size, chip in zipped:
        h0, w0, c0 = chip.shape
        notch = tip_list[0].copy()
        left = tip_list[1].copy()
        right = tip_list[2].copy()

        size = np.array(size, dtype=np.float32)
        notch /= size
        left /= size
        right /= size

        size = np.array([w0, h0], dtype=np.float32)
        notch *= size
        left *= size
        right *= size

        chip_ = chip.copy()
        h0, w0, c0 = chip_.shape

        left += padding
        notch += padding
        right += padding

        pad = np.zeros((h0, padding, 3), dtype=chip_.dtype)
        chip_ = np.hstack((pad, chip_, pad))
        h, w, c = chip_.shape
        pad = np.zeros((padding, w, 3), dtype=chip_.dtype)
        chip_ = np.vstack((pad, chip_, pad))
        h, w, c = chip_.shape

        delta = right - left
        radian = np.arctan2(delta[1], delta[0])
        degree = np.degrees(radian)
        M = cv2.getRotationMatrix2D((left[1], left[0]), degree, 1)
        chip_ = cv2.warpAffine(chip_, M, (w, h), flags=cv2.INTER_LANCZOS4)

        H = np.vstack((M, [0, 0, 1]))
        vert_list = np.array([notch, left, right])
        vert_list_ = vt.transform_points_with_homography(H, vert_list.T).T
        notch, left, right = vert_list_

        left[0] -= padding // 2
        left[1] -= padding // 2
        notch[1] += padding // 2
        right[0] += padding // 2
        right[1] -= padding // 2

        sshape = np.array([left, notch, right], np.float32)
        tshape = np.array([[0, 0], [w0 // 2, h0], [w0, 0]], np.float32)
        sshape = sshape.reshape(1, -1, 2)
        tshape = tshape.reshape(1, -1, 2)
        matches = [
            cv2.DMatch(0, 0, 0),
            cv2.DMatch(1, 1, 0),
            cv2.DMatch(2, 2, 0),
        ]
        tps.clear()
        tps.estimateTransformation(tshape, sshape, matches)
        chip_ = tps.warpImage(chip_)

        chip_ = chip_[:h0, :w0, :]
        chip_h, chip_w = chip_.shape[:2]

        yield (
            chip_,
            chip_w,
            chip_h,
        )
def fix_annotation_orientation(ibs, min_percentage=0.95):
    """
    Fixes the annotations that are outside the bounds of the image due to a
    changed image orientation flag in the database

    CommandLine:
        python -m ibeis.scripts.fix_annotation_orientation_issue fix_annotation_orientation

    Example:
        >>> # ENABLE_DOCTEST
        >>> import ibeis
        >>> from ibeis.scripts.fix_annotation_orientation_issue import *  # NOQA
        >>> ibs = ibeis.opendb()
        >>> unfixable_gid_list = fix_annotation_orientation(ibs)
        >>> assert len(unfixable_gid_list) == 0
    """
    from vtool import exif

    def bbox_overlap(bbox1, bbox2):
        ax1 = bbox1[0]
        ay1 = bbox1[1]
        ax2 = bbox1[0] + bbox1[2]
        ay2 = bbox1[1] + bbox1[3]
        bx1 = bbox2[0]
        by1 = bbox2[1]
        bx2 = bbox2[0] + bbox2[2]
        by2 = bbox2[1] + bbox2[3]
        overlap_x = max(0, min(ax2, bx2) - max(ax1, bx1))
        overlap_y = max(0, min(ay2, by2) - max(ay1, by1))
        return overlap_x * overlap_y

    orient_dict = exif.ORIENTATION_DICT_INVERSE
    good_orient_list = [
        exif.ORIENTATION_UNDEFINED,
        exif.ORIENTATION_000,
    ]
    good_orient_key_list = [
        orient_dict.get(good_orient) for good_orient in good_orient_list
    ]
    assert None not in good_orient_key_list

    gid_list = ibs.get_valid_gids()
    orient_list = ibs.get_image_orientation(gid_list)
    flag_list = [orient not in good_orient_key_list for orient in orient_list]

    # Filter based on based gids
    unfixable_gid_list = []
    gid_list = ut.filter_items(gid_list, flag_list)
    if len(gid_list) > 0:
        args = (len(gid_list), )
        print('Found %d images with non-standard orientations' % args)
        aids_list = ibs.get_image_aids(gid_list,
                                       is_staged=None,
                                       __check_staged__=False)
        size_list = ibs.get_image_sizes(gid_list)
        invalid_gid_list = []
        zipped = zip(gid_list, orient_list, aids_list, size_list)
        for gid, orient, aid_list, (w, h) in zipped:
            image = ibs.get_images(gid)
            h_, w_ = image.shape[:2]
            if h != h_ or w != w_:
                ibs._set_image_sizes([gid], [w_], [h_])
            orient_str = exif.ORIENTATION_DICT[orient]
            image_bbox = (0, 0, w, h)
            verts_list = ibs.get_annot_rotated_verts(aid_list)
            invalid = False
            for aid, vert_list in zip(aid_list, verts_list):
                annot_bbox = vt.bbox_from_verts(vert_list)
                overlap = bbox_overlap(image_bbox, annot_bbox)
                area = annot_bbox[2] * annot_bbox[3]
                percentage = overlap / area
                if percentage < min_percentage:
                    args = (gid, orient_str, aid, overlap, area, percentage)
                    print(
                        '\tInvalid GID %r, Orient %r, AID %r: Overlap %0.2f, Area %0.2f (%0.2f %%)'
                        % args)
                    invalid = True
                    # break
            if invalid:
                invalid_gid_list.append(gid)

        invalid_gid_list = list(set(invalid_gid_list))
        if len(invalid_gid_list) > 0:
            args = (
                len(invalid_gid_list),
                len(gid_list),
                invalid_gid_list,
            )
            print('Found %d / %d images with invalid annotations = %r' % args)
            orient_list = ibs.get_image_orientation(invalid_gid_list)
            aids_list = ibs.get_image_aids(invalid_gid_list,
                                           is_staged=None,
                                           __check_staged__=False)
            size_list = ibs.get_image_sizes(invalid_gid_list)
            zipped = zip(invalid_gid_list, orient_list, aids_list, size_list)
            for invalid_gid, orient, aid_list, (w, h) in zipped:
                orient_str = exif.ORIENTATION_DICT[orient]
                image_bbox = (0, 0, w, h)
                args = (
                    invalid_gid,
                    len(aid_list),
                )
                print('Fixing GID %r with %d annotations' % args)
                theta = np.pi / 2.0
                tx = 0.0
                ty = 0.0
                if orient == orient_dict.get(exif.ORIENTATION_090):
                    theta *= 1.0
                    tx = w
                elif orient == orient_dict.get(exif.ORIENTATION_180):
                    theta *= 2.0
                    tx = w
                    ty = h
                elif orient == orient_dict.get(exif.ORIENTATION_270):
                    theta *= -1.0
                    ty = h
                else:
                    raise ValueError('Unrecognized invalid orientation')
                H = np.array([[np.cos(theta), -np.sin(theta), tx],
                              [np.sin(theta), np.cos(theta), ty],
                              [0.0, 0.0, 1.0]])
                # print(H)
                verts_list = ibs.get_annot_rotated_verts(aid_list)
                for aid, vert_list in zip(aid_list, verts_list):
                    vert_list = np.array(vert_list)
                    # print(vert_list)
                    vert_list = vert_list.T
                    transformed_vert_list = vt.transform_points_with_homography(
                        H, vert_list)
                    transformed_vert_list = transformed_vert_list.T
                    # print(transformed_vert_list)

                    ibs.set_annot_verts([aid], [transformed_vert_list],
                                        update_visual_uuids=False)
                    current_theta = ibs.get_annot_thetas(aid)
                    new_theta = current_theta + theta
                    ibs.set_annot_thetas(aid,
                                         new_theta,
                                         update_visual_uuids=False)

                    fixed_vert_list = ibs.get_annot_rotated_verts(aid)
                    fixed_annot_bbox = vt.bbox_from_verts(fixed_vert_list)
                    fixed_overlap = bbox_overlap(image_bbox, fixed_annot_bbox)
                    fixed_area = fixed_annot_bbox[2] * fixed_annot_bbox[3]
                    fixed_percentage = fixed_overlap / fixed_area
                    args = (invalid_gid, orient_str, aid, fixed_overlap,
                            fixed_area, fixed_percentage)
                    print(
                        '\tFixing GID %r, Orient %r, AID %r: Overlap %0.2f, Area %0.2f (%0.2f %%)'
                        % args)
                    if fixed_percentage < min_percentage:
                        print('\tWARNING: FIXING DID NOT CORRECT AID %r' %
                              (aid, ))
                        unfixable_gid_list.append(gid)
    print('Un-fixable gid_list = %r' % (unfixable_gid_list, ))
    return unfixable_gid_list
    for location, color in zip(location_list, color_list):
        cv2.circle(chip1_, location, 5, color=color)

    chip_filename = 'img_aid_%d_1.png' % (aid, )
    chip_filepath = join(notch_path, chip_filename)
    cv2.imwrite(chip_filepath, chip1_)

    delta = right - left
    radian = np.arctan2(delta[1], delta[0])
    degree = np.degrees(radian)
    M = cv2.getRotationMatrix2D((left[1], left[0]), degree, 1)
    chip2 = cv2.warpAffine(chip1, M, (w, h), flags=cv2.INTER_LANCZOS4)

    H = np.vstack((M, [0, 0, 1]))
    vert_list = np.array([notch, left, right])
    vert_list_ = vt.transform_points_with_homography(H, vert_list.T).T
    notch, left, right = vert_list_

    location_list = [
        tuple(map(int, np.around(notch))),
        tuple(map(int, np.around(left))),
        tuple(map(int, np.around(right))),
    ]
    chip2_ = chip2.copy()
    for location, color in zip(location_list, color_list):
        cv2.circle(chip2_, location, 5, color=color)

    chip_filename = 'img_aid_%d_2.png' % (aid, )
    chip_filepath = join(notch_path, chip_filename)
    cv2.imwrite(chip_filepath, chip2_)
Пример #9
0
def preproc_cropped_chips(depc, cid_list, tipid_list, config=None):
    """
    CommandLine:
        python -m ibeis_flukematch.plugin --exec-preproc_cropped_chips --show

    Example:
        >>> # DISABLE_DOCTEST
        >>> from ibeis_flukematch.plugin import *  # NOQA
        >>> ibs, aid_list = testdata_humpbacks()
        >>> config = CropChipConfig(crop_enabled=True)
        >>> cid_list = ibs.depc.get_rowids('chips', aid_list, config)
        >>> tipid_list = ibs.depc.get_rowids('Notch_Tips', aid_list, config)
        >>> depc = ibs.depc
        >>> list(preproc_cropped_chips(depc, cid_list, tipid_list, config))
        >>> #cpid_list = ibs.depc.d.get_Cropped_Chips_rowids(aid_list, config)
        >>> #cpid_list = ibs.depc.w.Cropped_Chips.get_rowids(aid_list, config)
        >>> chip_list = ibs.depc.get('Cropped_Chips', aid_list, 'img', config)
        >>> notch_tips = ibs.depc.get('Cropped_Chips', aid_list, ('notch', 'left', 'right'), config)
        >>> import plottool as pt
        >>> ut.ensure_pylab_qt4()
        >>> for notch, chip, aid in ut.InteractiveIter(zip(notch_tips, chip_list, aid_list)):
        >>>     pt.reset()
        >>>     pt.imshow(chip)
        >>>     print(ibs.depc.get('Cropped_Chips', [aid], 'img', config, read_extern=False)[0])
        >>>     kpts_ = np.array(notch)
        >>>     pt.draw_kpts2(kpts_, pts=True, ell=False, pts_size=20)
        >>>     pt.update()
        >>> ut.show_if_requested()
    """
    # crop first
    img_list = depc.get_native_property(const.CHIP_TABLE, cid_list, 'img')
    tips_list = depc.get_native_property('Notch_Tips', tipid_list, ('left', 'notch', 'right'))

    #imgpath_list = depc.get_native_property(const.CHIP_TABLE, cid_list, 'img',
    #                                        read_extern=False)

    cropped_chip_dpath = depc.controller.get_chipdir() + '_crop'
    ut.ensuredir(cropped_chip_dpath)
    #crop_path_list = [ut.augpath(path, '_crop' + config.get_hashid())
    #                  for path in imgpath_list]

    #for img, tips, path in zip(img_list, tips_list, crop_path_list):
    for img, tips in zip(img_list, tips_list):
        left, notch, right = tips
        bbox = (0, 0, img.shape[1], img.shape[0])  # default to bbox being whole image
        chip_size = (img.shape[1], img.shape[0])
        if left[0] > right[0]:
            # HACK: Ugh, I don't like this
            # TODO: maybe move this to infer_kp?
            right, left = (left, right)
        if config['crop_enabled']:
            # figure out bbox (x, y, w, h) w/x, y on top left
            # assume left is on the left note: this may not be a good assumption
            # note: lol that's not a good assumption
            # what do when network predicts left on right and right on left?
            bbox = (left[0],  # leftmost x value
                    0,  # top of the image
                    (right[0] - left[0]),  # width
                    img.shape[0],  # height
                    )
        if config['crop_dim_size'] is not None:
            # we're only resizing in x, but after the crop
            # as a result we need to make sure we use the image dimensions apparent to get the chip size
            # we want to preserve the aspect ratio of the crop, not the whole image
            new_x = config['crop_dim_size']
            #ratio = bbox[2] / bbox[3]  # w/h
            #new_y = int(new_x / ratio)
            #chip_size = (new_x, new_y)
            try:
                #print("[cropped-chips] %s: bbox: %r, l/n/r %r" % (path, bbox,tips))
                chip_size = vt.get_scaled_size_with_width(new_x, bbox[2], bbox[3])
            except OverflowError:
                print("[cropped chip] WARNING: Probably got a bad keypoint prediction: bbox: %r" % (bbox,))
                yield None
        M = vt.get_image_to_chip_transform(bbox, chip_size, 0)
        with ut.embed_on_exception_context:
            new_img = cv2.warpAffine(img, M[:-1, :], chip_size)

        notch_, left_, right_ = vt.transform_points_with_homography(M, np.array([notch, left, right]).T).T

        notch_ = bound_point(notch_, chip_size)
        left_  = bound_point(left_, chip_size)
        right_ = bound_point(right_, chip_size)
        #vt.imwrite(path, new_img)
        yield (new_img, bbox[2], bbox[3], M, notch_, left_, right_)
Пример #10
0
def draw_keypoints(ax, kpts_, scale_factor=1.0, offset=(0.0, 0.0), rotation=0.0,
                   ell=True, pts=False, rect=False, eig=False, ori=False,
                   sifts=None, siftkw={}, H=None, **kwargs):
    """
    draws keypoints extracted by pyhesaff onto a matplotlib axis

    FIXME: There is probably a matplotlib bug here. If you specify two different
    alphas in a collection, whatever the last alpha was gets applied to
    everything

    Args:
        ax (mpl.Axes):
        kpts (ndarray): keypoints [[x, y, a, c, d, theta], ...]
        scale_factor (float):
        offset (tuple):
        rotation (float):
        ell (bool):
        pts (bool):
        rect (bool):
        eig (bool):
        ori (bool):
        sifts (None):

    References:
        http://stackoverflow.com/questions/28401788/using-homogeneous-transforms-non-affine-with-matplotlib-patches

    CommandLine:
        python -m plottool.mpl_keypoint --test-draw_keypoints --show

    Example:
        >>> # ENABLE_DOCTEST
        >>> from plottool.mpl_keypoint import *  # NOQA
        >>> from plottool.mpl_keypoint import _draw_patches, _draw_pts  # NOQA
        >>> import plottool as pt
        >>> import vtool as vt
        >>> imgBGR = vt.get_star_patch(jitter=True)
        >>> H = np.array([[1, 0, 0], [.5, 2, 0], [0, 0, 1]])
        >>> H = None
        >>> TAU = 2 * np.pi
        >>> kpts_ = vt.make_test_image_keypoints(imgBGR, scale=.5, skew=2, theta=TAU / 8.0)
        >>> scale_factor=1.0
        >>> offset=(0.0, 0.0)
        >>> rotation=0.0
        >>> ell=True
        >>> pts=True
        >>> rect=True
        >>> eig=True
        >>> ori=True
        >>> # make random sifts
        >>> sifts = mpl_sift.testdata_sifts()
        >>> siftkw = {}
        >>> kwargs = dict(ori_color=[0, 1, 0], rect_color=[0, 0, 1], eig_color=[1, 1, 0], pts_size=.1)
        >>> w, h = imgBGR.shape[0:2][::-1]
        >>> imgBGR_ = imgBGR if H is None else vt.warpAffine(imgBGR, H, (w * 2, h * 2))
        >>> fig, ax = pt.imshow(imgBGR_ * 255)
        >>> draw_keypoints(ax, kpts_, scale_factor, offset, rotation, ell, pts,
        ...                rect, eig, ori, sifts, siftkw, H=H, **kwargs)
        >>> pt.iup()
        >>> pt.show_if_requested()
    """
    if kpts_.shape[1] == 2:
        # pad out structure if only xy given
        kpts = np.zeros((len(kpts_), 6))
        kpts[:, 0:2] = kpts_
        kpts[:, 2] = 1
        kpts[:, 4] = 1
        kpts_ = kpts

    if scale_factor is None:
        scale_factor = 1.0
    #print('[mpl_keypoint.draw_keypoints] kwargs = ' + ut.dict_str(kwargs))
    # ellipse and point properties
    pts_size       = kwargs.get('pts_size', 2)
    pts_alpha      = kwargs.get('pts_alpha', 1.0)
    ell_alpha      = kwargs.get('ell_alpha', 1.0)
    ell_linewidth  = kwargs.get('ell_linewidth', 2)
    ell_color      = kwargs.get('ell_color', None)
    if ell_color is None:
        ell_color = [1, 0, 0]
    # colors
    pts_color      = kwargs.get('pts_color',  ell_color)
    rect_color     = kwargs.get('rect_color', ell_color)
    eig_color      = kwargs.get('eig_color',  ell_color)
    ori_color      = kwargs.get('ori_color',  ell_color)
    # linewidths
    eig_linewidth  = kwargs.get('eig_linewidth',  ell_linewidth)
    rect_linewidth = kwargs.get('rect_linewidth', ell_linewidth)
    ori_linewidth  = kwargs.get('ori_linewidth',  ell_linewidth)
    # Offset keypoints
    assert len(kpts_) > 0, 'cannot draw no keypoints1'
    kpts = ktool.offset_kpts(kpts_, offset, scale_factor)
    assert len(kpts) > 0, 'cannot draw no keypoints2'
    # Build list of keypoint shape transforms from unit circles to ellipes
    invVR_aff2Ds = get_invVR_aff2Ds(kpts, H=H)
    try:
        if sifts is not None:
            # SIFT descriptors
            pass_props(kwargs, siftkw, 'bin_color', 'arm1_color', 'arm2_color',
                       'arm1_lw', 'arm2_lw', 'arm_alpha', 'arm_alpha', 'multicolored_arms')
            mpl_sift.draw_sifts(ax, sifts, invVR_aff2Ds, **siftkw)
        if rect:
            # Bounding Rectangles
            rect_patches = rectangle_actors(invVR_aff2Ds)
            _draw_patches(ax, rect_patches, rect_color, ell_alpha, rect_linewidth)
        if ell:
            # Keypoint shape
            ell_patches = ellipse_actors(invVR_aff2Ds)
            _draw_patches(ax, ell_patches, ell_color, ell_alpha, ell_linewidth)
        if eig:
            # Shape eigenvectors
            eig_patches = eigenvector_actors(invVR_aff2Ds)
            _draw_patches(ax, eig_patches, eig_color, ell_alpha, eig_linewidth)
        if ori:
            # Keypoint orientation
            ori_patches = orientation_actors(kpts, H=H)
            _draw_patches(ax, ori_patches, ori_color, ell_alpha, ori_linewidth, ori_color)
        if pts:
            # Keypoint locations
            _xs, _ys = ktool.get_xys(kpts)
            if H is not None:
                # adjust for homogrpahy
                import vtool as vt
                _xs, _ys = vt.transform_points_with_homography(H, np.vstack((_xs, _ys)))

            pts_patches = _draw_pts(ax, _xs, _ys, pts_size, pts_color, pts_alpha)
            if pts_patches is not None:
                _draw_patches(ax, pts_patches, 'none', pts_alpha, pts_size, pts_color)
    except ValueError as ex:
        ut.printex(ex, '\n[mplkp] !!! ERROR')
        #print('_oris.shape = %r' % (_oris.shape,))
        #print('_xs.shape = %r' % (_xs.shape,))
        #print('_iv11s.shape = %r' % (_iv11s.shape,))
        raise