Esempio n. 1
0
class RadiusEstimator(RadialFinder):
    '''Estimate vessel radius by fitting a circle'''
    def __init__(self, img, threshold=0.2):
        # The main idea of the algo is based on assumed radiual "symmetry"
        # of the result. So when we fit the circle we don't want to work with
        # all the pixels by just the "rim" ones for each angle
        super(RadiusEstimator, self).__init__(
            f=lambda x: x,
            # For each ray, how do you find a rim?
            reduction=lambda x: reduce_last(x, threshold * np.max(x)),
            img=img)
        # And we will be fitting a circle
        self.model = CircleModel()

    def __call__(self, img):
        '''Estimate for the given image'''
        x_, y_ = self.collect(img)

        ii, = np.where(
            np.logical_and(np.logical_and(x_ > 10, x_ < 80),
                           np.logical_and(y_ > 10, y_ < 80)))

        x_, y_ = x_[ii], y_[ii]
        self.model.estimate(np.c_[x_, y_])
        # Give back the circle parameters
        return self.model.params
Esempio n. 2
0
def test_circle_model_int_overflow():
    xy = np.array([[1, 0], [0, 1], [-1, 0], [0, -1]], dtype=np.int32)
    xy += 500

    model = CircleModel()
    model.estimate(xy)

    assert_almost_equal(model.params, [500, 500, 1])
Esempio n. 3
0
def test_circle_model_estimate():
    # generate original data without noise
    model0 = CircleModel()
    model0.params = (10, 12, 3)
    t = np.linspace(0, 2 * np.pi, 1000)
    data0 = model0.predict_xy(t)

    # add gaussian noise to data
    random_state = np.random.RandomState(1234)
    data = data0 + random_state.normal(size=data0.shape)

    # estimate parameters of noisy data
    model_est = CircleModel()
    model_est.estimate(data)

    # test whether estimated parameters almost equal original parameters
    assert_almost_equal(model0.params, model_est.params, 0)
Esempio n. 4
0
def test_circle_model_estimate():
    # generate original data without noise
    model0 = CircleModel()
    model0.params = (10, 12, 3)
    t = np.linspace(0, 2 * np.pi, 1000)
    data0 = model0.predict_xy(t)

    # add gaussian noise to data
    random_state = np.random.RandomState(1234)
    data = data0 + random_state.normal(size=data0.shape)

    # estimate parameters of noisy data
    model_est = CircleModel()
    model_est.estimate(data)

    # test whether estimated parameters almost equal original parameters
    assert_almost_equal(model0.params, model_est.params, 1)
Esempio n. 5
0
    def fit(self, image):
        B = image > 0.5 * np.max(image)  #+3*np.std(image)

        circle = CircleModel()
        # Need a better model here
        hull = array_convex_hull(B)
        x_, y_ = hull.T
        x_ = np.r_[x_, x_[0]]
        y_ = np.r_[y_, y_[0]]
        circle.estimate(np.c_[x_, y_])

        # Plot ellipse
        XC, YC, R = circle.params
        x = XC + R * np.sin(self.thetas)
        y = YC + R * np.cos(self.thetas)

        self.params = (XC, YC, R)

        return B, np.c_[x, y]
Esempio n. 6
0
    def fit(self, image):
        B = np.zeros_like(image)
        # Radial sample for maximum
        x_, y_ = self.m.collect(image)
        # We are only after points that are not too far
        ii, = np.where(
            np.logical_and(np.logical_and(x_ > 10, x_ < 80),
                           np.logical_and(y_ > 10, y_ < 80)))
        x_ = x_[ii]
        y_ = y_[ii]
        B[x_, y_] = 1

        circle = CircleModel()
        circle.estimate(np.c_[x_, y_])

        XC, YC, R = circle.params
        x = XC + R * np.sin(self.thetas)
        y = YC + R * np.cos(self.thetas)

        self.params = (XC, YC, R)

        return B, np.c_[x, y]
Esempio n. 7
0
def test_circle_model_insufficient_data():
    model = CircleModel()

    with expected_warnings(["Input data does not contain enough significant"]):
        model.estimate(np.array([[1, 2], [3, 4]]))

    with expected_warnings(["Input data does not contain enough significant"]):
        model.estimate(np.ones((6, 2)))

    with expected_warnings(["Input data does not contain enough significant"]):
        model.estimate(np.array([[0, 0], [1, 1], [2, 2]]))
Esempio n. 8
0
def fit_objects(image, fit_obj='circle'):
    """Fits objects in each region of the input image, returning the
    parameters of each object.

    Parameters
    ----------
    image : (N, M) ndarray
        Binary input image.
    fit_obj : string, optional (default : 'circle')
        Object to be fitted on the regions. Accepts the strings 'circle'
        and 'ellipse'.

    Returns
    -------
    image_fit : (N, M, 3) ndarray
        An image with objects in green representing the fitted objects
        labeling each region.
    data_fit : array
        The parameters for each object fitted. Each row corresponds to
        a region present on the input image. Each column represents one
        parameter of the fitted object. For fit_obj='circle', they are
        the coordinates for the center of the circle, and the radius
        (x_center, y_center, radius); for fit_obj='ellipse', they are
        the coordinates for the center of the ellipse, the major and
        minor axis and the orientation (x_center, y_center, minor_axis,
        major_axis, theta).

    Examples
    --------
    >>> from skcv.draw import draw_synthetic_circles
    >>> from skimage import img_as_bool
    >>> image = draw_synthetic_circles((512, 512), quant=20, shades=1,
                                       seed=0)
    >>> image_fit, data_fit = fit_objects(img_as_bool(image),
                                          fit_obj='circle')

    >>> from skcv.draw import draw_synthetic_ellipses
    >>> from skimage import img_as_bool
    >>> image = draw_synthetic_ellipses((512, 512), quant=20, shades=1,
                                        seed=0)
    >>> image_fit, data_fit = fit_objects(img_as_bool(image),
                                          fit_obj='ellipse')
    """

    image_fit = gray2rgb(image)

    # checking labels.
    img_label, num_objects = label(image, return_num=True)

    if fit_obj == 'circle':
        obj = CircleModel()
        data_fit = np.zeros((num_objects, 3))
    elif fit_obj == 'ellipse':
        obj = EllipseModel()
        data_fit = np.zeros((num_objects, 5))

    for num in range(num_objects):
        # finding the contour.
        obj_contour = find_contours(img_label == num+1,
                                    fully_connected='high',
                                    level=0)

        try:
            # modelling image using obtained points.
            obj.estimate(obj_contour[0])
            data_fit[num] = obj.params
            aux_fit = data_fit[num].astype(int)

            if fit_obj == 'circle':
                # drawing circle.
                rows, cols = circle(aux_fit[0], aux_fit[1], aux_fit[2],
                                    shape=image_fit.shape)
                image_fit[rows, cols] = [False, True, False]
            elif fit_obj == 'ellipse':
                # drawing ellipse.
                rows, cols = ellipse_perimeter(aux_fit[0], aux_fit[1],
                                               aux_fit[2], aux_fit[3],
                                               aux_fit[4],
                                               shape=image_fit.shape)
                image_fit[rows, cols] = [False, True, False]
        except TypeError:
            print('No sufficient points on region #', num)

    return image_fit, data_fit
Esempio n. 9
0
    fig, ax = plt.subplots(1, 2)
    ax = ax.ravel()

    red_ = foo[idx]
    results = np.zeros_like(red_)
    x_, y_ = m.collect(red_)
    ii, = np.where(
        np.logical_and(np.logical_and(x_ > 10, x_ < 80),
                       np.logical_and(y_ > 10, y_ < 80)))
    x_ = x_[ii]
    y_ = y_[ii]
    results[x_, y_] = 1

    circle = CircleModel()
    circle.estimate(np.c_[x_, y_])

    thetas = np.linspace(0, 2 * np.pi, 200)
    XC, YC, R = circle.params
    x = XC + R * np.sin(thetas)
    y = YC + R * np.cos(thetas)

    ax[0].imshow(red_)
    ax[1].imshow(results)

    ax[0].plot(y, x, color='magenta')
    ax[1].plot(y, x, color='magenta')

    plt.show()
    exit()
    import tqdm
Esempio n. 10
0
deviations = []
for color in (0, 1, 2):
    masked = ma.array(hsv[:, :, color], mask=~canvas.astype(np.bool))
    deviations.append(masked.std())

mole.h = deviations[0]
mole.s = deviations[1]
mole.v = deviations[2]

# In[104]:

from skimage.measure import CircleModel

circle_model = CircleModel()
circle_model.estimate(contours[0])
symmetry = circle_model.residuals(contours[0]).mean()

mole.symmetry = symmetry

# In[125]:

diameter = (19.05 / coin_radius) * (circle_model.params[2])

mole.diameter = diameter

mole.status = 100

db.session.merge(mole)
db.session.commit()