Exemplo n.º 1
0
 def create_basist(self, block=15, n=10):
     npt = (n - 1) * block + 1
     basist = zeros([npt, n])
     x = arange(npt) / float(block)
     for jx in range(n):
         basist[:, jx] = signal.bspline(x - jx, 2)
     # end-effects, it's important that the sum is flat
     basist[:, 0] += signal.bspline(x + 1, 2)
     basist[:, n - 1] += signal.bspline(x - n, 2)
     return basist
Exemplo n.º 2
0
def find_peak_start(input, treshold=0.001, peak_length=15):
    input = numpy.abs(numpy.gradient(signal.bspline(input, 25)))

    # Control parameters
    input_treshold = numpy.nanmax(input) * treshold
    input_length = input.shape[0]
    recording = False
    start_x = 0
    stop_x = 0

    # Walk from start to end. When the current value exceeds threshold,
    # start recording.
    for i in range(0, input_length):
        if recording:
            if input[i] > treshold:
                stop_x = i

                if (stop_x - start_x) > peak_length:
                    return start_x
            else:
                recording = False
        else:
            if input[i] > treshold:
                start_x = i
                recording = True

    # Nothing found
    return 0
Exemplo n.º 3
0
def find_peak_start(input, treshold=0.001, peak_length=15):
    input = numpy.abs(numpy.gradient(signal.bspline(input, 25)))

    # Control parameters
    input_treshold = numpy.nanmax(input) * treshold
    input_length = input.shape[0]
    recording = False
    start_x = 0
    stop_x = 0

    # Walk from start to end. When the current value exceeds threshold,
    # start recording.
    for i in range(0, input_length):
        if recording:
            if input[i] > treshold:
                stop_x = i

                if (stop_x - start_x) > peak_length:
                    return start_x
            else:
                recording = False
        else:
            if input[i] > treshold:
                start_x = i
                recording = True

    # Nothing found
    return 0
Exemplo n.º 4
0
def main():
    from scipy.signal import bspline

    orders = [1, 2, 3]
    particle_positions = 3. + np.arange(0, 1., 0.1)

    bsplines = []
    path = sys.argv[1]

    for centering in ["primal", "dual"]:

        for order in orders:
            filename = os.path.join(path, f"bsplines_{order}_{centering}.dat")

            node_splines = np.zeros((order + 1, particle_positions.size),
                                    dtype=np.int32)
            splines_val = np.zeros((order + 1, particle_positions.size),
                                   dtype=np.float64)

            for ipos, pos in enumerate(particle_positions):
                node_splines[:, ipos] = get_nodes(pos, order, centering)

            # loop on all nodes and calculate the spline at the node
            # from the current particle position

            with open(filename, 'wb') as f:
                for ipos, pos in enumerate(particle_positions):
                    if centering == "dual":
                        pos -= .5
                    splines_val[:, ipos] = bspline(node_splines[:, ipos] - pos,
                                                   order)
                    print(ipos, node_splines[:, ipos], splines_val[:, ipos])
                    node_splines[:, ipos].tofile(f)
                    splines_val[:, ipos].tofile(f)
Exemplo n.º 5
0
def main():

    orders = [1,2,3]
    particle_positions = 3. + np.arange(0,1.,0.1)

    bsplines = []

    path = sys.argv[1]

    for order in orders:
        filename = path+os.path.sep + "bsplines_{}.dat".format(order)

        node_splines = np.zeros((order+1, particle_positions.size), dtype=np.int32)
        splines_val  = np.zeros((order+1, particle_positions.size), dtype=np.float64)

        for ipos, pos in enumerate(particle_positions):
            node_splines[:,ipos] = get_nodes(pos, order)

        # loop on all nodes and calculate the spline at the node
        # from the current particle position

        with open(filename, 'wb') as f:
            for ipos, pos in enumerate(particle_positions):
                splines_val[:,ipos] = bspline(node_splines[:, ipos] - pos, order)
                print(ipos, node_splines[:, ipos], splines_val[:,ipos])
                node_splines[:, ipos].tofile(f)
                splines_val[:, ipos].tofile(f)
 def __call__(self, d):
     sfact = self.s // d + 1
     #w =  np.bartlett(2*sfact+1)
     w = signal.bspline(np.linspace(-2, 2, 4 * sfact + 1), 3)
     fh = ndi.convolve1d(self.mat, w, axis=0, mode='constant')
     fh = ndi.convolve1d(fh, w, axis=1, mode='constant')
     sh = ndi.zoom(fh, d / self.s, order=3, prefilter=False)
     return sh
Exemplo n.º 7
0
    def __basis(self, order=4, divisions=4):
        """
        Follows the derivations in:

        Kybic, J. and Unser, M. (2003). Fast parametric elastic image
        registration. IEEE Transactions on Image Processing, 12(11), 1427-1442.

        Computes the spline tensor product and stores the products, as basis
        vectors.

        @param order: b-spline order.
        @param division: number of spline knots.
        """

        shape = self.coordinates.tensor[0].shape
        grid = self.coordinates.tensor

        spacing = shape[1] / divisions
        xKnots = shape[1] / spacing
        yKnots = shape[0] / spacing

        Qx = np.zeros((grid[0].size, xKnots))
        Qy = np.zeros((grid[0].size, yKnots))

        for index in range(0, xKnots):
            bx = signal.bspline( grid[1] / spacing - index, order)
            Qx[:,index] = bx.flatten()

        for index in range(0, yKnots):
            by = signal.bspline( grid[0] / spacing - index, order)
            Qy[:,index] = by.flatten()

        basis = []
        for j in range(0,xKnots):
            for k in range(0, yKnots):
                basis.append(Qx[:,j]*Qy[:,k])

        self.basis = np.array(basis).T
Exemplo n.º 8
0
    def __basis(self, order=4, divisions=5):
        """
        Computes the spline tensor product and stores the products, as basis
        vectors.

        Parameters
        ----------
        order: int
            B-spline order, optional.
        divisions: int, optional.
            Number of spline knots.
        """

        shape = self.coordinates.tensor[0].shape
        grid = self.coordinates.tensor

        spacing = shape[1] / divisions
        xKnots = shape[1] / spacing
        yKnots = shape[0] / spacing

        Qx = np.zeros((grid[0].size, xKnots))
        Qy = np.zeros((grid[0].size, yKnots))

        for index in range(0, xKnots):
            bx = signal.bspline(grid[1] / spacing - index, order)
            Qx[:, index] = bx.flatten()

        for index in range(0, yKnots):
            by = signal.bspline(grid[0] / spacing - index, order)
            Qy[:, index] = by.flatten()

        basis = []
        for j in range(0, xKnots):
            for k in range(0, yKnots):
                basis.append(Qx[:, j] * Qy[:, k])

        self.basis = np.array(basis).T
Exemplo n.º 9
0
    def __basis(self, order=4, divisions=4):
        """
        Computes the spline tensor product and stores the products, as basis
        vectors.
    
        Parameters
        ----------
        order: int
            B-spline order, optional.
        divisions: int, optional.
            Number of spline knots.
        """

        shape = self.coordinates.tensor[0].shape
        grid = self.coordinates.tensor

        spacing = shape[1] / divisions
        xKnots = shape[1] / spacing
        yKnots = shape[0] / spacing

        Qx = np.zeros((grid[0].size, xKnots))
        Qy = np.zeros((grid[0].size, yKnots))

        for index in range(0, xKnots):
            bx = signal.bspline( grid[1] / spacing - index, order)
            Qx[:,index] = bx.flatten()

        for index in range(0, yKnots):
            by = signal.bspline( grid[0] / spacing - index, order)
            Qy[:,index] = by.flatten()

        basis = []
        for j in range(0,xKnots):
            for k in range(0, yKnots):
                basis.append(Qx[:,j]*Qy[:,k])

        self.basis = np.array(basis).T
Exemplo n.º 10
0
    def _shape(self, x, y):
        """Private method calculate b-spline value for particles on x-position on grid

        Keyword arguments:
        ------------------
        x -- position on grid (numpy.array)
        y -- particle(s) position (numpy.array)
              
        Return:
        -------
        bspline (numpy.array of float) of B-spline(x,order) value representing kernel  
        """

        ksi = (x - y) / self.particles.support_scale
        return sb.bspline(ksi, self.spline_order)
Exemplo n.º 11
0
def interpolate(img_stack, slices, method='bcspline'):
    """interpolate a single frame. method can be none, bilinear, lanczos3, or bcspline"""

    #TODO: make this more efficient!!
    if method == 'none':
        return img_stack

    #create the filter based on the type of interpolation:
    if method == 'bcspline':
        #reconstruction/interpolation filter
        #3rd order bspline function
        filt = signal.bspline([-1.5, -1.0, -0.5, 0.0, 0.5, 1.0, 1.5], 3)
    elif method == 'bilinear':
        filt = [0.5, 1.0, 0.5]
    elif method == 'lanczos3':
        #x = linspace(-2.5,2.5,11) #evenly spaced from -2.5 to 2.5 by 0.5 increments
        #filt = sinc(x/3)*sinc(x)
        filt = [
            2.44565217e-02, 0, -1.35869565e-01, 0, 6.11413043e-01, 1,
            6.11413043e-01, 0, -1.35869565e-01, 0, 2.44565217e-02
        ]

    #allocate the output array:
    #img_stack.shape is (w/2, h/2, 4)
    #we're going to expand to (w,h,4):
    s = list(img_stack.shape)
    s[:2] = np.multiply(s[:2], 2)  #element-wise multiply (w,h,4)
    #interpolated result:
    interp_stack = zeros(s)

    #interpolation coefficients for intermediate steps
    c_jk = zeros(s[:2])  #(w,h)

    #loop over last dimension (i0,i90,...)
    for j in xrange(s[-1]):
        #zero the coefficients
        c_jk[...] = 0.0
        #get coefficients
        if method in ['bilinear', 'lanczos3']:
            #coefficients are just the image slices
            c_jk[slices[j]] = img_stack[..., j]
        elif method == 'bcspline':
            #coefficients are bicubic spline coefficients for slice
            c_jk[slices[j]] = signal.cspline2d(img_stack[..., j])
        #convolve (filters are seperable, so we can use sepfir2d)
        interp_stack[..., j] = signal.sepfir2d(c_jk, filt, filt)
    #return interpolated image:
    return interp_stack
    def aggregate_windows(self, window_seq, order=2, **kwargs):
        """
        
        :param window_seq: 
        :param order: 
        :param kwargs: 
        :return: 
        """

        coef = 30
        for window in window_seq:
            splined_window = bspline(
                1 - np.array(window)[::coef],
                n=order,
            )
            for win_index, win_item in enumerate(splined_window):
                for i in range(coef):
                    yield win_item
Exemplo n.º 13
0
    def pair_eval(self, X, Y):
        """
        Evaluate k(x1, y1), k(x2, y2), ...

        Parameters
        ----------
        X, Y : n x 1 numpy array

        Return
        -------
        a numpy array with length n
        """
        (n1, d1) = X.shape
        (n2, d2) = Y.shape
        assert d1 == 1, 'd1 must be 1'
        assert d2 == 1, 'd2 must be 1'
        diff = (X - Y) / self.width
        Kvec = sig.bspline(diff, 1)
        return Kvec
Exemplo n.º 14
0
    def pair_eval(self, X, Y):
        """
        Evaluate k(x1, y1), k(x2, y2), ...

        Parameters
        ----------
        X, Y : n x 1 numpy array

        Return
        -------
        a numpy array with length n
        """
        (n1, d1) = X.shape
        (n2, d2) = Y.shape
        assert d1==1, 'd1 must be 1'
        assert d2==1, 'd2 must be 1'
        diff = old_div((X-Y),self.width)
        Kvec = sig.bspline( diff , 1)
        return Kvec
Exemplo n.º 15
0
    def eval(self, X1, X2):
        """
        Evaluate the triangular kernel on the two 2d numpy arrays.

        Parameters
        ----------
        X1 : n1 x 1 numpy array
        X2 : n2 x 1 numpy array

        Return
        ------
        K : a n1 x n2 Gram matrix.
        """
        (n1, d1) = X1.shape
        (n2, d2) = X2.shape
        assert d1 == 1, 'd1 must be 1'
        assert d2 == 1, 'd2 must be 1'
        diff = (X1 - X2.T) / self.width
        K = sig.bspline(diff, 1)
        return K
Exemplo n.º 16
0
    def eval(self, X1, X2):
        """
        Evaluate the triangular kernel on the two 2d numpy arrays.

        Parameters
        ----------
        X1 : n1 x 1 numpy array
        X2 : n2 x 1 numpy array

        Return
        ------
        K : a n1 x n2 Gram matrix.
        """
        (n1, d1) = X1.shape
        (n2, d2) = X2.shape
        assert d1==1, 'd1 must be 1'
        assert d2==1, 'd2 must be 1'
        diff = old_div((X1-X2.T),self.width)
        K = sig.bspline( diff , 1)
        return K
    def aggregate_windows(self,
                          window_seq,
                          order=2,
                          **kwargs):
        """
        
        :param window_seq: 
        :param order: 
        :param kwargs: 
        :return: 
        """

        coef = 30
        for window in window_seq:
            splined_window = bspline(
                1 - np.array(window)[::coef],
                n=order,
            )
            for win_index, win_item in enumerate(splined_window):
                for i in range(coef):
                    yield win_item
Exemplo n.º 18
0
    def eval(self, X1, X2):
        """
        Evaluate the triangular kernel on the two 2d numpy arrays.

        Parameters
        ----------
        X1 : n1 x 1 numpy array
        X2 : n2 x 1 numpy array

        Return
        ------
        K : a n1 x n2 Gram matrix.
        """
        d1 = X1.shape[1]
        if d1 != 1:
            raise ValueError("The X1 dimension (_, {}) must be 1".format(d1))

        d2 = X2.shape[1]
        if d2 != 1:
            raise ValueError("The X2 dimension (_, {}) must be 1".format(d2))

        diff = X1 - X2.T
        np.divide(diff, self.width, out=diff)
        return signal.bspline(diff, 1)
Exemplo n.º 19
0
 def test_splines(self):
     x = np.linspace(-10, 10, 10000)
     for degree in range(9):
         np.testing.assert_allclose(signal.bspline(x, degree),
                                    bsplines.bspline(x, degree))
Exemplo n.º 20
0
        return None
    n_b = n + 1
    n = (n + 1) / h
    b = [0 for _ in np.arange(-1 * n / 2, (n / 2) + 0.5, 0.5)]
    x = [i * h for i in np.arange(-1 * n / 2, (n / 2) + 0.5, 0.5)]
    if n == 1:
        for i in range(0, len(x)):
            b[i] = b_n_first(x[i])
        return x, b
    for i in range(0, len(x)):
        b[i] = b_n(x[i], n_b)
    return x, b


if __name__ == '__main__':
    x_10, y_10 = beta_spline(10)
    x_15, y_15 = beta_spline(15)
    y_signal = signal.bspline(x_15, 15)
    sns.set()
    fig, axs = plt.subplots(2, figsize=(WIDTH, HEIGHT))
    axs[0].plot(x_10, y_10, color='red')
    axs[0].plot(x_15, y_15, color='green')
    axs[0].set_title('Beta Splines')
    axs[0].set_xlabel('X')
    axs[0].set_ylabel('Y')
    axs[0].legend(['Spline (n=10)', 'Spline (n=15)'])
    axs[1].plot(x_15, y_signal, color='black')
    axs[1].set_xlabel('X')
    axs[1].set_ylabel('Y')
    axs[1].legend(['Spline (scipy.gignal, n=15)'])
    plt.show()
Exemplo n.º 21
0
    def featgrid(self, center, value, type_='fast_gaussian'):
        """Map an individual feature (atomic or residue) on the grid.

        Args:
            center (list(float)): position of the feature center
            value (float): value of the feature
            type_ (str, optional): method to map

        Returns:
            np.array: Mapped feature

        Raises:
            ValueError: Description
        """

        # shortcut for th center
        x0, y0, z0 = center
        sigma = np.sqrt(1. / 2)
        beta = 0.5 / (sigma**2)

        # simple Gaussian
        if type_ == 'gaussian':
            dd = np.sqrt((self.xgrid - x0)**2
                         + (self.ygrid - y0)**2
                         + (self.zgrid - z0)**2)
            dd = value * np.exp(-beta * dd)
            return dd

        # fast gaussian
        elif type_ == 'fast_gaussian':

            cutoff = 5. * beta

            dd = np.sqrt((self.xgrid - x0)**2
                         + (self.ygrid - y0)**2
                         + (self.zgrid - z0)**2)
            dgrid = np.zeros(self.npts)

            dgrid[dd < cutoff] = value * np.exp(-beta * dd[dd < cutoff])

            return dgrid

        # Bsline
        elif type_ == 'bspline':
            spline_order = 4
            spl = bspline((self.xgrid - x0) / self.res[0], spline_order) \
                * bspline((self.ygrid - y0) / self.res[1], spline_order) \
                * bspline((self.zgrid - z0) / self.res[2], spline_order)
            dd = value * spl
            return dd

        # nearest neighbours
        elif type_ == 'nearest':

            # distances
            dx = np.abs(self.x - x0)
            dy = np.abs(self.y - y0)
            dz = np.abs(self.z - z0)

            # index
            indx = np.argsort(dx)[:2]
            indy = np.argsort(dy)[:2]
            indz = np.argsort(dz)[:2]

            # weight
            wx = dx[indx]
            wx /= np.sum(wx)

            wy = dy[indy]
            wy /= np.sum(wy)

            wz = dx[indz]
            wz /= np.sum(wz)

            # define the points
            indexes = [indx, indy, indz]
            points = list(itertools.product(*indexes))

            # define the weight
            W = [wx, wy, wz]
            W = list(itertools.product(*W))
            W = [np.sum(iw) for iw in W]

            # put that on the grid
            dgrid = np.zeros(self.npts)

            for w, pt in zip(W, points):
                dgrid[pt[0], pt[1], pt[2]] = w * value

            return dgrid

        # default
        else:
            raise ValueError(f'Options not recognized for the grid {type_}')
Exemplo n.º 22
0
import numpy as np
import matplotlib.pyplot as plt
import scipy.signal as sps
import scipy.interpolate as spi

# plot cubic cardinal B-spline (knots 0, 1, 2, 3, 4)
p = 3
xx = np.linspace(0, p + 1, 100)
yy = sps.bspline(xx - (p + 1) / 2, p)
plt.plot(xx, yy)
plt.show()

# plot cubic non-uniform spline (m=5 DOFs)
xi = [0, 1, 3, 4, 6, 7, 8, 10, 11]
c = [2, -1, 1, 0, 1]
s = spi.BSpline(xi, c, p)
m = len(c)
xx = np.linspace(xi[p], xi[m])
yy = s(xx)
plt.plot(xx, yy)
plt.show()
Exemplo n.º 23
0
def spline_fit(x, y, weights, xfit):
    """
    Fit a cubic b-spline to y vs. x with weights and full error propagation.
    Return fit with diagonalized errors.

    Inputs:
        x, y, weights : numpy arrays sorted by ascending x
    
    Returns 1D arrays:
        coadd_y[]
        coadd_ivar[]
        
    Where coadd_ivar is the diagonal inverse variance of coadd_y.
    """
    #- Setup cubic b-spline basis matrix: y = A coeff
    t0 = time()
    ny = len(y)
    dxfit = N.gradient(xfit)
    A = N.zeros( (ny, len(xfit)) )
    for i in range(A.shape[0]):
        A[i] = bspline((x[i] - xfit)/dxfit, 3)

    t0 = timeit("Setup A", t0)

    #- Convert to sparse matrices
    A = scipy.sparse.dia_matrix(A)
    W = spdiags(weights, 0, ny, ny)
    t0 = timeit("Sparsify A", t0)

    #- Generate inverse covariance matrix
    iCovCoeff = A.T.dot(W.dot(A))

    #- Solve "y = A coeff" with weights -> (A.T W) y = (A.T W A) coeff
    wy = A.T.dot(W.dot(y))
    t0 = timeit("Apply weights", t0)
    # coeff = scipy.sparse.linalg.lsqr(iCovCoeff, wy)[0]   
    # t0 = timeit("Solve", t0)

    #- Solve with banded matrices
    iCovDiag = iCovCoeff.todia().data[-1::-1, :]  #- have to flip for solver
    ndiag = iCovDiag.shape[0]/2
    coeff = scipy.linalg.solve_banded((ndiag, ndiag), iCovDiag, wy)
    t0 = timeit("Solve", t0)

    #- Evaluate b-spline solution at xfit
    B = N.zeros( (len(xfit), len(xfit)) )
    for i in range(B.shape[0]):
        B[i] = bspline((xfit[i] - xfit)/dxfit, 3)

    coadd = B.dot(coeff)
    t0 = timeit("Evaluate", t0)
    
    ### This is the expensive step as matrices get larger
    ### could use eig_banded and invert with that
    #- Convert iCov for coefficients into iCov for the coadd itself
    #-   coadd = B coeff
    #-   CovCoadd = B CovCoeff B.T
    #-   iCovCoadd = iB.T iCovCoeff iB,  since B is square and invertable
    iB = N.linalg.inv(B)
    iCovCoadd = iB.T.dot( iCovCoeff.dot(iB) )
    t0 = timeit("Get iCov(coadd)", t0)
    
    ### This is the next most expensive step as matrices get larger
    #- Diagonalize errors
    try:
        R, coivar = resolution_from_icov(iCovCoadd)
        Rc = R.dot(coadd)
    except:
        print "ERROR: Unable to find R for range", xfit[0], xfit[1]
        return N.zeros(len(coadd)), N.zeros(len(coadd))
    t0 = timeit("Diagonalize", t0)
        
    return Rc, coivar
Exemplo n.º 24
0
def key_points(face,
               d_nose_x1=30,
               d_nose_x2=5,
               d_nose_y=5,
               d_lip_y1=25,
               d_lip_y2=70,
               d_lip_y3=4,
               d_lip_x1=45,
               d_chin_x=3,
               d_chin_y1=10,
               d_chin_y2=75,
               d_eye_x=2,
               d_eye_y=50):
    """
    Rotate and zoom the face to create a full frame face. This is based on the
    fact that the nose is the highest point of the picture
    """

    # We apply surfature to calculate the first and second derivates
    K, H, Pmax, Pmin = surfature(face)

    # Remove all key points
    face.key_points.clear()

    #
    # Nose
    #
    nose_x, nose_y = max_xy(face.Z)
    face.key_points["nose"] = (nose_x, nose_y)

    #
    # Nose left and right
    #
    nose_left = Pmin[(nose_y - d_nose_y):(nose_y + d_nose_y),
                     (nose_x - d_nose_x1):(nose_x - d_nose_x2)]
    nose_right = Pmin[(nose_y - d_nose_y):(nose_y + d_nose_y),
                      (nose_x + d_nose_x2):(nose_x + d_nose_x1)]

    nose_left_x, nose_left_y = min_xy(nose_left,
                                      offset_x=(nose_x - d_nose_x1),
                                      offset_y=(nose_y - d_nose_y))
    nose_right_x, nose_right_y = min_xy(nose_right,
                                        offset_x=(nose_x + d_nose_x2),
                                        offset_y=(nose_y - d_nose_y))

    face.key_points["nose_left"] = (nose_left_x, nose_left_y)
    face.key_points["nose_right"] = (nose_right_x, nose_right_y)

    #
    # Upper, lower, left right lip
    #
    lip_y = numpy.nanargmax(Pmax[(nose_y + d_lip_y1):(nose_y + d_lip_y2),
                                 nose_x]) + (nose_y + d_lip_y1)
    lip_left = Pmax[(lip_y - d_lip_y3):(lip_y + d_lip_y3),
                    (nose_x - d_lip_x1):nose_x]
    lip_right = Pmax[(lip_y - d_lip_y3):(lip_y + d_lip_y3),
                     nose_x:(nose_x + d_lip_x1)]

    lip_left_x = find_peak_start(numpy.sum(lip_left,
                                           axis=0)) + (nose_x - d_lip_x1)
    lip_left_y = numpy.nanargmax(Pmax[(lip_y - d_lip_y3):(lip_y + d_lip_y3),
                                      lip_left_x]) + (lip_y - d_lip_y3)

    lip_right_x = find_peak_stop(numpy.sum(lip_right, axis=0)) + nose_x
    lip_right_y = numpy.nanargmax(Pmax[(lip_y - d_lip_y3):(lip_y + d_lip_y3),
                                       lip_right_x]) + (lip_y - d_lip_y3)

    face.key_points['lip'] = (nose_x, lip_y)
    face.key_points['lip_left'] = (lip_left_x, lip_left_y)
    face.key_points['lip_right'] = (lip_right_x, lip_right_y)

    #
    # Chin
    #
    chin = numpy.gradient(
        signal.bspline(face.Z[(lip_y + d_chin_y1):, nose_x], 25))
    chin_x, chin_y = nose_x, numpy.nanargmin(chin) + (lip_y + d_chin_y1)

    face.key_points["chin"] = (chin_x, chin_y)

    #
    # Eyes
    #
    eye_left = Pmax[nose_left_y - d_eye_y:nose_left_y + d_eye_y,
                    nose_left_x - d_eye_x:nose_left_x + d_eye_x]
    eye_right = Pmax[nose_right_y - d_eye_y:nose_right_y + d_eye_y,
                     nose_right_x - d_eye_x:nose_right_x + d_eye_x]

    eye_left_x, eye_left_y = max_xy(eye_left, nose_left_x - d_eye_x, d_eye_y)
    eye_right_x, eye_right_y = max_xy(eye_right, nose_right_x - d_eye_x,
                                      d_eye_y)

    face.key_points["eye_left"] = (eye_left_x, eye_left_y)
    face.key_points["eye_right"] = (eye_right_x, eye_right_y)

    #
    # Nose face border
    #
    nose_line = numpy.gradient(face.Z[nose_y, :])
    border_nose_left_x, border_nose_left_y = numpy.nanargmax(
        nose_line[:lip_left_x - 10]), nose_y
    border_nose_right_x, border_nose_right_y = numpy.nanargmin(
        nose_line[lip_right_x:]) + lip_right_x + 10, nose_y

    face.key_points["border_nose_left"] = (border_nose_left_x,
                                           border_nose_left_y)
    face.key_points["border_nose_right"] = (border_nose_right_x,
                                            border_nose_right_y)

    #
    # Lip face border
    #
    lip_line = numpy.gradient(face.Z[lip_y, :])
    border_lip_left_x, border_lip_left_y = numpy.nanargmax(
        lip_line[:lip_left_x - 10]), lip_y
    border_lip_right_x, border_lip_right_y = numpy.nanargmin(
        lip_line[lip_right_x:]) + lip_right_x + 10, lip_y

    face.key_points["border_lip_left"] = (border_lip_left_x, border_lip_left_y)
    face.key_points["border_lip_right"] = (border_lip_right_x,
                                           border_lip_right_y)

    #
    # Forehead border
    #
    forehead_line = numpy.gradient(face.Z[nose_y - (chin_y - nose_y), :])
    border_forehead_left_x, border_forehead_left_y = numpy.nanargmax(
        forehead_line[:lip_left_x - 10]), nose_y - (chin_y - nose_y)
    border_forehead_right_x, border_forehead_right_y = numpy.nanargmin(
        forehead_line[lip_right_x:]) + lip_right_x + 10, nose_y - (chin_y -
                                                                   nose_y)

    face.key_points["border_forehead_left"] = (border_forehead_left_x,
                                               border_forehead_left_y)
    face.key_points["border_forehead_right"] = (border_forehead_right_x,
                                                border_forehead_right_y)
Exemplo n.º 25
0
def key_points(face, 
    d_nose_x1=30, d_nose_x2=5, d_nose_y=5,
    d_lip_y1=25, d_lip_y2=70, d_lip_y3=4, d_lip_x1=50,
    d_chin_x=3, d_chin_y1=50, d_chin_y2=75,
    d_eye_x=2, d_eye_y=50):

    """
    Rotate and zoom the face to create a full frame face. This is based on the
    fact that the nose is the highest point of the picture
    """

    # We apply surfature to calculate the first and second derivates
    K, H, Pmax, Pmin = surfature(face)

    # Remove all key points 
    face.key_points.clear()

    #
    # Nose
    #
    nose_x, nose_y = max_xy(face.Z)
    face.key_points["nose"] = (nose_x, nose_y)

    #
    # Nose left and right
    #
    nose_left = Pmin[(nose_y - d_nose_y):(nose_y + d_nose_y), (nose_x - d_nose_x1):(nose_x - d_nose_x2)]
    nose_right = Pmin[(nose_y - d_nose_y):(nose_y + d_nose_y), (nose_x + d_nose_x2):(nose_x + d_nose_x1)]

    nose_left_x, nose_left_y = min_xy(nose_left, offset_x=(nose_x - d_nose_x1), offset_y=(nose_y - d_nose_y))
    nose_right_x, nose_right_y = min_xy(nose_right, offset_x=(nose_x + d_nose_x2), offset_y=(nose_y - d_nose_y))

    face.key_points["nose_left"] = (nose_left_x, nose_left_y)
    face.key_points["nose_right"] = (nose_right_x, nose_right_y)

    # 
    # Upper, lower, left right lip
    #
    lip_y = numpy.nanargmax(Pmax[(nose_y + d_lip_y1):(nose_y + d_lip_y2), nose_x]) + (nose_y + d_lip_y1)
    lip_left = Pmax[(lip_y - d_lip_y3):(lip_y + d_lip_y3), (nose_x - d_lip_x1):nose_x]
    lip_right = Pmax[(lip_y - d_lip_y3):(lip_y + d_lip_y3), nose_x:(nose_x + d_lip_x1)]

    lip_left_x = find_peak_start(numpy.sum(lip_left, axis=0)) + (nose_x - d_lip_x1)
    lip_left_y = numpy.nanargmax(Pmax[(lip_y - d_lip_y3):(lip_y + d_lip_y3), lip_left_x]) + (lip_y - d_lip_y3)

    lip_right_x = find_peak_stop(numpy.sum(lip_right, axis=0)) + nose_x
    lip_right_y = numpy.nanargmax(Pmax[(lip_y - d_lip_y3):(lip_y + d_lip_y3), lip_right_x]) + (lip_y - d_lip_y3)

    face.key_points['lip'] = (nose_x, lip_y)
    face.key_points['lip_left'] = (lip_left_x, lip_left_y)
    face.key_points['lip_right'] = (lip_right_x, lip_right_y)

    #
    # Chin
    #
    chin = numpy.gradient(signal.bspline(face.Z[(lip_y + d_chin_y1):, nose_x], 25))
    chin_x, chin_y = nose_x, numpy.nanargmin(chin) + (lip_y + d_chin_y1)

    face.key_points["chin"] = (chin_x, chin_y)

    # 
    # Eyes
    #
    eye_left = Pmax[d_eye_y:nose_left_y - d_eye_y, nose_left_x - d_eye_x:nose_left_x + d_eye_x]
    eye_right = Pmax[d_eye_y:nose_right_y - d_eye_y, nose_right_x - d_eye_x:nose_right_x + d_eye_x]

    eye_left_x, eye_left_y = max_xy(eye_left, nose_left_x - d_eye_x, d_eye_y)
    eye_right_x, eye_right_y = max_xy(eye_right, nose_right_x - d_eye_x, d_eye_y)

    face.key_points["eye_left"] = (eye_left_x, eye_left_y)
    face.key_points["eye_right"] = (eye_right_x, eye_right_y)

    #
    # Nose face border
    #
    nose_line = numpy.gradient(face.Z[nose_y, :])
    border_nose_left_x, border_nose_left_y = numpy.nanargmax(nose_line[:lip_left_x - 10]), nose_y
    border_nose_right_x, border_nose_right_y = numpy.nanargmin(nose_line[lip_right_x + 10:]) + lip_right_x + 10, nose_y

    face.key_points["border_nose_left"] = (border_nose_left_x, border_nose_left_y)
    face.key_points["border_nose_right"] = (border_nose_right_x, border_nose_right_y)

    #
    # Lip face border
    #
    lip_line = numpy.gradient(face.Z[lip_y, :])
    border_lip_left_x, border_lip_left_y = numpy.nanargmax(lip_line[:lip_left_x - 10]), lip_y
    border_lip_right_x, border_lip_right_y = numpy.nanargmin(lip_line[lip_right_x + 10:]) + lip_right_x + 10, lip_y

    face.key_points["border_lip_left"] = (border_lip_left_x, border_lip_left_y)
    face.key_points["border_lip_right"] = (border_lip_right_x, border_lip_right_y)

    #
    # Forehead border
    #
    forehead_line = numpy.gradient(face.Z[nose_y - (chin_y - nose_y), :])
    border_forehead_left_x, border_forehead_left_y = numpy.nanargmax(forehead_line[:lip_left_x - 10]), nose_y - (chin_y - nose_y)
    border_forehead_right_x, border_forehead_right_y = numpy.nanargmin(forehead_line[lip_right_x + 10:]) + lip_right_x + 10, nose_y - (chin_y - nose_y)

    face.key_points["border_forehead_left"] = (border_forehead_left_x, border_forehead_left_y)
    face.key_points["border_forehead_right"] = (border_forehead_right_x, border_forehead_right_y)