Пример #1
0
    def inigaus_fbdsm(self, isl, thr, beam, img):
        """ initial guess for gaussians like in fbdsm """
        from math import sqrt
        from const import fwsig
        import functions as func

        im = isl.image - isl.islmean
        if img.opts.ini_method == 'curvature':
            im_pos = -1.0 * func.make_curvature_map(isl.image - isl.islmean)
            thr_pos = 0.0
        else:
            im_pos = im
            thr_pos = thr
        mask = isl.mask_active
        av = img.clipped_mean
        inipeak, iniposn, im1 = func.get_maxima(im,
                                                mask,
                                                thr_pos,
                                                isl.shape,
                                                beam,
                                                im_pos=im_pos)
        if len(inipeak) == 0:
            av, stdnew, maxv, maxp, minv, minp = func.arrstatmask(im, mask)
            inipeak = [maxv]
            iniposn = [maxp]
        nmulsrc1 = len(iniposn)

        domore = True
        while domore:
            domore = False
            av, stdnew, maxv, maxp, minv, minp = func.arrstatmask(im1, mask)
            if stdnew > isl.rms and maxv >= thr and maxv >= isl.mean + 2.0 * isl.rms:
                domore = True
                x1, y1 = N.array(iniposn).transpose()
                dumr = N.sqrt((maxp[0] - x1) * (maxp[0] - x1) +
                              (maxp[1] - y1) * (maxp[1] - y1))
                distbm = dumr / sqrt(beam[0] * beam[1] * fwsig * fwsig)
                if N.any((distbm < 0.5) + (dumr < 2.2)):
                    domore = False
                if domore:
                    iniposn.append(N.array(maxp))
                    inipeak.append(maxv)
                    im1 = func.mclean(im1, maxp, beam)

        inipeak = N.array(inipeak)
        iniposn = N.array(iniposn)
        ind = list(N.argsort(inipeak))
        ind.reverse()
        inipeak = inipeak[ind]
        iniposn = iniposn[ind]
        gaul = []
        for i in range(len(inipeak)):
            g = (float(inipeak[i]), int(iniposn[i][0]), int(
                iniposn[i][1])) + beam
            gaul.append(g)

        return gaul, nmulsrc1, len(inipeak)
Пример #2
0
    def inigaus_fbdsm(self, isl, thr, beam, img):
        """ initial guess for gaussians like in fbdsm """
        from math import sqrt
        from const import fwsig
        import functions as func

        im = isl.image-isl.islmean
        if img.opts.ini_method == 'curvature':
            im_pos = -1.0 * func.make_curvature_map(isl.image-isl.islmean)
            thr_pos = 0.0
        else:
            im_pos = im
            thr_pos = thr
        mask = isl.mask_active
        av = img.clipped_mean
        inipeak, iniposn, im1 = func.get_maxima(im, mask, thr_pos, isl.shape, beam, im_pos=im_pos)
        if len(inipeak) == 0:
          av, stdnew, maxv, maxp, minv, minp = func.arrstatmask(im, mask)
          inipeak = [maxv]; iniposn = [maxp]
        nmulsrc1 = len(iniposn)

        domore = True
        while domore:
          domore = False
          av, stdnew, maxv, maxp, minv, minp = func.arrstatmask(im1, mask)
          if stdnew > isl.rms and maxv >= thr and maxv >= isl.mean+2.0*isl.rms:
            domore = True
            x1, y1 = N.array(iniposn).transpose()
            dumr = N.sqrt((maxp[0]-x1)*(maxp[0]-x1)+(maxp[1]-y1)*(maxp[1]-y1))
            distbm = dumr/sqrt(beam[0]*beam[1]*fwsig*fwsig)
            if N.any((distbm < 0.5) + (dumr < 2.2)):
              domore = False
            if domore:
              iniposn.append(N.array(maxp)); inipeak.append(maxv)
              im1 = func.mclean(im1, maxp, beam)

        inipeak = N.array(inipeak); iniposn = N.array(iniposn)
        ind = list(N.argsort(inipeak)); ind.reverse()
        inipeak = inipeak[ind]
        iniposn = iniposn[ind]
        gaul = []
        for i in range(len(inipeak)):
          g = (float(inipeak[i]), int(iniposn[i][0]), int(iniposn[i][1])) + beam
          gaul.append(g)

        return gaul, nmulsrc1, len(inipeak)
Пример #3
0
    def inigaus_nobeam(self, isl, thr, beam, img):
        """ To get initial guesses when the source sizes are very different
        from the beam, and can also be elongated. Mainly in the context of
        a-trous transform images. Need to arrive at a good guess of the sizes
        and hence need to partition the image around the maxima first. Tried the
        IFT watershed algo but with markers, it segments the island only around
        the minima and not the whole island. Cant find a good weighting scheme
        for tesselation either. Hence will try this :

        Calculate number of maxima. If one, then take moment as initial
        guess. If more than one, then moment of whole island is one of the
        guesses if mom1 is within n pixels of one of the maxima. Else dont take
        whole island moment. Instead, find minima on lines connecting all maxima
        and use geometric mean of all minima of a peak as the size of that peak.
        """
        from math import sqrt
        from const import fwsig
        import scipy.ndimage as nd
        import functions as func

        im = isl.image-isl.islmean
        if img.opts.ini_method == 'curvature':
            im_pos = -1.0 * func.make_curvature_map(isl.image-isl.islmean)
            thr_pos = 0.0
        else:
            im_pos = im
            thr_pos = -1e9
        mask = isl.mask_active
        av = img.clipped_mean
        inipeak, iniposn, im1 = func.get_maxima(im, mask, thr_pos, isl.shape, beam, im_pos=im_pos)
        npeak = len(iniposn)
        gaul = []

        av, stdnew, maxv, maxp, minv, minp = func.arrstatmask(im, mask)
        mom = func.momanalmask_gaus(isl.image-isl.islmean, isl.mask_active, 0, 1.0, True)
        if npeak <= 1:
          g = (float(maxv), int(round(mom[1])), int(round(mom[2])), mom[3]/fwsig, \
                                  mom[4]/fwsig, mom[5])
          gaul.append(g)

        if npeak > 1:                   # markers start from 1=background, watershed starts from 1=background
          watershed, markers = func.watershed(im, mask=isl.mask_active)
          nshed = N.max(markers)-1      # excluding background
          xm, ym = N.transpose([N.where(markers==i) for i in range(1,nshed+2)])[0]
          coords = [c for c in N.transpose([xm,ym])[1:]]
          alldists = [func.dist_2pt(c1, c2) for c1 in coords for c2 in coords if N.any(c1!=c2)]  # has double
          meandist = N.mean(alldists)    # mean dist between all pairs of markers
          compact = []; invmask = []
          for ished in range(nshed):
            shedmask = N.where(watershed==ished+2, False, True) + isl.mask_active # good unmasked pixels = 0
            imm = nd.binary_dilation(~shedmask, N.ones((3,3), int))
            xbad, ybad = N.where((imm==1)*(im>im[xm[ished+1], ym[ished+1]]))
            imm[xbad, ybad] = 0
            invmask.append(imm); x, y = N.where(imm); xcen, ycen = N.mean(x), N.mean(y) # good pixels are now = 1
            dist = func.dist_2pt([xcen, ycen], [xm[ished+1], ym[ished+1]])
            if dist < max(3.0, meandist/4.0):
              compact.append(True)  # if not compact, break source + diffuse
            else:
              compact.append(False)
          if not N.all(compact):
           avsize = []
           ind = N.where(compact)[0]
           for i in ind: avsize.append(N.sum(invmask[i]))
           avsize = sqrt(N.mean(N.array(avsize)))
           for i in range(len(compact)):
             if not compact[i]:                         # make them all compact
               newmask = N.zeros(imm.shape, bool)
               newmask[max(0,xm[i+1]-avsize/2):min(im.shape[0],xm[i+1]+avsize/2), \
                       max(0,ym[i+1]-avsize/2):min(im.shape[1],ym[i+1]+avsize/2)] = True
               invmask[i] = invmask[i]*newmask
          resid = N.zeros(im.shape, dtype=N.float32)                    # approx fit all compact ones
          for i in range(nshed):
            mask1 = ~invmask[i]
            size = sqrt(N.sum(invmask))/fwsig
            xf, yf = coords[i][0], coords[i][1]
            p_ini = [im[xf, yf], xf, yf, size, size, 0.0]
            x, y = N.indices(im.shape)
            p, success = func.fit_gaus2d(im*invmask[i], p_ini, x, y)
            resid = resid + func.gaus_2d(p, x, y)
            gaul.append(p)
          resid = im - resid
          if not N.all(compact):                        # just add one gaussian to fit whole unmasked island
            maxv = N.max(resid)                         # assuming resid has only diffuse emission. can be false
            x, y = N.where(~isl.mask_active); xcen = N.mean(x); ycen = N.mean(y)
            invm = ~isl.mask_active
            #bound = invm - nd.grey_erosion(invm, footprint = N.ones((3,3), int)) # better to use bound for ellipse fitting
            mom = func.momanalmask_gaus(invm, N.zeros(invm.shape, dtype=N.int16), 0, 1.0, True)
            g = (maxv, xcen, ycen, mom[3]/fwsig, mom[4]/fwsig, mom[5]-90.)
            gaul.append(g)
            coords.append([xcen, ycen])

        return gaul