def test_inertia_tensor_2d():
    image = np.zeros((40, 40))
    image[15:25, 5:35] = 1  # big horizontal rectangle (aligned with axis 1)
    T = inertia_tensor(image)
    assert T[0, 0] > T[1, 1]
    np.testing.assert_allclose(T[0, 1], 0)
    v0, v1 = inertia_tensor_eigvals(image, T=T)
    np.testing.assert_allclose(np.sqrt(v0/v1), 3, rtol=0.01, atol=0.05)
Beispiel #2
0
def test_inertia_tensor_2d():
    image = np.zeros((40, 40))
    image[15:25, 5:35] = 1  # big horizontal rectangle (aligned with axis 1)
    T = inertia_tensor(image)
    assert T[0, 0] > T[1, 1]
    np.testing.assert_allclose(T[0, 1], 0)
    v0, v1 = inertia_tensor_eigvals(image, T=T)
    np.testing.assert_allclose(np.sqrt(v0/v1), 3, rtol=0.01, atol=0.05)
Beispiel #3
0
    def inertia_tensor(self):
        '''
        Compute the inertia tensor of the image and retrun the eigenvalue and eigenvector.
        :return eigval: eigenvalue
        :return eigvec: eigenvector
        '''
        inertia = skim.inertia_tensor(self.field)
        eigval, eigvec = np.linalg.eig(inertia)

        return eigval / self.res, eigvec
Beispiel #4
0
def get_inertia(mask, mu=None):
    """compute inertia tensor and eigenvalues from mask, if moments are give the function is much faster"""
    if mu is None:
        mu = measure.moments(mask)

    inertia_tensor = measure.inertia_tensor(mask, mu)
    inertia_eigen = measure.inertia_tensor_eigvals(mask,
                                                   mu=mu,
                                                   T=inertia_tensor)
    return inertia_tensor, inertia_eigen
Beispiel #5
0
def test_inertia_tensor_3d():
    image = draw.ellipsoid(10, 5, 3)
    T0 = inertia_tensor(image)
    eig0, V0 = np.linalg.eig(T0)
    # principal axis of ellipse = eigenvector of smallest eigenvalue
    v0 = V0[:, np.argmin(eig0)]

    assert np.allclose(v0, [1, 0, 0]) or np.allclose(-v0, [1, 0, 0])

    imrot = ndi.rotate(image.astype(float), 30, axes=(0, 1), order=1)
    Tr = inertia_tensor(imrot)
    eigr, Vr = np.linalg.eig(Tr)
    vr = Vr[:, np.argmin(eigr)]

    # Check that axis has rotated by expected amount
    pi, cos, sin = np.pi, np.cos, np.sin
    R = np.array([[cos(pi / 6), -sin(pi / 6), 0],
                  [sin(pi / 6), cos(pi / 6), 0], [0, 0, 1]])
    expected_vr = R @ v0
    assert (np.allclose(vr, expected_vr, atol=1e-3, rtol=0.01)
            or np.allclose(-vr, expected_vr, atol=1e-3, rtol=0.01))
def test_inertia_tensor_3d():
    image = draw.ellipsoid(10, 5, 3)
    T0 = inertia_tensor(image)
    eig0, V0 = np.linalg.eig(T0)
    # principal axis of ellipse = eigenvector of smallest eigenvalue
    v0 = V0[:, np.argmin(eig0)]

    assert np.allclose(v0, [1, 0, 0]) or np.allclose(-v0, [1, 0, 0])

    imrot = ndi.rotate(image.astype(float), 30, axes=(0, 1), order=1)
    Tr = inertia_tensor(imrot)
    eigr, Vr = np.linalg.eig(Tr)
    vr = Vr[:, np.argmin(eigr)]

    # Check that axis has rotated by expected amount
    pi, cos, sin = np.pi, np.cos, np.sin
    R = np.array([[ cos(pi/6), -sin(pi/6), 0],
                  [ sin(pi/6),  cos(pi/6), 0],
                  [         0,          0, 1]])
    expected_vr = R @ v0
    assert (np.allclose(vr, expected_vr, atol=1e-3, rtol=0.01) or
            np.allclose(-vr, expected_vr, atol=1e-3, rtol=0.01))
Beispiel #7
0
def test_inertia_tensor_2d(dtype):
    image = np.zeros((40, 40), dtype=dtype)
    image[15:25, 5:35] = 1  # big horizontal rectangle (aligned with axis 1)
    expected_dtype = _supported_float_type(image.dtype)

    T = inertia_tensor(image)
    assert T.dtype == expected_dtype
    assert T[0, 0] > T[1, 1]
    np.testing.assert_allclose(T[0, 1], 0)

    v0, v1 = inertia_tensor_eigvals(image, T=T)
    assert v0.dtype == expected_dtype
    assert v1.dtype == expected_dtype
    np.testing.assert_allclose(np.sqrt(v0 / v1), 3, rtol=0.01, atol=0.05)
def detect_chars_pos_and_img(frame, robot_pos):
    """
    Detect where all the characters are in the frame and returns the list of it.
    Frame is single channel image of the blue and black values (characters on the area).
    """
    # Morphology to make the equal and divide one shape
    kernel = np.zeros((9, 9), np.uint8)
    cv.circle(img=kernel, center=(4, 4), radius=4, color=255, thickness=-1)
    dilated_img = cv.morphologyEx(frame, cv.MORPH_CLOSE, kernel, iterations=1)

    # Find the contours of images
    contours, _ = cv.findContours(image=dilated_img,
                                  mode=cv.RETR_EXTERNAL,
                                  method=cv.CHAIN_APPROX_SIMPLE)
    chars_pos = []
    chars_img = []

    for contour in contours:
        # Find bounding box for each contour
        x, y, w, h = cv.boundingRect(contour)
        # Verify with the box is big enough and not close to the robot
        r = range(2, 60)
        R = range(15, 60)
        robot_pos_threshold = 50
        robot_dist = norm((x + w / 2 - robot_pos[0], y + h / 2 - robot_pos[1]))
        if np.min([w, h]) in r and np.max(
            [w, h]) in R and robot_dist > robot_pos_threshold:
            # Extract image
            extracted_img = frame[y:y + h, x:x + w]
            # Compute angle of rotation
            mu = inertia_tensor(extracted_img)
            alpha = np.degrees(1 / 2 * np.arctan2(2 * mu[0][1],
                                                  (mu[1][1] - mu[0][0])))
            # Rotate image to align vertically
            rotation_matrix = cv.getRotationMatrix2D((int(w / 2), int(h / 2)),
                                                     alpha, 1)
            rotated_img = cv.warpAffine(
                extracted_img, rotation_matrix,
                (np.max([extracted_img.shape[1], extracted_img.shape[0]]),
                 np.max([extracted_img.shape[1], extracted_img.shape[0]])))
            # Normalize image for the CNN
            normalized_img = normalize_img(rotated_img)
            # Add position of char to the list
            chars_pos.append((x + w / 2, y + h / 2))
            # Add char image to the list
            chars_img.append(normalized_img)
    return chars_pos, chars_img
def moments_features(image):
    """calculates the set of moments for each channel
    
    Calculates the intertia tensor, intertia tensor eigenvalues, as well as 
    the moments of the image (https://en.wikipedia.org/wiki/Image_moment)

    Parameters
    ----------
    image : 3D array, shape (M, N, C)
        The input image with multiple channels.

    Returns
    -------
    features :  dict  
        dictionary including percentiles, moments and sum per channel 

    """
    # storing the feature values
    features = dict()
    for ch in range(image.shape[2]):
        hu_moments = moments_hu(image[:, :, ch])
        for i in range(len(hu_moments)):
            features["moments_hu_" + str(i + 1) + "_Ch" +
                     str(ch + 1)] = hu_moments[i]

        inertia_tensor_calculated = inertia_tensor(image[:, :, ch]).ravel()
        features["inertia_tensor_1_ch" +
                 str(ch + 1)] = inertia_tensor_calculated[0]
        features["inertia_tensor_2_ch" +
                 str(ch + 1)] = inertia_tensor_calculated[1]
        features["inertia_tensor_3_ch" +
                 str(ch + 1)] = inertia_tensor_calculated[3]

        inertia_tensor_eigvalues = inertia_tensor_eigvals(image[:, :, ch])
        features["inertia_tensor_eigvalues_1_ch" +
                 str(ch + 1)] = inertia_tensor_eigvalues[0]
        features["inertia_tensor_eigvalues_2_ch" +
                 str(ch + 1)] = inertia_tensor_eigvalues[1]

        the_moments = moments(image[:, :, ch], order=5).ravel()

        for i in range(len(the_moments)):
            features["moments_" + str(i + 1) + "_Ch" +
                     str(ch + 1)] = the_moments[i]

    return features