Exemplo n.º 1
0
def delta(S, element=3):
    # inputs:
    #   S :  n x m x 3 or 4) Stokes
    #   element :
    #       as int or float: side length of square window (element x element) for averaging
    #       as array or list: 2-D array describing (weighted) averaging window
    #           eg. 0 1 0
    #               1 1 1
    #               0 1 0

    # outputs:
    #   n x m delta metric for array
    element_error = 'element must be an int or a 2D array'
    if type(element) in [int, float]:
        neighborhood = np.ones((element, element))
    elif not type(
            element
    ) is np.ndarray:  # if it is not an int or float it must be array
        raise ValueError(element_error)
    elif not len(element.shape) == 2:  # if it's an array must be 2D
        raise ValueError(element_error)
    else:
        neighborhood = element

    # gives the number of cells that will be averaged for each cell. besides the edges, this will be element**2
    N = conv(np.ones((S.shape[0], S.shape[1])), neighborhood, 'same')
    P = StD(S)  #DoP
    ca = S[:, :, 1] / P  # cos 2 AoLP
    sa = S[:, :, 2] / P  # sin 2 AoLP
    cam = conv(ca, neighborhood, 'same') / N  # averaged cosine
    sam = conv(sa, neighborhood, 'same') / N  # averaged sine

    return np.sqrt(1 - (cam**2 + sam**2))  # delta metric, see Tyo et al 2016
Exemplo n.º 2
0
def sobelFilter(image):
    '''
    Description:
    This function will execute a Sobel Filter on the given image to find its horizontal and vertical gradients.
    The default filter is set to 3x3.
    Input:
        -image (np.array)
        
    Output:
        - grad_x (np.array)
        - grad_y (np.array)
    '''
    
    # creating sobel kernels
    fx = np.array([1, 2, 1,
                   0, 0, 0,
                   -1,-2,-1])
    fy = np.array([-1,0,1,
                   -2,0,2,
                   -1,0,1])
    
    fx = fx.reshape(3,3)
    fy = fy.reshape(3,3)
    
    grad_x = conv(image,fx)
    grad_y = conv(image,fy)
    
    return grad_x,grad_y
Exemplo n.º 3
0
def yx_derivatives(im, sigma=4):    
    
    # Create the gauss kernel for blurring the input image
    # It will be convolved with the image
    # wsize should be an odd number
    wsize = 5
    gausskernel = gaussFilter(sigma, window = wsize)

    # fx is the filter for vertical gradient
    # fy is the filter for horizontal gradient
    # Please not the vertical direction is positive X
    fx = createFilter([0,  1, 0,
                       0,  0, 0,
                       0, -1, 0])
    fy = createFilter([ 0, 0, 0,
                       -1, 0, 1,
                        0, 0, 0])

    imblurred = conv(im, gausskernel, 'same')
    # print "imout:", imout.shape
    gradx = conv(imblurred, fx, 'same')
    grady = conv(imblurred, fy, 'same')

    # Create the output array 
    # (3d array of y, x, (y,x pair of immediate derivative))
    points_shape = im.shape
    points_shape = (points_shape[0], points_shape[1], 2)
    points = np.empty(points_shape)
    
    points[:,:,0] = grady
    points[:,:,1] = gradx
    
    return points
Exemplo n.º 4
0
def delta_aop(aop, element=3):
    # inputs:
    #   aop: n x m array of angle of polarization in radians with a range of pi
    #   element :
    #       as int or float: side length of square window (element x element) for averaging
    #       as array or list: 2-D array describing (weighted) averaging window
    #           eg. 0 1 0
    #               1 1 1
    #               0 1 0

    # outputs:
    #   n x m delta metric for array

    # gives the number of cells that will be averaged for each cell. besides the edges, this will be element*
    if type(element) in [int, float]:
        neighborhood = np.ones((element, element))
    elif not type(element) in [np.ndarray, list]:
        neighborhood = np.ones((3, 3))
    else:
        neighborhood = element

    N = conv(np.ones((aop.shape[0], aop.shape[1])), neighborhood, 'same')
    ca = np.cos(2 * aop)
    sa = np.sin(2 * aop)  # sin AoLP
    cam = conv(ca, neighborhood, 'same') / N  # averaged cosine
    sam = conv(sa, neighborhood, 'same') / N  # averaged sine

    return np.sqrt(1 - (cam**2 + sam**2))  # delta metric, see Tyo et al 2016
def ModifiedRicianPlusConstant(x, c, a, sig, n_angles=360, return_derivs=False):
    assert np.isclose(x[1]-x[0], x[-1]-x[-2])  # check for uniform spacing
    assert x[1] - x[0] > 0.  #x must be increasing
    if not return_derivs:
        mr = ModifiedRician(x, a, sig, n_angles=n_angles, return_derivs=False)
    else:
        (mr, dmrda, dmrds) = ModifiedRician(x, a, sig, n_angles=n_angles, return_derivs=True)
        
    space = x[1] - x[0]
    ss = ( space/2.35 )  # sigma of normal  -
    cen = (x[0] + x[-1])/2. + c*c
    #indic = np.where(x - cen < 0.)[0]  # indicator function
    f = space*np.exp( (- 0.5/ss**2)*(x-cen)**2 )/(2*np.pi*ss)  # this integrates to unity with good sampling
    sf = np.sum(f)
    if sf > 1.e-4:
        f /= sf
    g = conv(mr, f, mode='same', method='fft')
    if not return_derivs:
        return(g)
    else:
        dmrda = conv(dmrda, f, mode='same', method='fft')
        dmrds = conv(dmrds, f, mode='same', method='fft')
        dfdcen = f*(x-cen)/ss**2
        dmrdcen = conv(mr, dfdcen, mode='same', method='fft')
        return(mr, np.array([dmrdcen, dmrda, dmrds]))
Exemplo n.º 6
0
def harriscorner(img, thresh=0.2, sigma=1, window=3):
    gaussion = gaussFilter(sigma, window)
    gradkernel = np.asarray([-1, 0, 1], dtype='float32')
    dx = conv1d(img, gradkernel, 1, 3)
    dy = np.transpose(conv1d(np.transpose(img), gradkernel, 1, 3))
    dx2 = dx * dx
    dy2 = dy * dy
    dxy = dx * dy

    dx2 = conv(dx2, gaussion, mode='same')
    dy2 = conv(dy2, gaussion, mode='same')
    dxy = conv(dxy, gaussion, mode='same')

    hessian = np.zeros((img.shape[0], img.shape[1], 2, 2), dtype='float32')
    hessian[:, :, 0, 0] = dx2
    hessian[:, :, 0, 1] = dxy
    hessian[:, :, 1, 0] = dxy
    hessian[:, :, 1, 1] = dy2
    cornerness = np.linalg.det(hessian) - 0.04 * np.trace(
        hessian, axis1=hessian.ndim - 2, axis2=hessian.ndim - 1)
    #     eaignvalue = np.linalg.eigvals(hessian)
    #
    mask = np.zeros((img.shape[0], img.shape[1])) + 255
    min = cornerness.min()
    max = cornerness.max()
    cornerness = (cornerness - min) / (max - min)
    mask[cornerness <= thresh] = 0
    return mask
Exemplo n.º 7
0
def convolve(img, psf, type='default', extend=True, mode='same', extend_margin=100, **kargs):
    """
    Compute the convolution of two 2D signals: img and psf
    type:
        define the convolution type
    """
    if extend is int:
        extend_margin = extend
        
    if extend:
        img = img_extend(img, extend_margin)
        
    if type is 'fft':
        from scipy.signal import fftconvolve as conv
        I = conv(img, psf, mode)
    elif type is 'default':
        from scipy.signal import convolve as conv
        I = conv(img, psf, mode)
    elif type is 'accurate':
        from scipy.signal import convolve2d as convolve
        I = conv(img, psf, mode)
    elif type is 'fft2':
        I = np.fft.fftshift((np.fft.irfft2(np.fft.rfft2(img) * np.fft.rfft2(psf))))
    
    if extend:
        I = I[extend_margin:-extend_margin, extend_margin:-extend_margin]
        
    return I
Exemplo n.º 8
0
 def x_in(self, vis):
     if self.style == 'reichert':
         return [(conv(np.abs(vis), filt,
                       mode='valid'), conv(vis, filt, mode='valid'))
                 for filt in self.filters]
     else:
         return np.array(
             [conv(vis, filt, mode='valid') for filt in self.filters])
Exemplo n.º 9
0
    def ConvFresnel2D(self, g, x, diam_out, z, index_of_refraction=1,
                      set_dx=True, return_derivs=False):
        if g.shape[0] != x.shape[0]:
            raise Exception("ConvFresnel2D: input field and grid must have same sampling.")
        if g.ndim != 2:
            raise Exception("ConvFresnel2D: input field array must be 2D.")
        if g.shape[0] != g.shape[1]:
            raise Exception("ConvFresnel2D: input field array must be square.")

        lam = self.params['wavelength']/index_of_refraction
        dx, diam = self.GetDxAndDiam(x)
        dx_new = dx  # this will probably change
        dPhiTol_deg = self.params['max_chirp_step_deg']
        dx_chirp = (dPhiTol_deg/180)*lam*z/(diam + diam_out)  # sampling criterion for chirp (factors of pi cancel)
        if isinstance(set_dx, bool):  # this step is needed so that 1 and 1.0 are not treated as True
            if set_dx == False:  pass
            else:  # use chirp sampling criterion
                if dx < dx_chirp:
                    dx_new = dx_chirp
        else:  # take dx_new to be value of set_dx
            if not isinstance(set_dx, float):
                raise Exception("ConvFresnel2D: set_dx must be a bool or a float.")
            if set_dx <= 0:
                raise Exception("ConvFresnel2D: numerical value of set_dx must be > 0.")
            dx_new = set_dx

        if not np.isclose(dx, dx_new):  # interpolate g onto a grid with spacing of approx dx_new
            [g, x] = self.ResampleField2D(g, x, dx_new, kind=self.params['interp_style'])
            dx = x[1] - x[0]

        # make the kernel grid (s) match x as closely as possible
        ns = int(np.round(diam + diam_out)/dx)  # number of points on extended kernel
        s = np.linspace(-diam/2 - diam_out/2 + dx/2, diam/2 + diam_out/2 - dx/2, ns) # spatial grid of extended kernel
        ind = np.where(np.abs(s) < diam_out/2)[0] # get the part of s within the 1D output grid
        [sx, sy] = np.meshgrid(s, s, indexing='xy')
        i_out = np.where(np.sqrt(sx*sx + sy*sy) > diam_out/2)

        #Calculate Fresnel convoltion kernel, (Goodman 4-16)
        #  Note: the factor p = 1/(lam*z) is applied later
        #  Also note: the factor -1j*np.exp(2j*np.pi*z/lam) causes unwanted oscillations with z
        kern = np.exp(1j*np.pi*(sx*sx + sy*sy)/(lam*z))  # Fresnel kernel
        if dx > dx_chirp:  # Where does |s| exceed the max step for this dx?
            s_max = lam*z*self.params['max_chirp_step_deg']/(360*dx)
            null_ind = np.where(np.sqrt(sx*sx + sy*sy) > s_max)
            kern[null_ind[0], null_ind[1]] = 0
        h = conv(kern, g, mode='same', method='fft')  # h is on the s spatial grid
        h[i_out[0], i_out[1]] = 0.  # zero the field outside the desired region
        h = h[ind[0]:ind[-1] + 1, ind[0]:ind[-1] + 1]
        p = 1/(lam*z)
        if not return_derivs:
            return([p*h, s[ind]])
        #dpdz = (-1j/(lam*z*z) + 2*np.pi/(lam*lam*z))*np.exp(2j*np.pi*z/lam)  # includes unwanted piston term
        dpdz = -1/(lam*z*z)
        dkerndz = -1j*np.pi*(sx*sx + sy*sy)*kern/(lam*z*z)
        dhdz = conv(dkerndz, g, mode='same', method='fft')
        dhdz[i_out[0], i_out[1]] = 0.
        dhdz = dhdz[ind[0]:ind[-1] + 1, ind[0]:ind[-1] + 1]
        return([p*h, dpdz*h + p*dhdz, s[ind]])
Exemplo n.º 10
0
    def cnnbp(self, y):
        n = len(self.layers)
        self.e = self.o - y
        self.L = 0.5 * np.sum(self.e**2) / self.e.shape[1]
        self.od = self.e * (self.o * (1 - self.o))

        self.fvd = np.dot(self.ffW.transpose(), self.od)
        if self.layers[n - 1].types == 'c':
            self.fvd = self.fvd * (self.fv * (1 - self.fv))
        sa = self.layers[n - 1].a[0].shape
        fvnum = sa[1] * sa[2]
        for j in range(len(self.layers[n - 1].a)):
            if self.layers[n - 1].d == None:
                self.layers[n - 1].d = {}
            self.layers[n - 1].d.setdefault(j)
            self.layers[n - 1].d[j] = self.fvd[(j * fvnum):(
                (j + 1) * fvnum), :].transpose().reshape(sa[0], sa[1], sa[2])

        for l in range(n - 2, -1, -1):
            if self.layers[l].types == 'c':
                for j in range(len(self.layers[l].a)):
                    if self.layers[l].d == None:
                        self.layers[l].d = {}
                    self.layers[l].d.setdefault(j)
                    self.layers[l].d[j]=self.layers[l].a[j]*(1-self.layers[l].a[j])*\
                         np.kron(self.layers[l+1].d[j],np.ones(( self.layers[l+1].scale,self.layers[l+1].scale))/(self.layers[l+1].scale**2))

            elif self.layers[l].types == 's':
                for j in range(len(self.layers[l].a)):
                    if self.layers[l].d == None:
                        self.layers[l].d = {}
                    self.layers[l].d.setdefault(j)
                    z = np.zeros(self.layers[l].a[0].shape)
                    for i in range(len(self.layers[l + 1].a)):
                        rotated = np.array(
                            [rot90(self.layers[l + 1].k[j][i], 2)])
                        z = z + conv(self.layers[l + 1].d[i], rotated, 'full')
                    self.layers[l].d[j] = z

        for l in range(1, n):
            m = self.layers[l].d[0].shape[0]
            if self.layers[l].types == 'c':
                for j in range(len(self.layers[l].a)):
                    for i in range(len(self.layers[l - 1].a)):
                        #self.layers[l].dk[i][j]=rot90(conv(self.layers[l-1].a[i],rot90(self.layers[l].d[j],2),'valid'),2)
                        self.layers[l].dk[i][j] = self.layers[l].dk[i][j] * 0
                        for t in range(self.layers[l].d[0].shape[0]):
                            self.layers[l].dk[i][j] += rot90(
                                conv(self.layers[l - 1].a[i][t],
                                     rot90(self.layers[l].d[j][t], 2),
                                     'valid'), 2)

                        self.layers[l].dk[i][j] = self.layers[l].dk[i][j] / m
                    self.layers[l].db[j] = np.sum(self.layers[l].d[j]) / m
        self.dffW = np.dot(self.od, self.fv.transpose()) / self.od.shape[1]
        self.dffb = np.mean(self.od, 1).reshape(self.ffb.shape)
Exemplo n.º 11
0
def gaussianfilter(img, sigma):
    kernel = gauss(sigma)[0]
    kernel = (kernel / kernel.sum())

    # Applying the gaussian kernel over rows and columns separatelly
    smooth_img = np.apply_along_axis(lambda x: conv(x, kernel, "same"), 0, img)
    smooth_img = np.apply_along_axis(lambda x: conv(x, kernel, "same"), 1,
                                     smooth_img)

    return smooth_img
Exemplo n.º 12
0
    def update_next(self):

        # alive pixels counts
        convoluted1 = conv(self.curr_board_array, self.__kernel, mode='same')
        mask1 = np.logical_and(np.logical_and(convoluted1>=2, convoluted1<=3), self.curr_board_array==1)

        # alive pixels do not count
        convoluted2 = conv(self.curr_board_array, self.__kernel, mode='same')
        mask2 = convoluted2==3

        self.__next_board_array = (np.logical_or(mask1, mask2)*1).astype(np.uint8)
Exemplo n.º 13
0
Arquivo: CNN.py Projeto: Agnesfen/dml
	def cnnbp(self,y):
		n=len(self.layers)
		self.e=self.o-y
		self.L=0.5*np.sum(self.e**2)/self.e.shape[1]
		self.od=self.e*(self.o*(1-self.o))
		
		self.fvd=np.dot(self.ffW.transpose(),self.od)
		if self.layers[n-1].types=='c':
			self.fvd=self.fvd*(self.fv*(1-self.fv))
		sa=self.layers[n-1].a[0].shape
		fvnum=sa[1]*sa[2]
		for j in range(len(self.layers[n-1].a)):
			if self.layers[n-1].d==None:
				self.layers[n-1].d={}
			self.layers[n-1].d.setdefault(j)
			self.layers[n-1].d[j]=self.fvd[(j*fvnum):((j+1)*fvnum),:].transpose().reshape(sa[0],sa[1],sa[2])

		for l in range(n-2,-1,-1):
			if self.layers[l].types=='c':
				for j in range(len(self.layers[l].a)):
					if self.layers[l].d==None:
						self.layers[l].d={}
					self.layers[l].d.setdefault(j)
					self.layers[l].d[j]=self.layers[l].a[j]*(1-self.layers[l].a[j])*\
										np.kron(self.layers[l+1].d[j],np.ones((	self.layers[l+1].scale,self.layers[l+1].scale))/(self.layers[l+1].scale**2))
					
					
			elif self.layers[l].types=='s':
				for j in range(len(self.layers[l].a)):
					if self.layers[l].d==None:
						self.layers[l].d={}
					self.layers[l].d.setdefault(j)
					z=np.zeros(self.layers[l].a[0].shape)
					for i in range(len(self.layers[l+1].a)):
						rotated=np.array([rot90(self.layers[l+1].k[j][i],2)])
						z=z+conv(self.layers[l+1].d[i],rotated,'full')
					self.layers[l].d[j]=z

		for l in range(1,n):
			m=self.layers[l].d[0].shape[0]
			if self.layers[l].types=='c':
				for j in range(len(self.layers[l].a)):
					for i in range(len(self.layers[l-1].a)):
						#self.layers[l].dk[i][j]=rot90(conv(self.layers[l-1].a[i],rot90(self.layers[l].d[j],2),'valid'),2)
						self.layers[l].dk[i][j]=self.layers[l].dk[i][j]*0
						for t in range(self.layers[l].d[0].shape[0]):
							self.layers[l].dk[i][j]+=rot90(conv(self.layers[l-1].a[i][t],rot90(self.layers[l].d[j][t],2),'valid'),2)
						
						self.layers[l].dk[i][j]=self.layers[l].dk[i][j]/m
					self.layers[l].db[j]=np.sum(self.layers[l].d[j])/m
		self.dffW=np.dot(self.od,self.fv.transpose())/self.od.shape[1]
		self.dffb = np.mean(self.od,1).reshape(self.ffb.shape);
Exemplo n.º 14
0
def get_theta(mono_img):
    imin = mono_img.copy() * 255.0
    wsize = 5
    gausskernel = can.gaussFilter(4, window = wsize)
    
    fx = can.createFilter([0,  1, 0,
                            0,  0, 0,
                            0, -1, 0])
    fy = can.createFilter([ 0, 0, 0,
                            1, 0, -1,
                            0, 0, 0])

    imout = conv(imin, gausskernel, 'valid')
    gradxx = conv(imout, fx, 'valid')
    gradyy = conv(imout, fy, 'valid')

    gradx = np.zeros(mono_img.shape)
    grady = np.zeros(mono_img.shape)
    padx = (imin.shape[0] - gradxx.shape[0]) / 2.0
    pady = (imin.shape[1] - gradxx.shape[1]) / 2.0
    gradx[padx:-padx, pady:-pady] = gradxx
    grady[padx:-padx, pady:-pady] = gradyy
    
    # Net gradient is the square root of sum of square of the horizontal
    # and vertical gradients

    grad = hypot(gradx, grady)
    theta = arctan2(grady, gradx)
    theta = 180 + (180 / pi) * theta
    # Only significant magnitudes are considered. All others are removed
    xx, yy = where(grad < 5)
    theta[xx, yy] = 0
    
    # The angles are quantized. This is the first step in non-maximum
    # supression. Since, any pixel will have only 4 approach directions.
    x0,y0 = where(((theta<22.5)+(theta>157.5)*(theta<202.5)
                   +(theta>337.5)) == True)
    x45,y45 = where( ((theta>22.5)*(theta<67.5)
                      +(theta>202.5)*(theta<247.5)) == True)
    x90,y90 = where( ((theta>67.5)*(theta<112.5)
                      +(theta>247.5)*(theta<292.5)) == True)
    x135,y135 = where( ((theta>112.5)*(theta<157.5)
                        +(theta>292.5)*(theta<337.5)) == True)

    theta = theta
    theta[x0,y0] = 0
    theta[x45,y45] = 45
    theta[x90,y90] = 90
    theta[x135,y135] = 135
    
    return theta
Exemplo n.º 15
0
    def ConvFresnel1D(self, g, x, diam_out, z, index_of_refraction=1,
                      set_dx=True, return_derivs=False):
        if g.shape != x.shape:
            raise Exception("Input field and grid must have same dimensions.")
        lam = self.params['wavelength']/index_of_refraction
        dx, diam = self.GetDxAndDiam(x)
        dx_new = dx  # this will probably change
        dPhiTol_deg = self.params['max_chirp_step_deg']
        dx_chirp = (dPhiTol_deg/180)*lam*z/(diam + diam_out)  # sampling criterion for chirp (factors of pi cancel)
        if isinstance(set_dx, bool):  # this step is needed so that 1 and 1.0 are not treated as True
            if set_dx == False: pass
            else:  # use chirp sampling criterion
                if dx_chirp < dx:
                    dx_new = dx_chirp
        else:  # take dx_new to be value of set_dx
            if not isinstance(set_dx, float):
                raise Exception("ConvFresnel1D: set_dx must be a bool or a float.")
            if set_dx <= 0:
                raise Exception("ConvFresnel1D: numerical value of set_dx must be > 0.")
            dx_new = set_dx

        if not np.isclose(dx, dx_new):  # interpolate g onto a grid with spacing of (approx) dx_new
            [g, x] = self.ResampleField1D(g, x, dx_new)
            dx = x[1] - x[0]

        # make the kernel grid (s) match x as closely as possible
        ns = int(np.round(diam + diam_out)/dx)  # number of points on extended kernel
        s = np.linspace(-diam/2 - diam_out/2 + dx/2, diam/2 + diam_out/2 - dx/2, ns) # spatial grid of extended kernel
        indices_out = np.where(np.abs(s) < diam_out/2)[0] # get the part of s within the output grid

        #Calculate Fresnel convoltion kernel, (Goodman 4-16)
        #  Note: the factor p = 1/(lam*z) is applied later
        #  Also note: the factor -1j*np.exp(2j*np.pi*z/lam) causes unwanted oscillations with z
        kern = np.exp(1j*np.pi*s*s/(lam*z))  # Fresnel kernel
        if dx > dx_chirp:  # Where does |s| exceed the max step for this dx?
            s_max = lam*z*self.params['max_chirp_step_deg']/(360*dx)
            null_ind = np.where(np.abs(s) > s_max)[0]
            kern[null_ind] = 0
        h = conv(kern, g, mode='same', method='fft')  # h is on the s spatial grid

        p = 1/(lam*z)
        if not return_derivs:
            return([p*h[indices_out], s[indices_out]])
        #dpdz = (-1j/(lam*z*z) + 2*np.pi/(lam*lam*z))*np.exp(2j*np.pi*z/lam)  # includes unwanted oscillations
        dpdz = -1/(lam*z*z)
        dkerndz = -1j*np.pi*s*s*kern/(lam*z*z)
        dhdz = conv(dkerndz, g, mode='same', method='fft')
        s = s[indices_out]
        h = h[indices_out]
        dhdz = dhdz[indices_out]
        return([p*h, dpdz*h + p*dhdz, s])
Exemplo n.º 16
0
	def _centripetal_autowave_update(self):
		'''Curvature flow model of W:
		4) W{A} = A' = [[F_2a'{M{A'}} + F_1a'{A'}] < 0.5]
		5) A' = A + [F_1a{M{A}} > 0.5]
		6) [F_1a{X}]_ij = X_ij if A_ij == 0 else 0
		7) [F_2a{X}]_ij = X_ij if A_ij == 1 else 0
		8) [X > d]_ij = 1 if X_ij >= d else 0
		9) [X < d]_ij = 1 if X_ij <= d else 0
		'''
		M_Y = conv(self.Y, self.W, mode='same')
		Y_p = self.Y + (np.where(self.Y==0, M_Y, 0) >= 0.5)
		M_Yp = conv(Y_p, self.W, mode='same')
		W = Y_p + ((np.where(Y_p==1, M_Yp, 0) + np.where(Y_p==0, Y_p, 0)) <= 0.5)
		return W
Exemplo n.º 17
0
    def cnnff(self, x):
        #print x
        self.layers[0].a = {}
        self.layers[0].a.setdefault(0)
        self.layers[0].a[0] = x.copy()
        inputmap = 1
        n = len(self.layers)

        for l in range(1, n):
            if self.layers[l].types == 's':
                for j in range(inputmap):

                    temp = np.ones(
                        (self.layers[l].scale,
                         self.layers[l].scale)) / (self.layers[l].scale**2)
                    z = conv(self.layers[l - 1].a[j], np.array([temp]),
                             'valid')
                    z = np.array(
                        z)[:, ::self.layers[l].scale, ::self.layers[l].scale]

                    if self.layers[l].a == None:
                        self.layers[l].a = {}
                    self.layers[l].a.setdefault(j)
                    self.layers[l].a[j] = z

            if self.layers[l].types == 'c':
                if self.layers[l].a == None:
                    self.layers[l].a = {}
                for j in range(self.layers[l].out):  #for each outmaps
                    z = np.zeros(self.layers[l - 1].a[0].shape - np.array([
                        0, self.layers[l].kernelsize -
                        1, self.layers[l].kernelsize - 1
                    ]))
                    for i in range(inputmap):  #cumulate from inputmaps
                        z += conv(self.layers[l - 1].a[i],
                                  np.array([self.layers[l].k[i][j]]), 'valid')
                    self.layers[l].a.setdefault(j)
                    self.layers[l].a[j] = sigmoid(z + self.layers[l].b[j])
                inputmap = self.layers[l].out

        self.fv = None
        for j in range(len(self.layers[n - 1].a)):
            sa = self.layers[n - 1].a[j].shape
            p = self.layers[n - 1].a[j].reshape(sa[0], sa[1] * sa[2]).copy()
            if (self.fv == None):
                self.fv = p
            else:
                self.fv = np.concatenate((self.fv, p), axis=1)
        self.fv = self.fv.transpose()
        self.o = sigmoid(np.dot(self.ffW, self.fv) + self.ffb)
Exemplo n.º 18
0
def circstd(aop, element=3):
    if type(element) in [int, float]:
        neighborhood = np.ones((element, element))
    elif not type(element) in [np.ndarray, list]:
        neighborhood = np.ones((3, 3))
    else:
        neighborhood = element

    N = conv(np.ones((aop.shape[0], aop.shape[1])), neighborhood, 'same')
    ca = np.cos(2 * aop)
    sa = np.sin(2 * aop)  # sin AoLP
    cam = conv(ca, neighborhood, 'same') / N  # averaged cosine
    sam = conv(sa, neighborhood, 'same') / N  # averaged sine
    R = np.hypot(sam, cam)
    return np.sqrt(-2 * np.log(R)) / 2.0
Exemplo n.º 19
0
def lucas_kanade(images, window_size=5, tau=1e-2):
    """
    Inputs:
    images: list of 2 images at time t and t+1
    window_size: patch size of (window_size x window_size) around each pixel
    tau: threshold for smallest eigen value to ensure "cornerness" or validity of flow

    Output:
    (u,v, valid) = a tuple of u and v components of the flow field at each point and whether the point is valid (0 or 1)
    """

    img1 = images[0]
    img2 = images[1]

    kernel_x = np.array([[-1., 1.], [-1., 1.]])
    kernel_y = np.array([[-1., -1.], [1., 1.]])
    kernel_t = np.array([[1., 1.], [1., 1.]])  # *.25

    # window_size is odd, all the pixels with offset in between [-w, w] are inside the window
    w = int(window_size / 2)

    # ------Implement Lucas Kanade--------

    # for each point, calculate I_x, I_y, I_t
    mode = 'same'
    fx = conv(img1, kernel_x, boundary='symm', mode=mode)
    fy = conv(img1, kernel_y, boundary='symm', mode=mode)
    ft = conv(img2, kernel_t, boundary='symm', mode=mode) + \
        conv(img1, -kernel_t, boundary='symm', mode=mode)
    u = np.zeros(img1.shape)
    v = np.zeros(img1.shape)
    valid = np.zeros(img1.shape)
    # within window window_size * window_size
    for i in range(w, img1.shape[0] - w):
        for j in range(w, img1.shape[1] - w):
            Ix = fx[i - w:i + w + 1, j - w:j + w + 1].flatten()
            Iy = fy[i - w:i + w + 1, j - w:j + w + 1].flatten()
            It = ft[i - w:i + w + 1, j - w:j + w + 1].flatten()
            b = np.reshape(It, (It.shape[0], 1))  # get b here
            A = np.vstack((Ix, Iy)).T  # get A here
            # if the smallest eigenvalue of A'A is larger than the threshold τ:
            if np.min(abs(np.linalg.eigvals(np.matmul(A.T, A)))) >= tau:
                nu = np.matmul(np.linalg.pinv(A), b)  # get velocity here
                u[i, j] = nu[0]
                v[i, j] = nu[1]
                valid[i, j] = 1

    return (u, v, valid)
def voigt(x,c1,w1,c2,w2):
	""" Voigt function: convolution of Lorentzian and Gaussian.
		Convolution implemented with the FFT convolve function in scipy.
		NOT NORMALISED """
	
	### Create larger array so convolution doesn't screw up at the edges of the arrays
	# this assumes nicely behaved x-array...
	# i.e. x[0] == x.min() and x[-1] == x.max(), monotonically increasing
	dx = (x[-1]-x[0])/len(x)
	xp_min = x[0] - len(x)/3 * dx
	xp_max = x[-1] + len(x)/3 * dx
	xp = linspace(xp_min,xp_max,3*len(x))
	
	L = lorentzian(xp,c1,w1)
	G = gaussian(xp,c2,w2)
	
	#convolve
	V = conv(L,G,mode='same')
	
	#normalise to unity height !!! delete me later !!!
	V /= V.max()
	
	#create interpolation function to convert back to original array size
	fn_out = interp(xp,V)
	
	return fn_out(x)
Exemplo n.º 21
0
def gaussFilter(image,sigma,window):
    '''
    Description:
        This function will execute a Gaussian Blurring Filter on the given image. The sigma and window size
        are set to default sigma = 2 and window = 5x5. 
    
    Input:
        -image (np.array)
        -sigma (int)
        -window size (int)
    
    Output:
        - blurred_im (np.array)
    '''
    # creating an empty kernel
    kernel = np.zeros((window,window))
    # centre of the kernel
    c0 = window // 2 
    
    # computing kernel using Gaussian function
    for x in range(window):
            for y in range(window):
                r = np.hypot((x-c0),(y-c0)) #calculating magnitude of the centre pixel. x^2 + y^2
                val = (1.0/2*np.math.pi*sigma)*np.math.exp(-(r*r)/(2*sigma*sigma)) # computes gaussian filter
                kernel[x,y] = val
    
    kernel = kernel / kernel.sum()

    # executes convolution
    blurred_im = conv(np.asarray(image),kernel)[1:-1,1:-1]

    
    return blurred_im
def voigt(x, c1, w1, c2, w2):
    """ Voigt function: convolution of Lorentzian and Gaussian.
		Convolution implemented with the FFT convolve function in scipy.
		NOT NORMALISED """

    ### Create larger array so convolution doesn't screw up at the edges of the arrays
    # this assumes nicely behaved x-array...
    # i.e. x[0] == x.min() and x[-1] == x.max(), monotonically increasing
    dx = (x[-1] - x[0]) / len(x)
    xp_min = x[0] - len(x) / 3 * dx
    xp_max = x[-1] + len(x) / 3 * dx
    xp = linspace(xp_min, xp_max, 3 * len(x))

    L = lorentzian(xp, c1, w1)
    G = gaussian(xp, c2, w2)

    #convolve
    V = conv(L, G, mode='same')

    #normalise to unity height !!! delete me later !!!
    V /= V.max()

    #create interpolation function to convert back to original array size
    fn_out = interp(xp, V)

    return fn_out(x)
Exemplo n.º 23
0
    def windolf_sampling(self, params, layer):
	a = np.abs(params)
	alpha = np.angle(params)

	if layer=='visible':
	    rates = np.abs(self.clamp)
	    phases = vm(alpha, a*rates / self.sigma_sq)
	    return rates*np.exp(1j*phases)
	else:
	    bessels = bessel(a - self.biases)/ self.sigma_sq
	    custom_kernel = np.ones((self.pool_size, self.pool_size))
	    sum_bessels = conv(bessels, custom_kernel, mode='valid')
	    # Downsample
	    sum_bessels = sum_bessels[0::self.pool_stride, 0::self.pool_stride]
	    
	    bessel_sftmx_denom = 1.0 + sum_bessels
	    upsampled_denom = bessel_sftmx_denom.repeat(self.pool_stride, axis=0).repeat(self.pool_stride, axis=1)    
	    hid_cat_P = bessels / upsampled_denom
	    pool_P = 1.0 - 1.0 / bessel_sftmx_denom
		
	    hid_rates, pool_rates = self._dbn_maxpool_sample_helper(hid_cat_P, pool_P)
	    hid_phases = vm(alpha, a*hid_rates / self.sigma_sq)
	    hid_samples = hid_rates*np.exp(1j*hid_phases)
	    pool_phases = np.sum(imx.view_as_blocks(hid_phases, (self.pool_size, self.pool_size)), axis=(2,3))
	    pool_samples = pool_rates*np.exp(1j*pool_phases)
	    return hid_samples, pool_samples
Exemplo n.º 24
0
def fft_submatrix_max(A):
    """
    Searches for the rectangular subarray of A with maximum sum
    Uses FFT-based convolution operations
    """
    M, N = A.shape
    this_location, max_value = ((0, 0), (0, 0)), 0
    t0 = time.time()
    for m, n in itertools.product(xrange(2, M), xrange(2, N)):
        convolved = conv(A, np.ones((m, n)), mode='same')
        row, col = np.unravel_index(convolved.argmax(), convolved.shape)
        # index offsets for odd dimension length:
        if m % 2 == 1:
            m_off = 1
        else:
            m_off = 0
        if n % 2 == 1:
            n_off = 1
        else:
            n_off = 0

        this_location = (
            slice(row - m / 2, row + m / 2 + m_off), slice(col - n / 2, col + n / 2 + n_off))
        value = A[this_location].sum()

        if value >= max_value:
            max_value = value
            location = this_location
    location, max_value = local_search(A, location)
    t = time.time() - t0
    return location, max_value, t
def gradientCalculator(im, sigma):
    '''
    Helper function that calculates the array of gradient directions for
    an input image. This will be used in Part 5 to make the paint strokes
    orthogonal to edge directions.
    '''
    imin = im.copy() * 255.0
    # Create the gauss kernel for blurring the input image
    # It will be convolved with the image
    # wsize should be an odd number
    wsize = 5
    gausskernel = gaussFilter(sigma, window = wsize)
    # fx is the filter for vertical gradient
    # fy is the filter for horizontal gradient
    # Please note the vertical direction is positive X

    fx = createFilter([0,  1, 0,
                       0,  0, 0,
                       0, -1, 0])
    fy = createFilter([ 0, 0, 0,
                       -1, 0, 1,
                        0, 0, 0])

    imout = conv(imin, gausskernel, 'valid')
    # print "imout:", imout.shape
    gradxx = conv(imout, fx, 'valid')
    gradyy = conv(imout, fy, 'valid')

    gradx = np.zeros(im.shape)
    grady = np.zeros(im.shape)
    padx = (imin.shape[0] - gradxx.shape[0]) / 2.0
    pady = (imin.shape[1] - gradxx.shape[1]) / 2.0
    gradx[padx:-padx, pady:-pady] = gradxx
    grady[padx:-padx, pady:-pady] = gradyy
    
    # Net gradient is the square root of sum of square of the horizontal
    # and vertical gradients

    grad = hypot(gradx, grady)
    theta = arctan2(grady, gradx)
    
    # clear gradients below threshold 5 (for Part5)
    xx, yy = where(grad < 5)
    theta[xx, yy] = 0
    grad[xx, yy] = 0

    return theta
Exemplo n.º 26
0
    def matched_filter(self, matching_template, signal, method='lfilt'):
        """ Implementation of a matched filter, using either the FIR method
        using an lfilter, or by using correlation directly.

        matching_template - waveform to match to, must be smaller than signal
                            [1-D numpy array]
        signal -            signal under test, must be longer than
                            matching_template [1-D numpy array]
        fs -                sample rate of the signal [Hz, float]
        method:
                            'lfilt' - Uses scipys lfilter with the reversed
                                      template acting as the b coefficients.
                            'conv'- using scipys convolution function to
                                    convolve the reversed template with the
                                    signal.
                            'fftconv' - using scipys fftconv function function
                                        to convolve the reversed template with
                                        the signal.
                            'corr'- using scipys correlate function to directly
                                    correlate the template to the signal.
        """

        if method is 'lfilt':
            matching_template = matching_template[::-1]  # flip the template
            matched_signal = lfilt(matching_template, [1.0], signal)

        elif method is 'conv':
            matching_template = matching_template[::-1]  # flip the template
            matched_signal = conv(signal,
                                  matching_template,
                                  mode='same',
                                  method='direct')

        elif method is 'fftconv':
            matching_template = matching_template[::-1]  # flip the template
            matched_signal = conv(signal,
                                  matching_template,
                                  mode='same',
                                  method='fft')

        elif method is 'corr':
            matched_signal = corr(signal,
                                  matching_template,
                                  mode='same',
                                  method='auto')

        return matched_signal
Exemplo n.º 27
0
def harris_corner_detector(im):
    """
  Detects harris corners.
  Make sure the returned coordinates are x major!!!
  :param im: A 2D array representing an image.
  :return: An array with shape (N,2), where ret[i,:] are the [x,y] coordinates of the ith corner points.
  """
    x_derivative = conv(im, X_DERIVATIVE_KERNEL, mode='same', boundary='symm')
    y_derivative = conv(im, Y_DERIVATIVE_KERNEL, mode='same', boundary='symm')
    Ix2 = blur_spatial(x_derivative**2, BLUR_KERNEL_SIZE)
    Iy2 = blur_spatial(y_derivative**2, BLUR_KERNEL_SIZE)
    IxIy = blur_spatial(x_derivative * y_derivative, BLUR_KERNEL_SIZE)
    m_det = (Ix2 * Iy2) - (IxIy * IxIy)
    m_trace = Ix2 + Iy2
    response_values = m_det - RESPONSE_FACTOR * (m_trace**2)
    binary_response = non_maximum_suppression(response_values)
    corners_indices = np.argwhere(binary_response.T)
    return corners_indices
Exemplo n.º 28
0
def create_kernel(kernel_size):
    counter = kernel_size
    kernel = np.array([1]).reshape(1, 1).astype('float64')

    while counter > 1:
        a = np.array([1, 1]).reshape(1, 2).astype('float64')
        kernel = (conv(kernel, a))
        counter = counter - 1
    return kernel / np.sum(kernel)
    def validateBattlefield_03(field):
        """

        """
        from scipy.signal import convolve2d as conv
        b = [[[[1 for j in range(i)]], [[1] for j in range(i)]]
             for i in range(1, 5)]
        b += [[[[1, 0], [0, 1]], [[0, 1], [1, 0]]]]
        count = [1, 2, 3, 4, 2]
        c = [40, 10, 4, 1, 0]
        for i in range(5):
            c0 = conv(field, b[i][0])
            c1 = conv(field, b[i][1])
            if sum([list(j).count(count[i])
                    for j in c0]) + sum([list(j).count(count[i])
                                         for j in c1]) != c[i]:
                return False
        return True
Exemplo n.º 30
0
def retrieve_gaussian_components(img, sigma, spacing, cmask=None):
    g1 = gaussian1D(sigma)
    g1 /= g1.max()
    l = g1.shape[0]
    g2 = np.outer(g1, g1)
    img2 = conv(img, g2, mode="same")
    if cmask is not None: img2 *= cmask
    coeffs = img2[l//2:-(l//2):spacing, l//2:-(l//2):spacing] # view !
    return coeffs
Exemplo n.º 31
0
Arquivo: CNN.py Projeto: Agnesfen/dml
	def cnnff(self,x):
		#print x
		self.layers[0].a={}
		self.layers[0].a.setdefault(0)
		self.layers[0].a[0]=x.copy()
		inputmap=1
		n=len(self.layers)
		
		for l in range(1,n):
			if self.layers[l].types=='s':
				for j in range(inputmap):
				
					temp=np.ones((self.layers[l].scale,self.layers[l].scale))/(self.layers[l].scale**2)
					z=conv(self.layers[l-1].a[j],np.array([temp]), 'valid')
					z=np.array(z)[:,::self.layers[l].scale,::self.layers[l].scale]

					if self.layers[l].a==None:
						self.layers[l].a={}
					self.layers[l].a.setdefault(j)
					self.layers[l].a[j] =z
					

			if self.layers[l].types=='c':
				if self.layers[l].a==None:
					self.layers[l].a={}
				for j in range(self.layers[l].out): #for each outmaps
					z = np.zeros(self.layers[l-1].a[0].shape - np.array([0,self.layers[l].kernelsize-1,self.layers[l].kernelsize-1]))
					for i in range(inputmap):       #cumulate from inputmaps
						z+=conv(self.layers[l-1].a[i],np.array([self.layers[l].k[i][j]]),'valid')			
					self.layers[l].a.setdefault(j)
					self.layers[l].a[j]=sigmoid(z+self.layers[l].b[j])
				inputmap = self.layers[l].out
				
		self.fv=None
		for j in range(len(self.layers[n-1].a)):
			sa=self.layers[n-1].a[j].shape
			p=self.layers[n-1].a[j].reshape(sa[0],sa[1]*sa[2]).copy()
			if (self.fv==None):
				self.fv=p
			else:
				self.fv=np.concatenate((self.fv,p),axis=1)
		self.fv=self.fv.transpose()
		self.o=sigmoid(np.dot(self.ffW,self.fv) + self.ffb)
def create_gaussian_vec_ker(vec_size):
    '''
    this function creates a gaussian kernel by convolution of [1 1] with itself, kernel_size times
    :param kernel_size: number of convolution operations to be performed
    :return: tuple of the (gaussian coefficients vector, gaussian kernel)
    '''
    if (vec_size < MIN_KER_SIZE):
        return np.asmatrix(np.array([1]))
    gaussian_vec = GAUSSIAN_KERNEL
    for i in range(vec_size - 2):
        gaussian_vec = conv(GAUSSIAN_KERNEL, gaussian_vec, mode='full')
    gaussian_ker = conv(gaussian_vec,
                        gaussian_vec.reshape((vec_size, 1)),
                        mode='full')
    vec_normalize_factor = np.sum(gaussian_vec)
    ker_normalize_factor = np.sum(gaussian_ker)
    gaussian_vec = gaussian_vec / vec_normalize_factor
    gaussian_ker = gaussian_ker / ker_normalize_factor
    return (gaussian_vec, gaussian_ker)
Exemplo n.º 33
0
def ConvFresnel2D(g,
                  x,
                  diam_out,
                  z,
                  inputs,
                  index_of_refraction=1,
                  set_dx=True):
    lam = inputs[0] / index_of_refraction
    [dx, diam] = GetDxAndDiam(x)

    dPhiTol_deg = inputs[3]
    dx_chirp = (dPhiTol_deg / 180) * lam * z / (
        diam + diam_out)  # sampling criterion for chirp (factors of pi cancel)
    if set_dx == False:
        dx_new = dx
    elif set_dx == True:  # use chirp sampling criterion
        dx_new = dx_chirp
    else:  # take dx_new to be value of set_dx
        if str(type(set_dx)) != "<class 'float'>":
            raise Exception("ConvFresnel2D: set_dx must be a bool or a float.")
        if set_dx <= 0:
            raise Exception(
                "ConvFresnel2D: numerical value of set_dx must be > 0.")
        dx_new = set_dx

    if dx != dx_new:  # interpolate g onto a grid with spacing of approx dx_new
        [g, x] = ResampleField2D(g, x, dx_new, inputs, kind='cubic')
        dx = x[1] - x[0]

    # make the kernel grid (s) match x as closely as possible
    ns = int(np.round(diam + diam_out) /
             dx)  # number of points on extended kernel
    s = np.linspace(-diam / 2 - diam_out / 2 + dx / 2,
                    diam / 2 + diam_out / 2 - dx / 2,
                    ns)  # spatial grid of extended kernel
    ind = np.where(np.abs(s) < diam_out /
                   2)[0]  # get the part of s within the 1D output grid
    [sx, sy] = np.meshgrid(s, s, indexing='xy')
    i_out = np.where(np.sqrt(sx * sx + sy * sy) > diam_out / 2)

    #Calculate Fresnel convoltion kernel, (Goodman 4-16)
    #  Note: the factor p = 1/(lam*z) is applied later
    #  Also note: the factor -1j*np.exp(2j*np.pi*z/lam) causes unwanted oscillations with z
    kern = np.exp(1j * np.pi * (sx * sx + sy * sy) /
                  (lam * z))  # Fresnel kernel
    if dx > dx_chirp:  # Where does |s| exceed the max step for this dx?
        s_max = lam * z * dPhiTol_deg / (360 * dx)
        null_ind = np.where(np.sqrt(sx * sx + sy * sy) > s_max)
        kern[null_ind[0], null_ind[1]] = 0
    h = conv(kern, g, mode='same', method='fft')  # h is on the s spatial grid
    h[i_out[0], i_out[1]] = 0.  # zero the field outside the desired region
    h = h[ind[0]:ind[-1] + 1, ind[0]:ind[-1] + 1]
    p = 1 / (lam * z)
    return ([p * h, s[ind]])
Exemplo n.º 34
0
def put_gaussians_on_image(shp, sigma, spacing, g_coeffs=None, cmask=None, debug=False):
    g1 = gaussian1D(sigma)
    g1 /= g1.max()
    l = g1.shape[0]
    g2 = np.outer(g1, g1)
    res = np.zeros(shp)
    res[l//2:-(l//2):spacing, l//2:-(l//2):spacing] = 1 if g_coeffs is None else g_coeffs
    if cmask is not None: res *= cmask # do it before convol, otherwise truncation artefacts !
    if debug: print("%d Gaussians used for %s" % (res[res!=0].sum(), str(shp)))
    res = conv(res, g2, mode="same")
    return res
Exemplo n.º 35
0
 def x_out(self, hid):
     hid = np.pad(
         hid,
         ((0, 0),
          (self.filters[0].shape[0] - 1, self.filters[0].shape[0] - 1),
          (self.filters[0].shape[1] - 1, self.filters[0].shape[1] - 1)),
         mode='constant')
     if self.style == 'reichert':
         return list(
             np.sum(np.array([
                 (conv(np.abs(h), filt,
                       mode='valid'), conv(h, filt, mode='valid'))
                 for (h, filt) in zip(hid, self.adjoint_filters)
             ]),
                    axis=0))
     else:
         return np.sum(np.array([
             conv(h, filt, mode='valid')
             for (h, filt) in zip(hid, self.adjoint_filters)
         ]),
                       axis=0)
def blur_spatial(im, kernel_size):
    '''
    this function blurs the given image- im, by convolution with gaussian kernel
    :param im: the image to be blurred
    :param kernel_size: the desired gaussian kernel size
    :return: the blurred image
    '''
    if (kernel_size < MIN_KER_SIZE):
        return im
    gaussian_ker = create_gaussian_vec_ker(kernel_size)[1]
    blurred_img = conv(im, gaussian_ker, mode='same', boundary='wrap')
    return blurred_img
Exemplo n.º 37
0
def findAngle(im, sigma, minThreshold):
    
    imin = im.copy() * 255.0  
    
    wsize = 5
    gausskernel = gaussFilter(sigma, window = wsize)
    # fx is the filter for vertical gradient
    # fy is the filter for horizontal gradient
    # Please note the vertical direction is positive X

    fx = createFilter([0,  1, 0,
                       0,  0, 0,
                       0, -1, 0])
    fy = createFilter([ 0, 0, 0,
                       -1, 0, 1,
                        0, 0, 0])

    imout = conv(imin, gausskernel, 'valid')
    # print "imout:", imout.shape
    gradxx = conv(imout, fx, 'valid')
    gradyy = conv(imout, fy, 'valid')

    gradx = np.zeros(im.shape)
    grady = np.zeros(im.shape)
    padx = (imin.shape[0] - gradxx.shape[0]) / 2.0
    pady = (imin.shape[1] - gradxx.shape[1]) / 2.0
    gradx[padx:-padx, pady:-pady] = gradxx
    grady[padx:-padx, pady:-pady] = gradyy
    
    # Net gradient is the square root of sum of square of the horizontal
    # and vertical gradients

    grad = hypot(gradx, grady)
    theta = arctan2(grady, gradx)
    
    xx, yy = where(grad < minThreshold)
    theta[xx, yy] = 0
    grad[xx, yy] = 0
    
    return theta
Exemplo n.º 38
0
def conv_der(im):
    """
    derivative of an image using convolution

    Parameters
    ----------
    :param im

    Returns
    -------
    :return magnitude of the derivative

    """
    im = im.astype(np.float64)
    # set der x/y matrix
    der_x = np.array([[1, 0, -1]])
    der_y = np.array(der_x.transpose())
    # calculate the derivative to x and y
    dx = conv(im, der_x, mode='same')
    dy = conv(im, der_y, mode='same')

    return np.sqrt(np.abs(dx)**2 + np.abs(dy)**2)  # = magnitude
Exemplo n.º 39
0
def plot_rewards(n_episodes, rewards, average_range=10):
    """
    Generate plot showing total reward accumulated in each episode.
    """
    smoothed_rewards = (conv(rewards, np.ones(average_range), mode='same') /
                        average_range)
    fig = plt.figure()
    plt.plot(range(0, n_episodes, average_range),
             smoothed_rewards[0:n_episodes:average_range],
             marker='o',
             linestyle='--')
    plt.xlabel('Episodes')
    plt.ylabel('Total reward')
    return fig
    def __init__(self,imname,sigma,thresHigh = 50,thresLow = 10):
        self.imin = imread(imname,flatten = True)
 
        # Create the gauss kernel for blurring the input image
        # It will be convolved with the image
        gausskernel = self.gaussFilter(sigma,5)
        # fx is the filter for vertical gradient
        # fy is the filter for horizontal gradient
        # Please not the vertical direction is positive X
         
        fx = self.createFilter([1, 1, 1,
                                0, 0, 0,
                               -1,-1,-1])
        fy = self.createFilter([-1,0,1,
                                -1,0,1,
                                -1,0,1])
 
        imout = conv(self.imin,gausskernel)[1:-1,1:-1]
        gradx = conv(imout,fx)[1:-1,1:-1]
        grady = conv(imout,fy)[1:-1,1:-1]
 
        # Net gradient is the square root of sum of square of the horizontal
        # and vertical gradients
 
        grad = hypot(gradx,grady)
        theta = arctan2(grady,gradx)
        theta = 180 + (180/pi)*theta
        # Only significant magnitudes are considered. All others are removed
        x,y = where(grad < 10)
        theta[x,y] = 0
        grad[x,y] = 0
 
        # The angles are quantized. This is the first step in non-maximum
        # supression. Since, any pixel will have only 4 approach directions.
        x0,y0 = where(((theta<22.5)+(theta>157.5)*(theta<202.5)
                       +(theta>337.5)) == True)
        x45,y45 = where( ((theta>22.5)*(theta<67.5)
                          +(theta>202.5)*(theta<247.5)) == True)
        x90,y90 = where( ((theta>67.5)*(theta<112.5)
                          +(theta>247.5)*(theta<292.5)) == True)
        x135,y135 = where( ((theta>112.5)*(theta<157.5)
                            +(theta>292.5)*(theta<337.5)) == True)
 
        self.theta = theta
        Image.fromarray(self.theta).convert('L').save('Angle map.jpg')
        self.theta[x0,y0] = 0
        self.theta[x45,y45] = 45
        self.theta[x90,y90] = 90
        self.theta[x135,y135] = 135
        x,y = self.theta.shape        
        temp = Image.new('RGB',(y,x),(255,255,255))
        for i in range(x):
            for j in range(y):
                if self.theta[i,j] == 0:
                    temp.putpixel((j,i),(0,0,255))
                elif self.theta[i,j] == 45:
                    temp.putpixel((j,i),(255,0,0))
                elif self.theta[i,j] == 90:
                    temp.putpixel((j,i),(255,255,0))
                elif self.theta[i,j] == 45:
                    temp.putpixel((j,i),(0,255,0))
        self.grad = grad.copy()
        x,y = self.grad.shape
 
        for i in range(x):
            for j in range(y):
                if self.theta[i,j] == 0:
                    test = self.nms_check(grad,i,j,1,0,-1,0)
                    if not test:
                        self.grad[i,j] = 0
 
                elif self.theta[i,j] == 45:
                    test = self.nms_check(grad,i,j,1,-1,-1,1)
                    if not test:
                        self.grad[i,j] = 0
 
                elif self.theta[i,j] == 90:
                    test = self.nms_check(grad,i,j,0,1,0,-1)
                    if not test:
                        self.grad[i,j] = 0
                elif self.theta[i,j] == 135:
                    test = self.nms_check(grad,i,j,1,1,-1,-1)
                    if not test:
                        self.grad[i,j] = 0
                     
        init_point = self.stop(self.grad, thresHigh)
        # Hysteresis tracking. Since we know that significant edges are
        # continuous contours, we will exploit the same.
        # thresHigh is used to track the starting point of edges and
        # thresLow is used to track the whole edge till end of the edge.
         
        while (init_point != -1):
            #Image.fromarray(self.grad).show()
            print 'next segment at',init_point
            self.grad[init_point[0],init_point[1]] = -1
            p2 = init_point
            p1 = init_point
            p0 = init_point
            p0 = self.nextNbd(self.grad,p0,p1,p2,thresLow)
             
            while (p0 != -1):
                #print p0
                p2 = p1
                p1 = p0
                self.grad[p0[0],p0[1]] = -1
                p0 = self.nextNbd(self.grad,p0,p1,p2,thresLow)
                 
            init_point = self.stop(self.grad,thresHigh)
 
        # Finally, convert the image into a binary image
        x,y = where(self.grad == -1)
        self.grad[:,:] = 0
        self.grad[x,y] = 255
Exemplo n.º 41
0
def canny(im, sigma, thresHigh = 40, thresLow = 10):
    '''
        Takes an input image in the range [0, 1] and generate a gradient image
        with edges marked by 1 pixels.
    '''
    imin = im.copy() * 255.0

    # Create the gauss kernel for blurring the input image
    # It will be convolved with the image
    # wsize should be an odd number
    wsize = 5
    gausskernel = gaussFilter(sigma, window = wsize)
    # fx is the filter for vertical gradient
    # fy is the filter for horizontal gradient
    # Please note the vertical direction is positive X

    fx = createFilter([0,  1, 0,
                       0,  0, 0,
                       0, -1, 0])
    fy = createFilter([ 0, 0, 0,
                       -1, 0, 1,
                        0, 0, 0])

    imout = conv(imin, gausskernel, 'valid')
    # print "imout:", imout.shape
    gradxx = conv(imout, fx, 'valid')
    gradyy = conv(imout, fy, 'valid')

    gradx = np.zeros(im.shape)
    grady = np.zeros(im.shape)
    padx = (imin.shape[0] - gradxx.shape[0]) / 2.0
    pady = (imin.shape[1] - gradxx.shape[1]) / 2.0
    gradx[padx:-padx, pady:-pady] = gradxx
    grady[padx:-padx, pady:-pady] = gradyy
    
    # Net gradient is the square root of sum of square of the horizontal
    # and vertical gradients

    grad = hypot(gradx, grady)
    theta = arctan2(grady, gradx)
    theta = 180 + (180 / pi) * theta
    # Only significant magnitudes are considered. All others are removed
    xx, yy = where(grad < 10)
    theta[xx, yy] = 0
    grad[xx, yy] = 0

    # The angles are quantized. This is the first step in non-maximum
    # supression. Since, any pixel will have only 4 approach directions.
    x0,y0 = where(((theta<22.5)+(theta>157.5)*(theta<202.5)
                   +(theta>337.5)) == True)
    x45,y45 = where( ((theta>22.5)*(theta<67.5)
                      +(theta>202.5)*(theta<247.5)) == True)
    x90,y90 = where( ((theta>67.5)*(theta<112.5)
                      +(theta>247.5)*(theta<292.5)) == True)
    x135,y135 = where( ((theta>112.5)*(theta<157.5)
                        +(theta>292.5)*(theta<337.5)) == True)

    theta = theta
    Image.fromarray(theta).convert('L').save('Angle map.jpg')
    theta[x0,y0] = 0
    theta[x45,y45] = 45
    theta[x90,y90] = 90
    theta[x135,y135] = 135
    x,y = theta.shape       
    temp = Image.new('RGB',(y,x),(255,255,255))
    for i in range(x):
        for j in range(y):
            if theta[i,j] == 0:
                temp.putpixel((j,i),(0,0,255))
            elif theta[i,j] == 45:
                temp.putpixel((j,i),(255,0,0))
            elif theta[i,j] == 90:
                temp.putpixel((j,i),(255,255,0))
            elif theta[i,j] == 45:
                temp.putpixel((j,i),(0,255,0))
    retgrad = grad.copy()
    x,y = retgrad.shape

    for i in range(x):
        for j in range(y):
            if theta[i,j] == 0:
                test = nms_check(grad,i,j,1,0,-1,0)
                if not test:
                    retgrad[i,j] = 0

            elif theta[i,j] == 45:
                test = nms_check(grad,i,j,1,-1,-1,1)
                if not test:
                    retgrad[i,j] = 0

            elif theta[i,j] == 90:
                test = nms_check(grad,i,j,0,1,0,-1)
                if not test:
                    retgrad[i,j] = 0
            elif theta[i,j] == 135:
                test = nms_check(grad,i,j,1,1,-1,-1)
                if not test:
                    retgrad[i,j] = 0

    init_point = stop(retgrad, thresHigh)
    # Hysteresis tracking. Since we know that significant edges are
    # continuous contours, we will exploit the same.
    # thresHigh is used to track the starting point of edges and
    # thresLow is used to track the whole edge till end of the edge.

    while (init_point != -1):
        #Image.fromarray(retgrad).show()
        # print 'next segment at',init_point
        retgrad[init_point[0],init_point[1]] = -1
        p2 = init_point
        p1 = init_point
        p0 = init_point
        p0 = nextNbd(retgrad,p0,p1,p2,thresLow)

        while (p0 != -1):
            #print p0
            p2 = p1
            p1 = p0
            retgrad[p0[0],p0[1]] = -1
            p0 = nextNbd(retgrad,p0,p1,p2,thresLow)

        init_point = stop(retgrad,thresHigh)

    # Finally, convert the image into a binary image
    x,y = where(retgrad == -1)
    retgrad[:,:] = 0
    retgrad[x,y] = 1.0
    return retgrad
Exemplo n.º 42
0
N_squares = 40
W_squares = 20
starts = arange(0, W_squares, 1.0)
starts *= N / W_squares

for i in starts:
    for j in starts:
        grid[i:i+W_squares,j:j+W_squares] = 1

G = fft2(grid)
G = fftshift(G)
G /= G.max()

wider = ones((4,4))
G = conv(G, wider)

figure()

subplot(1, 2, 1)
imshow(grid)
axis('off')
title('\\textrm{Grid}')

subplot(1, 2, 2)
M = N/10
imshow(abs(G)[N/2-M:N/2+M, N/2-M:N/2+M], interpolation='nearest')
title('\\textrm{Fourier transform}')

axis('off')
Exemplo n.º 43
0
def roomcomp(impresp, filter, target, ntaps, mixed_phase, opformat, trim, nsthresh, noplot):

  print "Loading impulse response"
  
  # Read impulse response
  Fs, data = wavfile.read(impresp)
  data = norm(np.hstack(data))


  if trim:
    print "Removing leading silence"
    for spos,sval in enumerate(data):
        if abs(sval)>nsthresh:
            lzs=max(spos-1,0)
            ld =len(data)
            print 'Impulse starts at position ', spos, '/', len(data)
            print 'Trimming ', float(lzs)/float(Fs), ' seconds of silence'
            data=data[lzs:len(data)] #remove everything before sample at spos
            break
		  
  print "\nSample rate = ", Fs
  
  print "\nGenerating correction filter"

  ###
  ## Logarithmic pole positioning
  ###

  fplog = np.hstack((sp.logspace(sp.log10(20.), sp.log10(200.), 14.), sp.logspace(sp.log10(250.), 
             sp.log10(20000.), 13.))) 
  plog = freqpoles(fplog, Fs)

  ###
  ## Preparing data
  ###

  # making the measured response minumum-phase
  cp, minresp = rceps(data)

  # Impulse response
  imp = np.zeros(len(data), dtype=np.float64)
  imp[0]=1.0

  # Target
  outf = []
  db = []

  if target is 'flat':
    
    # Make the target output a bandpass filter
    Bf, Af = sig.butter(4, 30/(Fs/2), 'high')
    outf = sig.lfilter(Bf, Af, imp) 
    
  else:
    
    # load target file
    t = np.loadtxt(target)
    frq = t[:,0]; pwr = t[:,1]
    
    # calculate the FIR filter via windowing method
    fir = sig.firwin2(501, frq, np.power(10, pwr/20.0), nyq = frq[-1])	
    # Minimum phase, zero padding	
    cp, outf = rceps(np.append(fir, np.zeros(len(minresp) - len(fir))))
      
  ###
  ## Filter design
  ###

  #Parallel filter design
  (Bm, Am, FIR) = parfiltid(minresp, outf, plog)

  # equalized loudspeaker response - filtering the 
  # measured transfer function by the parallel filter
  equalizedresp = parfilt(Bm, Am, FIR, data)

  # Equalizer impulse response - filtering a unit pulse
  equalizer = norm(parfilt(Bm, Am, FIR, imp))

  # Windowing with a half hanning window in time domain
  han = np.hanning(ntaps*2)[-ntaps:]
  equalizer = han * equalizer[:ntaps]

  ###
  ## Mixed-phase compensation
  ## Based on the paper "Mixed Time-Frequency approach for Multipoint
  ## Room Rosponse Equalization," by A. Carini et al.
  ## To use this feature, your Room Impulse Response should have all
  ## the leading zeros removed.
  ###
  if mixed_phase is True:
    
    # prototype function
    hp = norm(np.real(equalizedresp))

    # time integration of the human ear is ~24ms
    # See "Measuring the mixing time in auditoria," by Defrance & Polack
    hop_size = 0.024
    samples = hop_size * Fs

    bins = np.int(np.ceil(len(hp) / samples))

    tmix = 0

    # Kurtosis method
    for b in range(bins):
      start = np.int(b * samples)
      end = np.int((b+1) * samples)
      k = kurtosis(hp[start:end])
      if k <= 0:
        tmix = b * hop_size
        break

    # truncate the prototype function
    taps = np.int(tmix*Fs)

    print "\nmixing time(secs) = ", tmix, "; taps = ", taps
    
    if taps > 0:
      # Time reverse the array
      h = hp[:taps][::-1]
      # create all pass filter
      phase = np.unwrap(np.angle(h))
      H = np.exp(1j*phase)
      # convert from db to linear
      mixed = np.power(10, np.real(H)/20.0)
      # create filter's impulse response
      mixed = np.real(ifft(mixed))
      
      # convolve and window to desired length
      equalizer = conv(equalizer, mixed)
      equalizer = han * equalizer[:ntaps]
      
      #data = han * data[:ntaps]
      #eqresp = np.real(conv(equalizer, data))
    else:
      print "zero taps; skipping mixed-phase computation"
  if opformat in ('wav', 'wav24'):      
  # Write data
    wavwrite_24(filter, Fs, norm(np.real(equalizer)))
    print '\nOutput format is wav24'
    print 'Output filter length =', len(equalizer), 'taps'
    print 'Output filter written to ' + filter
	
    print "\nUse sox to convert output .wav to raw 32 bit IEEE floating point if necessary,"
    print "or to merge left and right channels into a stereo .wav"
    print "\nExample: sox leq48.wav -t f32 leq48.bin"
    print "         sox -M le148.wav req48.wav output.wav\n"

  elif opformat == 'wav32':
    wavwrite_32(filter, Fs, norm(np.real(equalizer)))
    print '\nOutput format is wav32'
    print 'Output filter length =', len(equalizer), 'taps'
    print 'Output filter written to ' + filter
    print "\nUse sox to convert output .wav to raw 32 bit IEEE floating point if necessary,"
    print "or to merge left and right channels into a stereo .wav"
    print "\nExample: sox leq48.wav -t f32 leq48.bin"
    print "         sox -M le148.wav req48.wav output.wav\n"
  elif opformat == 'bin':
    # direct output to bin avoids float64->pcm16->float32 conversion by going direct 
    #float64->float32
    f = open(filter, 'wb')
    norm(np.real(equalizer)).astype('float32').tofile(f)
    f.close()
    print '\nOutput filter length =', len(equalizer), 'taps'
    print 'Output filter written to ' + filter
  else:
    print 'Output format not recognized, no file generated.'


  ###
  ## Plots
  ###
  if not noplot:
    data *= 500
    # original loudspeaker-room response
    tfplot(data, Fs, avg = 'abs')
    # 1/3 Octave smoothed
    tfplots(data, Fs, 'r')

    #tfplot(mixed, Fs, 'r')

    # equalizer transfer function
    tfplot(0.75*equalizer, Fs, 'g')
    # indicating pole frequencies
    plt.vlines(fplog, -2, 2, color='k', linestyles='solid')

    # equalized loudspeaker-room response
    tfplot(equalizedresp*0.01, Fs, avg = 'abs')
    # 1/3 Octave smoothed
    tfplots(equalizedresp*0.01, Fs, 'r')

    # Add labels
    # May need to reposition these based on input data
    plt.text(325,30,'Unequalized loudspeaker-room response')
    plt.text(100,-15,'Equalizer transfer function')
    plt.text(100,-21,'(Black lines: pole locations)')
    plt.text(130,-70,'Equalized loudspeaker-room response')

    a = plt.gca()
    a.set_xlim([20, 20000])
    a.set_ylim([-80, 80])
    plt.ylabel('Amplitude (dB)', color='b')
    plt.xlabel('Frequency (Hz)')
    plt.grid()
    plt.legend()
    plt.show()
Exemplo n.º 44
0
 def _waveCalibration(self, simpleWvCalib= True, absScale= True,
                      **kwargs):
     """
     """
     method = kwargs.pop('method', True)
     if simpleWvCalib:
         if absScale:
             return (np.arange(self.nwv) -
                     self.header['crpix1']) * self.header['cdelt1'] + self.header['crval1']
         else:
             return (np.arange(self.nwv) -
                     self.header['crpix1']) * self.header['cdelt1']
     else:
         if method:
             if self.band == '6562':
                 line=np.array([6561.097,6564.206])
                 lamb0=6562.817
                 dldw=0.019182
             elif self.band == '8542':
                 line=np.array([8540.817,8546.222])
                 lamb0=8542.090
                 dldw=-0.026252
             elif self.band == '5889':
                 line=np.array([5889.951,5892.898])
                 lamb0=5889.9509
                 dldw=0.016847
             elif self.band == '5434':
                 line=np.array([5434.524,5436.596])
                 lamb0=5434.5235
                 dldw=-0.016847
         else:
             if self.band == '6562':
                 line=np.array([6562.817,6559.580])
                 lamb0=6562.817
                 dldw=0.019182
             elif self.band == '8542':
                 line=np.array([8542.089,8537.930])
                 lamb0=8542.090
                 dldw=-0.026252
     
     w = np.arange(self.nwv)
     wl = np.zeros(2)
     wc = self.refProfile[20:self.nwv-20].argmin() + 20
     lamb = (w - wc) * dldw + lamb0
     
     for i in range(2):
         mask = np.abs(lamb - line[i]) <= 0.3
         wtmp = w[mask]
         ptmp = conv(self.refProfile[mask], [-1, 2, -1], 'same')
         mask2 = ptmp[1:-1].argmin() + 1
         try:
             wtmp = wtmp[mask2-3:mask2+4]
             ptmp = ptmp[mask2-3:mask2+4]
         except:
             raise ValueError('Fail to wavelength calibration\n'
             'please change the method %s to %s' %(repr(method), repr(not method)))
         c = np.polyfit(wtmp - np.median(wtmp), ptmp, 2)
         wl[i] = np.median(wtmp) - c[1]/(2*c[0])
         
     dldw = (line[1] - line[0])/(wl[1] - wl[0])
     wc = wl[0] - (line[0] - lamb0)/dldw
     return (w - wc) * dldw
Exemplo n.º 45
0
Arquivo: p2.py Projeto: blackle/Year_3
def computeGradient(im, sigma, canny_edges, thresh, interpolate):
    '''
        Takes an input image in the range [0, 1] and generate a gradient image
        with edges marked by 1 pixels.
    '''
    imin = im.copy() * 255.0

    # Create the gauss kernel for blurring the input image
    # It will be convolved with the image
    # wsize should be an odd number
    wsize = 5 #changed to 7 bc w/e
    gausskernel = canny.gaussFilter(sigma, window = wsize)
    # fx is the filter for vertical gradient
    # fy is the filter for horizontal gradient
    # Please not the vertical direction is positive X

    fx = canny.createFilter([0,  1, 0,
                       0,  0, 0,
                       0, -1, 0])
    fy = canny.createFilter([ 0, 0, 0,
                       -1, 0, 1,
                        0, 0, 0])

    imout = conv(imin, gausskernel, 'same','symm')
    # print "imout:", imout.shape
    gradx = conv(imout, fx, 'same','symm')
    grady = conv(imout, fy, 'same','symm')

    grad = hypot(gradx, grady)
    # Only significant magnitudes are considered. All others are removed


    if(interpolate):
        samplefraction = 4 #sample only points that are on the lattice of this size
        # it seems that sampling at smaller intervals makes really cool shapes
        interpolating_function='thin_plate'

        #compute thin plate spline, putting sample points on canny edges
        gsx, gsy = gradx.shape
        cxx, cyy = where(cannyimg[0:gsx:samplefraction,0:gsy:samplefraction] > 0)
        cxx = cxx*samplefraction
        cyy = cyy*samplefraction

        # the thin plate approximation routines give warnings, ignore them
        warnings.simplefilter("ignore")

        zz = gradx[cxx,cyy]
        mysamples = array([cxx,cyy,zz]).T.reshape(-1,3)
        xx,yy,zz = mysamples.T
        thin_plate_x = Rbf(xx,yy,zz,function=interpolating_function)

        zz = grady[cxx,cyy]
        mysamples = array([cxx,cyy,zz]).T.reshape(-1,3)
        xx,yy,zz = mysamples.T
        thin_plate_y = Rbf(xx,yy,zz,function=interpolating_function)

        #replace values below threshold with interpolation
        xx,yy = where(grad < thresh)
        gradx[xx,yy] = thin_plate_x(xx,yy)
        grady[xx,yy] = thin_plate_y(xx,yy)

    theta = arctan2(grady, gradx)
    #print zz

    if(not interpolate):
        xx,yy = where(grad < thresh)
        theta[xx, yy] = 0
        grad[xx, yy] = 0

    return (theta, grad)
Exemplo n.º 46
0
def wavecalib(band,profile,method=True):
    """
    Calibrate the wavelength for FISS spectrum profile.
    
    Parameters
    ----------
    band : str
        A string to identify the wavelength.
        Allowable wavelength bands are '6562','8542','5890','5434'
    profile : ~numpy.ndarray
        A 1 dimensional numpy array of spectral profile.
    Method : (optional) bool
        * Default is True.
        If true, the reference lines for calibration are the telluric lines.
        Else if False, the reference lines are the solar absorption lines.
    
    Returns
    -------
    wavelength : ~numpy.ndarray
        Calibrated wavelength.
    
    Notes
    -----
        This function is based on the FISS IDL code FISS_WV_CALIB.PRO
        written by J. Chae, 2013.
    
    Example
    -------
    >>> from fisspy.analysis import doppler
    >>> wv=doppler.wavecalib('6562',profile)
    
    """
    band=band[0:4]
    nw=profile.shape[0]
    
    if method:
        if band == '6562':
            line=np.array([6561.097,6564.206])
            lamb0=6562.817
            dldw=0.019182
        elif band == '8542':
            line=np.array([8540.817,8546.222])
            lamb0=8542.090
            dldw=-0.026252
        elif band == '5890':
            line=np.array([5889.951,5892.898])
            lamb0=5889.9509
            dldw=0.016847
        elif band == '5434':
            line=np.array([5434.524,5436.596])
            lamb0=5434.5235
            dldw=-0.016847
        else:
            raise ValueError("The wavelength band value is not allowable.\n"+
                             "Please select the wavelenth "+
                             "among '6562','8542','5890','5434'")
    else:
        if band == '6562':
            line=np.array([6562.817,6559.580])
            lamb0=6562.817
            dldw=0.019182
        elif band == '8542':
            line=np.array([8542.089,8537.930])
            lamb0=8542.090
            dldw=-0.026252
        else:
            raise ValueError("The wavelength band value is not allowable.\n"
                             "Please select the wavelenth "
                             "among '6562','8542','5890','5434'")
    
    w=np.arange(nw)
    wl=np.zeros(2)
    wc=profile[20:nw-20].argmin()+20
    lamb=(w-wc)*dldw+lamb0
    
    for i in range(2):
        mask=np.abs(lamb-line[i]) <= 0.3
        wtmp=w[mask]
        ptmp=conv(profile[mask],[-1,2,-1],'same')
        mask2=ptmp[1:-1].argmin()+1
        try:
            wtmp=wtmp[mask2-3:mask2+4]
            ptmp=ptmp[mask2-3:mask2+4]
        except:
            raise ValueError('Fail to wavelength calibration\n'
            'please change the method %s to %s' %(repr(method), repr(not method)))
        c=np.polyfit(wtmp-np.median(wtmp),ptmp,2)
        wl[i]=np.median(wtmp)-c[1]/(2*c[0])    #local minimum of the profile
    
    dldw=(line[1]-line[0])/(wl[1]-wl[0])
    wc=wl[0]-(line[0]-lamb0)/dldw
    wavelength=(w-wc)*dldw
    
    return wavelength
Exemplo n.º 47
0
def lambdameter(wv, data0, ref_spectrum= False, wvRange = False,
                hw= 0.03, sp= 5000, wvinput= True):
    """
    Determine the Lambdameter chord center for a given half width or intensity.
    
    Parameters
    ----------
    wv : ~numpy.ndarray
        A Calibrated wavelength.
    data : ~numpy.ndarray
        n (n=2 or n=3) dimensional spectral profile data, 
        the last dimension component must be the spectral component,
        and the size is equal to the size of wv.
    wvinput : bool
        There are two cases.
            
    * Case wvinput==True
        
            hw : float
                A half width of the horizontal line segment.
                
        Returns
        -------
        wc : nd ndarray
            n dimensional array of central wavelength values.
        intc : nd ndarray
            n dimensional array of intensies of the line segment.\\
        
    * Case wvinput==False
        
            sp : float
                An intensity of the horiznotal segment.
                
        Returns
        -------
        wc : nd ndarray
            n dimensional array of central wavelength values.
        hwc : nd ndarray
            n dimensional array of half widths of the line segment.
    
    Notes
    -----
        This function is based on the IDL code BISECTOR_D.PRO
        written by J. Chae.
    
    Example
    -------
    >>> from fisspy.analysis import doppler
    >>> wc, inten = doppler.labdameter(wv,data,0.2)
    
    """
    
    shape=data0.shape
    nw=shape[-1]
    reshape=shape[:-1]
    dkern = np.array([[-1, 1, 0, 1, -1]])
    rspec = np.any(ref_spectrum)
    ndim = data0.ndim
    wvoffset = 0
    dwv = wv[1]-wv[0]
    if rspec and data0.ndim == 3:
        refSpec = conv(ref_spectrum , dkern[0],'same')
        refSpec[:2] = refSpec[-2:] = 0
        refSpec = refSpec * np.ones((4,1))
        data2d = conv(data0.mean(0), dkern, 'same')
        data2d[:,:2] = data2d[:,-2:] = 0
        data = data2d * np.ones((4, 1, 1))
#        data[:,:,:2] = data[:,:,-2:] = 0
        dataT = data.transpose((1, 0, 2))
        yoff, xoff, cor = alignoffset(dataT, refSpec, cor= True)
        wvoffset = (xoff*(wv[1]-wv[0])) * (cor > 0.7)
    elif not rspec and ndim == 3:
        wvoffset = np.zeros(shape[1])
    elif ndim == 1 or ndim >=4:
        ValueError('The dimension of data0 must be 2 or 3.')
    
    if wv.shape[0] != nw:
        raise ValueError('The number of elements of wv and '
        'the number of elements of last axis for data are not equal.')
    
    if np.any(wvRange):
        ss = np.logical_and(wv >= wvRange[0], wv <= wvRange[1])
        nw = ss.sum()
        data0 = data0[:,:,ss].copy()
        wv = wv[ss].copy()
    na=int(data0.size/nw)
    data=data0.reshape((na,nw))

    
    s=data.argmin(axis=-1)
    
    if wvinput and hw == 0.:
        raise ValueError('The half-width value must be greater than 0.')
#        fna=range(na)
#        wtmp=wv[np.array((s-5,s-4,s-3,s-2,s-1,s,s+1,s+2,s+3,s+4,s+5))]
#        mwtmp=np.median(wtmp,axis=0)
#        sp0=np.array([data[i,s[i]-5:s[i]+6] for i in fna])
#        c=np.array([scipy.polyfit(wtmp[:,i]-mwtmp[i],sp0[i,:],2) for i in fna])
#        wc=mwtmp-c[:,1]/(2*c[:,0])
#        p=[scipy.poly1d(c[i,:]) for i in fna]
#        intc=np.array([p[i](wc[i]-mwtmp[i]) for i in fna])
#        wc=wc.reshape(reshape).T
#        intc=intc.reshape(reshape).T
#        return wc, intc
        
    posi0=np.arange(na)
    smin=[0,wv[0]]
    smax=[na-1,wv[-1]]
    order=[na,len(wv)]
    if wvinput:
            interp=LinearSpline(smin,smax,order,data)
            wl=np.array((posi0,wv[s]-hw)).T; wr=np.array((posi0,wv[s]+hw)).T
            intc=0.5*(interp(wl)+interp(wr))
    else:
        intc=np.ones(na)*sp
    
    wc=np.zeros(na)
    hwc=np.zeros(na)
    ref=1    
    rep=0
    s0=s.copy()
    more=data[posi0,s0]>100
    
    while ref > 0.00001 and rep <6:
        sp1=data-intc[:,None]
        comp=sp1[:,0:nw-1]*sp1[:,1:nw]
        
        s=comp[more] <=0.
        nsol=s.sum(axis=1)
        j=nsol//2
        whl=nsol.cumsum()-nsol+j-1
        whr=nsol.cumsum()-nsol+j
        whp, whs=np.where(s)
        l=whs[whl]
        r=whs[whr]
        posi=posi0[more]
        wl0=wv[l]-dwv/(sp1[posi,l+1]-sp1[posi,l])*sp1[posi,l]
        wr0=wv[r]-dwv/(sp1[posi,r+1]-sp1[posi,r])*sp1[posi,r]
        wc[more]=0.5*(wl0+wr0)
        hwc[more]=0.5*np.abs(wr0-wl0)
        
        if wvinput:
            wl=np.array((posi,wc[more]-hw)).T; wr=np.array((posi,wc[more]+hw)).T
            intc[more]=0.5*(interp(wl)+interp(wr))
            ref0=np.abs(hwc-hw)
            ref=ref0.max()
            more=(ref0>0.00001)*(data[posi0,s0]>100)
        else:
            ref=0
        rep+=1
    

    wc = wc.reshape(reshape) - wvoffset
    if wvinput:
        intc=intc.reshape(reshape)
        return wc, intc
    else:
        hwc=hwc.reshape(reshape)
        return wc, hwc