Пример #1
0
def find_ellipses_display( dfore , bw ):
    """Fits ellipses to connected components in image.
    Returns an EllipseList, each member representing
    the x,y position and orientation of a single fly."""

    # check number of above-threshold pixels
    rows, cols = num.nonzero( bw )

    # find connected components
    (L,ncc) = meas.label(bw)
    
    # make sure there aren't too many connected components
    if ncc > params.max_n_clusters:
        warn( "too many objects found (>%d); truncating object search"%(params.max_n_clusters) )
        # for now, just throw out the last connected components.
        # in the future, we can sort based on area and keep those
        # with the largest area. hopefully, this never actually
        # happens.
        ncc = params.max_n_clusters
        L[L >= ncc] = 0
        
    # fit ellipses
    ellipses = est.weightedregionprops(L,ncc,dfore)

    # check if any are small, and [try to] fix those
    (issmall,didlowerthresh,didmerge,diddelete) = est.fixsmalldisplay(ellipses,L,dfore)

    # check if any are large, and [try to] fix those
    (islarge,didsplit) = est.fixlargedisplay(ellipses,L,dfore)
    
    return (ellipses,issmall,islarge,didlowerthresh,didmerge,diddelete,didsplit)
Пример #2
0
def find_ellipses(dfore, L, ncc, dofix=True):
    """Fits ellipses to connected components in image.
    Returns an EllipseList, each member representing
    the x,y position and orientation of a single fly."""

    if DEBUG_TRACKINGSETTINGS:
        print 'ncc = ' + str(ncc) + ', max(L) = ' + str(
            num.max(L)) + ', nnz(L) = ' + str(
                num.flatnonzero(L).shape) + ', sum(dfore) = ' + str(
                    num.sum(num.sum(dfore)))

    # fit ellipses
    ellipses = est.weightedregionprops(L, ncc, dfore)

    if DEBUG_TRACKINGSETTINGS:
        print 'initial list of ellipses:'
        for i in range(len(ellipses)):
            print 'ellipse[%d] = ' % i + str(ellipses[i])

    #print 'time to fit ellipses: %.2f'%(time.time() - last_time)

    if dofix:

        # store current time to find out how long fitting ellipses takes
        last_time = time.time()

        # check if any are small, and [try to] fix those
        est.fixsmall(ellipses, L, dfore)

        #print 'after fixing small, ellipses = '
        #for i in range(len(ellipses)):
        #    print 'ellipse[%d] = '%i + str(ellipses[i])

        #print 'time to fix small ellipses: %.2f'%(time.time() - last_time)

        last_time = time.time()

        # check if any are large, and [try to] fix those
        est.fixlarge(ellipses, L, dfore)

        if DEBUG_TRACKINGSETTINGS:
            print 'after fixing large, ellipses ='
            for i in range(len(ellipses)):
                print 'ellipse[%d] = ' % i + str(ellipses[i])

        #print 'time to fix large ellipses: %.2f'%(time.time() - last_time)

        #est.deleteellipses(ellipses)

    return ellipses
Пример #3
0
def find_ellipses(dfore, L, ncc, dofix=True):
    """Fits ellipses to connected components in image.
    Returns an EllipseList, each member representing
    the x,y position and orientation of a single fly."""

    if DEBUG_TRACKINGSETTINGS:
        print "ncc = " + str(ncc) + ", max(L) = " + str(num.max(L)) + ", nnz(L) = " + str(
            num.flatnonzero(L).shape
        ) + ", sum(dfore) = " + str(num.sum(num.sum(dfore)))

    # fit ellipses
    ellipses = est.weightedregionprops(L, ncc, dfore)

    if DEBUG_TRACKINGSETTINGS:
        print "initial list of ellipses:"
        for i in range(len(ellipses)):
            print "ellipse[%d] = " % i + str(ellipses[i])

    # print 'time to fit ellipses: %.2f'%(time.time() - last_time)

    if dofix:

        # store current time to find out how long fitting ellipses takes
        last_time = time.time()

        # check if any are small, and [try to] fix those
        est.fixsmall(ellipses, L, dfore)

        # print 'after fixing small, ellipses = '
        # for i in range(len(ellipses)):
        #    print 'ellipse[%d] = '%i + str(ellipses[i])

        # print 'time to fix small ellipses: %.2f'%(time.time() - last_time)

        last_time = time.time()

        # check if any are large, and [try to] fix those
        est.fixlarge(ellipses, L, dfore)

        if DEBUG_TRACKINGSETTINGS:
            print "after fixing large, ellipses ="
            for i in range(len(ellipses)):
                print "ellipse[%d] = " % i + str(ellipses[i])

        # print 'time to fix large ellipses: %.2f'%(time.time() - last_time)

        # est.deleteellipses(ellipses)

    return ellipses
Пример #4
0
def find_ellipses_display( dfore , L, ncc ):
    """Fits ellipses to connected components in image.
    Returns an EllipseList, each member representing
    the x,y position and orientation of a single fly."""

    # fit ellipses
    if DEBUG_TRACKINGSETTINGS: print 'ncc = ' + str(ncc) + ', max(L) = ' + str(num.max(L)) + ', nnz(L) = ' + str(num.flatnonzero(L).shape) + ', sum(dfore) = ' + str(num.sum(num.sum(dfore)))
    ellipses = est.weightedregionprops(L,ncc,dfore)

    ellipsescopy = []
    for ell in ellipses:
        ellipsescopy.append(ell.copy())

    if DEBUG_TRACKINGSETTINGS: print 'before fixing, ellipses = ' + str(ellipses) + ', len = ' + str(len(ellipses))
    if DEBUG_TRACKINGSETTINGS:
        areasum = 0
        for ell in ellipses:
            areasum += ell.area
        print 'summed area of ellipses = ' + str(areasum)

    # check if any are small, and [try to] fix those
    (ellsmall,didlowerthresh,didmerge,diddelete) = est.fixsmalldisplay(ellipses,L,dfore)

    if DEBUG_TRACKINGSETTINGS: print 'after fixing small ellipses, ellipses = ' + str(ellipses) + ', len = ' + str(len(ellipses))
    if DEBUG_TRACKINGSETTINGS: print 'ellsmall = ' + str(ellsmall)
    if DEBUG_TRACKINGSETTINGS: print 'didlowerthresh = ' + str(didlowerthresh)
    if DEBUG_TRACKINGSETTINGS: print 'didmerge = ' + str(didmerge)
    if DEBUG_TRACKINGSETTINGS: print 'diddelete = ' + str(diddelete)

    # check if any are large, and [try to] fix those
    (elllarge,didsplit) = est.fixlargedisplay(ellipses,L,dfore)

    if DEBUG_TRACKINGSETTINGS: print 'after fixing large ellipses, ellipses = ' + str(ellipses) + ', len = ' + str(len(ellipses))
    if DEBUG_TRACKINGSETTINGS: print 'elllarge = ' + str(elllarge)
    if DEBUG_TRACKINGSETTINGS: print 'didsplit = ' + str(didsplit)
    if DEBUG_TRACKINGSETTINGS: print 'ellsmall = ' + str(ellsmall)
    if DEBUG_TRACKINGSETTINGS: print 'didlowerthresh = ' + str(didlowerthresh)
    if DEBUG_TRACKINGSETTINGS: print 'didmerge = ' + str(didmerge)
    if DEBUG_TRACKINGSETTINGS: print 'diddelete = ' + str(diddelete)    

    if DEBUG_TRACKINGSETTINGS: print 'returning ellipsescopy = ' + str(ellipsescopy) + ', len = ' + str(len(ellipsescopy))
    if DEBUG_TRACKINGSETTINGS:
        areasum = 0
        for ell in ellipsescopy:
            areasum += ell.area
        print 'summed area of ellipses = ' + str(areasum)
    
    return (ellipsescopy,ellsmall,elllarge,didlowerthresh,didmerge,diddelete,didsplit)
Пример #5
0
def find_ellipses_display( dfore , L, ncc ):
    """Fits ellipses to connected components in image.
    Returns an EllipseList, each member representing
    the x,y position and orientation of a single fly."""

    # fit ellipses
    if DEBUG_TRACKINGSETTINGS: print 'ncc = ' + str(ncc) + ', max(L) = ' + str(num.max(L)) + ', nnz(L) = ' + str(num.flatnonzero(L).shape) + ', sum(dfore) = ' + str(num.sum(num.sum(dfore)))
    ellipses = est.weightedregionprops(L,ncc,dfore)

    ellipsescopy = []
    for ell in ellipses:
        ellipsescopy.append(ell.copy())

    if DEBUG_TRACKINGSETTINGS: print 'before fixing, ellipses = ' + str(ellipses) + ', len = ' + str(len(ellipses))
    if DEBUG_TRACKINGSETTINGS:
        areasum = 0
        for ell in ellipses:
            areasum += ell.area
        print 'summed area of ellipses = ' + str(areasum)

    # check if any are small, and [try to] fix those
    (ellsmall,didlowerthresh,didmerge,diddelete) = est.fixsmalldisplay(ellipses,L,dfore)

    if DEBUG_TRACKINGSETTINGS: print 'after fixing small ellipses, ellipses = ' + str(ellipses) + ', len = ' + str(len(ellipses))
    if DEBUG_TRACKINGSETTINGS: print 'ellsmall = ' + str(ellsmall)
    if DEBUG_TRACKINGSETTINGS: print 'didlowerthresh = ' + str(didlowerthresh)
    if DEBUG_TRACKINGSETTINGS: print 'didmerge = ' + str(didmerge)
    if DEBUG_TRACKINGSETTINGS: print 'diddelete = ' + str(diddelete)

    # check if any are large, and [try to] fix those
    (elllarge,didsplit) = est.fixlargedisplay(ellipses,L,dfore)

    if DEBUG_TRACKINGSETTINGS: print 'after fixing large ellipses, ellipses = ' + str(ellipses) + ', len = ' + str(len(ellipses))
    if DEBUG_TRACKINGSETTINGS: print 'elllarge = ' + str(elllarge)
    if DEBUG_TRACKINGSETTINGS: print 'didsplit = ' + str(didsplit)
    if DEBUG_TRACKINGSETTINGS: print 'ellsmall = ' + str(ellsmall)
    if DEBUG_TRACKINGSETTINGS: print 'didlowerthresh = ' + str(didlowerthresh)
    if DEBUG_TRACKINGSETTINGS: print 'didmerge = ' + str(didmerge)
    if DEBUG_TRACKINGSETTINGS: print 'diddelete = ' + str(diddelete)    

    if DEBUG_TRACKINGSETTINGS: print 'returning ellipsescopy = ' + str(ellipsescopy) + ', len = ' + str(len(ellipsescopy))
    if DEBUG_TRACKINGSETTINGS:
        areasum = 0
        for ell in ellipsescopy:
            areasum += ell.area
        print 'summed area of ellipses = ' + str(areasum)
    
    return (ellipsescopy,ellsmall,elllarge,didlowerthresh,didmerge,diddelete,didsplit)
Пример #6
0
def find_ellipses2( dfore , L, ncc, dofix=True ):
    """Fits ellipses to connected components in image.
    Returns an EllipseList, each member representing
    the x,y position and orientation of a single fly."""
        
    # fit ellipses
    ellipses = est.weightedregionprops(L,ncc,dfore)

    if dofix:

        # check if any are small, and [try to] fix those
        est.fixsmall(ellipses,L,dfore)

        # check if any are large, and [try to] fix those
        est.fixlarge(ellipses,L,dfore)

    return (ellipses,L)
Пример #7
0
def find_ellipses2(dfore, L, ncc, dofix=True):
    """Fits ellipses to connected components in image.
    Returns an EllipseList, each member representing
    the x,y position and orientation of a single fly."""

    # fit ellipses
    ellipses = est.weightedregionprops(L, ncc, dfore)

    if dofix:

        # check if any are small, and [try to] fix those
        est.fixsmall(ellipses, L, dfore)

        # check if any are large, and [try to] fix those
        est.fixlarge(ellipses, L, dfore)

    return (ellipses, L)
Пример #8
0
def est_shape( bg ):
    """Estimate fly shape from a bunch of sample frames."""

    # which frames will we estimate size from
    framelist = num.round( num.linspace( 0, params.n_frames-1,
                                         params.n_frames_size ) ).astype( num.int )

    ellipses = []

    for frame in framelist:
        # get background-subtracted image
        (dfore,bw) = bg.sub_bg( frame )
        (L,ncc) = meas.label(bw)
        ellipsescurr = est.weightedregionprops(L,ncc,dfore)
        ellipses += ellipsescurr

    n_ell = len(ellipses)

    if n_ell == 0: # probably threshold is too low
        return

    # grab ellipse info
    major = num.zeros( (n_ell) )
    minor = num.zeros( (n_ell) )
    area = num.zeros( (n_ell) )
    for i in range(len(ellipses)):
        major[i] = ellipses[i].size.height
        minor[i] = ellipses[i].size.width
        area[i] = ellipses[i].area

    eccen = minor / major
    
    # compute the median
    iseven = num.mod(n_ell,2) == 0
    middle1 = num.floor(n_ell/2)
    middle2 = middle1 - 1
    major.sort()
    minor.sort()
    area.sort()
    eccen.sort()
    mu_maj = major[middle1]
    mu_min = minor[middle1]
    mu_area = area[middle1]
    mu_ecc = eccen[middle1]
    if iseven:
        mu_maj = (mu_maj + major[middle2])/2.
        mu_min = (mu_min + minor[middle2])/2.
        mu_area = (mu_area + area[middle2])/2.
        mu_ecc = (mu_ecc + eccen[middle2])/2.

    # compute absolute difference
    major = num.abs(major - mu_maj)
    minor = num.abs(minor - mu_min)
    area = num.abs(area - mu_area)
    eccen = num.abs(eccen - mu_ecc)

    # compute the median absolute difference
    major.sort()
    minor.sort()
    area.sort()
    eccen.sort()

    sigma_maj = major[middle1]
    sigma_min = minor[middle1]
    sigma_area = area[middle1]
    sigma_ecc = eccen[middle1]
    if iseven:
        sigma_maj = (sigma_maj + major[middle2])/2.
        sigma_min = (sigma_min + minor[middle2])/2.
        sigma_area = (sigma_area + area[middle2])/2.
        sigma_ecc = (sigma_ecc + eccen[middle2])/2.

    # estimate standard deviation assuming a Gaussian distribution
    # from the fact that half the data falls within mad
    # MADTOSTDFACTOR = 1./norminv(.75)
    MADTOSTDFACTOR = 1.482602
    sigma_maj *= MADTOSTDFACTOR
    sigma_min *= MADTOSTDFACTOR
    sigma_area *= MADTOSTDFACTOR
    sigma_ecc *= MADTOSTDFACTOR

    # fit Gaussians to the minor, major, eccentricity, and area
    #mu_maj = major.mean()
    #sigma_maj = major.std()
    #mu_min = minor.mean()
    #sigma_min = minor.std()
    #mu_ecc = eccen.mean()
    #sigma_ecc = eccen.std()
    #mu_area = area.mean()
    #sigma_area = area.std()

    # threshold at N standard deviations
    params.maxshape.major = mu_maj + params.n_std_thresh*sigma_maj
    params.minshape.major = mu_maj - params.n_std_thresh*sigma_maj
    if params.minshape.major < 0: params.minshape.major = 0
    params.maxshape.minor = mu_min + params.n_std_thresh*sigma_min
    params.minshape.minor = mu_min - params.n_std_thresh*sigma_min
    if params.minshape.minor < 0: params.minshape.minor = 0
    params.maxshape.ecc = mu_ecc + params.n_std_thresh*sigma_ecc
    params.minshape.ecc = mu_ecc - params.n_std_thresh*sigma_ecc
    if params.minshape.ecc < 0: params.minshape.ecc = 0
    if params.maxshape.ecc > 1: params.maxshape.ecc = 1
    params.maxshape.area = mu_area + params.n_std_thresh*sigma_area
    params.minshape.area = mu_area - params.n_std_thresh*sigma_area
    if params.minshape.area < 0: params.minshape.area = 0

    params.meanshape.major = mu_maj
    params.meanshape.minor = mu_min
    params.meanshape.ecc = mu_ecc
    params.meanshape.area = mu_area

    params.have_computed_shape = True
Пример #9
0
def find_ellipses( dfore , bw, dofix=True ):
    """Fits ellipses to connected components in image.
    Returns an EllipseList, each member representing
    the x,y position and orientation of a single fly."""

    # check number of above-threshold pixels
    rows, cols = num.nonzero( bw )

    # store current time to find out how long computing ccs takes
    last_time = time.time()

    # find connected components
    (L,ncc) = meas.label(bw)

    # make sure there aren't too many connected components
    if ncc > params.max_n_clusters:
        warn( "too many objects found (>%d); truncating object search"%(params.max_n_clusters) )
        # for now, just throw out the last connected components.
        # in the future, we can sort based on area and keep those
        # with the largest area. hopefully, this never actually
        # happens.
        ncc = params.max_n_clusters
        L[L >= ncc] = 0

    #print 'time to compute connected components: %.2f'%(time.time()-last_time)

    # store current time to find out how long fitting ellipses takes
    last_time = time.time()
        
    # fit ellipses
    ellipses = est.weightedregionprops(L,ncc,dfore)

    #print 'initial list of ellipses:'
    #for i in range(len(ellipses)):
    #    print 'ellipse[%d] = '%i + str(ellipses[i])

    #print 'time to fit ellipses: %.2f'%(time.time() - last_time)

    if dofix:

        # store current time to find out how long fitting ellipses takes
        last_time = time.time()

        # check if any are small, and [try to] fix those
        est.fixsmall(ellipses,L,dfore)

        #print 'after fixing small, ellipses = '
        #for i in range(len(ellipses)):
        #    print 'ellipse[%d] = '%i + str(ellipses[i])

        #print 'time to fix small ellipses: %.2f'%(time.time() - last_time)

        last_time = time.time()

        # check if any are large, and [try to] fix those
        est.fixlarge(ellipses,L,dfore)

        #print 'after fixing large, ellipses = \n'
        #for i in range(len(ellipses)):
        #    print 'ellipse[%d] = '%i + str(ellipses[i])

        #print 'time to fix large ellipses: %.2f'%(time.time() - last_time)

        #est.deleteellipses(ellipses)

    return ellipses
Пример #10
0
def est_shape( bg, tracking_settings_frame=None ):
    """Estimate fly shape from a bunch of sample frames."""

    interactive = params.interactive and \
                  tracking_settings_frame is not None and \
                  (not params.batch_executing)
    if interactive:
        progressbar = \
            wx.ProgressDialog('Computing Shape Model',
                              'Detecting observations in %d frames to estimate median and median absolute deviation of shape parameters'%params.n_frames_size,
                              params.n_frames_size,
                              tracking_settings_frame,
                              wx.PD_APP_MODAL|wx.PD_AUTO_HIDE|wx.PD_CAN_ABORT|wx.PD_REMAINING_TIME)

    # which frames will we estimate size from
    framelist = num.round( num.linspace( 0, params.n_frames-1,
                                         params.n_frames_size ) ).astype( num.int )

    ellipses = []

    i = 0
    for frame in framelist:
        # get background-subtracted image
        if interactive:
            (keepgoing,skip) = progressbar.Update(value=i,newmsg='Detecting observations in frame %d (%d / %d)'%(frame,i,params.n_frames_size))
            i+=1
            if not keepgoing:
                progressbar.Destroy()
                return False
        try:
            (dfore,bw,L,ncc) = bg.sub_bg( frame )
        except:
            continue
        ellipsescurr = est.weightedregionprops(L,ncc,dfore)
        ellipses += ellipsescurr

    n_ell = len(ellipses)

    if n_ell == 0: # probably threshold is too low
        return False

    # grab ellipse info
    major = num.empty( (n_ell) )
    minor = num.empty( (n_ell) )
    area = num.empty( (n_ell) )
    for i in range(len(ellipses)):
        major[i] = ellipses[i].size.height
        minor[i] = ellipses[i].size.width
        area[i] = ellipses[i].area

    eccen = minor / major
    
    # compute the median
    iseven = num.mod(n_ell,2) == 0
    middle1 = num.floor(n_ell/2)
    middle2 = middle1 - 1
    major.sort()
    minor.sort()
    area.sort()
    eccen.sort()
    mu_maj = major[middle1]
    mu_min = minor[middle1]
    mu_area = area[middle1]
    mu_ecc = eccen[middle1]
    if iseven:
        mu_maj = (mu_maj + major[middle2])/2.
        mu_min = (mu_min + minor[middle2])/2.
        mu_area = (mu_area + area[middle2])/2.
        mu_ecc = (mu_ecc + eccen[middle2])/2.

    # compute absolute difference
    major = num.abs(major - mu_maj)
    minor = num.abs(minor - mu_min)
    area = num.abs(area - mu_area)
    eccen = num.abs(eccen - mu_ecc)

    # compute the median absolute difference
    major.sort()
    minor.sort()
    area.sort()
    eccen.sort()

    sigma_maj = major[middle1]
    sigma_min = minor[middle1]
    sigma_area = area[middle1]
    sigma_ecc = eccen[middle1]
    if iseven:
        sigma_maj = (sigma_maj + major[middle2])/2.
        sigma_min = (sigma_min + minor[middle2])/2.
        sigma_area = (sigma_area + area[middle2])/2.
        sigma_ecc = (sigma_ecc + eccen[middle2])/2.

    # estimate standard deviation assuming a Gaussian distribution
    # from the fact that half the data falls within mad
    # MADTOSTDFACTOR = 1./norminv(.75)
    MADTOSTDFACTOR = 1.482602
    sigma_maj *= MADTOSTDFACTOR
    sigma_min *= MADTOSTDFACTOR
    sigma_area *= MADTOSTDFACTOR
    sigma_ecc *= MADTOSTDFACTOR

    # fit Gaussians to the minor, major, eccentricity, and area
    #mu_maj = major.mean()
    #sigma_maj = major.std()
    #mu_min = minor.mean()
    #sigma_min = minor.std()
    #mu_ecc = eccen.mean()
    #sigma_ecc = eccen.std()
    #mu_area = area.mean()
    #sigma_area = area.std()

    # threshold at N standard deviations
    params.maxshape.major = mu_maj + params.n_std_thresh*sigma_maj
    params.minshape.major = mu_maj - params.n_std_thresh*sigma_maj
    if params.minshape.major < 0: params.minshape.major = 0
    params.maxshape.minor = mu_min + params.n_std_thresh*sigma_min
    params.minshape.minor = mu_min - params.n_std_thresh*sigma_min
    if params.minshape.minor < 0: params.minshape.minor = 0
    params.maxshape.ecc = mu_ecc + params.n_std_thresh*sigma_ecc
    params.minshape.ecc = mu_ecc - params.n_std_thresh*sigma_ecc
    if params.minshape.ecc < 0: params.minshape.ecc = 0
    if params.maxshape.ecc > 1: params.maxshape.ecc = 1
    params.maxshape.area = mu_area + params.n_std_thresh*sigma_area
    params.minshape.area = mu_area - params.n_std_thresh*sigma_area
    if params.minshape.area < 0: params.minshape.area = 0

    params.meanshape.major = mu_maj
    params.meanshape.minor = mu_min
    params.meanshape.ecc = mu_ecc
    params.meanshape.area = mu_area

    params.have_computed_shape = True

    if interactive:
        progressbar.Destroy()
    
    return True
Пример #11
0
def est_shape(bg, tracking_settings_frame=None):
    """Estimate fly shape from a bunch of sample frames."""

    interactive = params.feedback_enabled and tracking_settings_frame is not None
    if interactive:
        progressbar = \
            wx.ProgressDialog('Computing Shape Model',
                              'Detecting observations in %d frames to estimate median and median absolute deviation of shape parameters'%params.n_frames_size,
                              params.n_frames_size,
                              tracking_settings_frame,
                              wx.PD_APP_MODAL|wx.PD_AUTO_HIDE|wx.PD_CAN_ABORT|wx.PD_REMAINING_TIME)

    # which frames will we estimate size from
    framelist = num.round(
        num.linspace(0, params.n_frames - 1,
                     params.n_frames_size)).astype(num.int)

    ellipses = []

    i = 0
    for frame in framelist:
        # get background-subtracted image
        if interactive:
            (keepgoing, skip) = progressbar.Update(
                value=i,
                newmsg='Detecting observations in frame %d (%d / %d)' %
                (frame, i, params.n_frames_size))
            i += 1
            if not keepgoing:
                progressbar.Destroy()
                return False
        try:
            (dfore, bw, L, ncc) = bg.sub_bg(frame)
        except:
            continue
        ellipsescurr = est.weightedregionprops(L, ncc, dfore)
        ellipses += ellipsescurr

    n_ell = len(ellipses)

    if n_ell == 0:  # probably threshold is too low
        return False

    # grab ellipse info
    major = num.empty((n_ell))
    minor = num.empty((n_ell))
    area = num.empty((n_ell))
    for i in range(len(ellipses)):
        major[i] = ellipses[i].size.height
        minor[i] = ellipses[i].size.width
        area[i] = ellipses[i].area

    eccen = minor / major

    # compute the median
    iseven = num.mod(n_ell, 2) == 0
    middle1 = num.floor(n_ell / 2)
    middle2 = middle1 - 1
    major.sort()
    minor.sort()
    area.sort()
    eccen.sort()
    mu_maj = major[middle1]
    mu_min = minor[middle1]
    mu_area = area[middle1]
    mu_ecc = eccen[middle1]
    if iseven:
        mu_maj = (mu_maj + major[middle2]) / 2.
        mu_min = (mu_min + minor[middle2]) / 2.
        mu_area = (mu_area + area[middle2]) / 2.
        mu_ecc = (mu_ecc + eccen[middle2]) / 2.

    # compute absolute difference
    major = num.abs(major - mu_maj)
    minor = num.abs(minor - mu_min)
    area = num.abs(area - mu_area)
    eccen = num.abs(eccen - mu_ecc)

    # compute the median absolute difference
    major.sort()
    minor.sort()
    area.sort()
    eccen.sort()

    sigma_maj = major[middle1]
    sigma_min = minor[middle1]
    sigma_area = area[middle1]
    sigma_ecc = eccen[middle1]
    if iseven:
        sigma_maj = (sigma_maj + major[middle2]) / 2.
        sigma_min = (sigma_min + minor[middle2]) / 2.
        sigma_area = (sigma_area + area[middle2]) / 2.
        sigma_ecc = (sigma_ecc + eccen[middle2]) / 2.

    # estimate standard deviation assuming a Gaussian distribution
    # from the fact that half the data falls within mad
    # MADTOSTDFACTOR = 1./norminv(.75)
    MADTOSTDFACTOR = 1.482602
    sigma_maj *= MADTOSTDFACTOR
    sigma_min *= MADTOSTDFACTOR
    sigma_area *= MADTOSTDFACTOR
    sigma_ecc *= MADTOSTDFACTOR

    # fit Gaussians to the minor, major, eccentricity, and area
    #mu_maj = major.mean()
    #sigma_maj = major.std()
    #mu_min = minor.mean()
    #sigma_min = minor.std()
    #mu_ecc = eccen.mean()
    #sigma_ecc = eccen.std()
    #mu_area = area.mean()
    #sigma_area = area.std()

    # threshold at N standard deviations
    params.maxshape.major = mu_maj + params.n_std_thresh * sigma_maj
    params.minshape.major = mu_maj - params.n_std_thresh * sigma_maj
    if params.minshape.major < 0: params.minshape.major = 0
    params.maxshape.minor = mu_min + params.n_std_thresh * sigma_min
    params.minshape.minor = mu_min - params.n_std_thresh * sigma_min
    if params.minshape.minor < 0: params.minshape.minor = 0
    params.maxshape.ecc = mu_ecc + params.n_std_thresh * sigma_ecc
    params.minshape.ecc = mu_ecc - params.n_std_thresh * sigma_ecc
    if params.minshape.ecc < 0: params.minshape.ecc = 0
    if params.maxshape.ecc > 1: params.maxshape.ecc = 1
    params.maxshape.area = mu_area + params.n_std_thresh * sigma_area
    params.minshape.area = mu_area - params.n_std_thresh * sigma_area
    if params.minshape.area < 0: params.minshape.area = 0

    params.meanshape.major = mu_maj
    params.meanshape.minor = mu_min
    params.meanshape.ecc = mu_ecc
    params.meanshape.area = mu_area

    if 'progressbar' in locals():
        progressbar.Destroy()

    return True
Пример #12
0
def find_ellipses(dfore, L, ncc, dofix=True, return_vals=False):
    """Fits ellipses to connected components in image.
    Returns a list of ellipses, each item representing
    the x,y position and orientation of a single fly."""
    if DEBUG_TRACKINGSETTINGS:
        print 'ncc = ' + str(ncc) + ', max(L) = ' + str(
            num.max(L)) + ', nnz(L) = ' + str(
                num.flatnonzero(L).shape) + ', sum(dfore) = ' + str(
                    num.sum(num.sum(dfore)))

    # fit ellipses
    ellipses = est.weightedregionprops(L, ncc, dfore)

    if return_vals:
        ellipsescopy = [ell.copy() for ell in ellipses]

    if DEBUG_TRACKINGSETTINGS:
        print 'initial list of ellipses:'
        for i in range(len(ellipses)):
            print 'ellipse[%d] = ' % i + str(ellipses[i])

    if dofix or return_vals:
        # check if any are small, and [try to] fix those
        (ellsmall, didlowerthresh, didmerge,
         diddelete) = est.fixsmall(ellipses, L, dfore, return_vals)
        # "ellipses" are fixed in place

        # check if any are large, and [try to] fix those
        (elllarge, didsplit) = est.fixlarge(ellipses, L, dfore, return_vals)

        if DEBUG_TRACKINGSETTINGS:
            print 'after fixing large, ellipses ='
            for i in range(len(ellipses)):
                print 'ellipse[%d] = ' % i + str(ellipses[i])

        if params.enforce_minmax_shape:
            # enforce shape parameters on remaining ellipses
            for ell in ellipses:
                if ell.area() < params.minshape.area or \
                       ell.area() > params.maxshape.area or \
                       ell.size.height < params.minshape.major or \
                       ell.size.height > params.maxshape.major or \
                       ell.size.width < params.minshape.minor or \
                       ell.size.width > params.maxshape.minor or \
                       ell.eccentricity() < params.minshape.ecc or \
                       ell.eccentricity() > params.maxshape.ecc:
                    # compare ell.eccentricity() to params.minshape.ecc because
                    # the .ecc was calculated from the distribution of eccentricity(),
                    # whereas params.minshape.eccentricity() would just be the
                    # eccentricity of params.minshape alone
                    if DEBUG_TRACKINGSETTINGS and False:
                        print params.minshape.area, ell.area(
                        ), params.maxshape.area, (
                            ell.area() < params.minshape.area
                            or ell.area() > params.maxshape.area)
                        print params.minshape.major, ell.size.height, params.maxshape.major, (
                            ell.size.height < params.minshape.major
                            or ell.size.height > params.maxshape.major)
                        print params.minshape.minor, ell.size.width, params.maxshape.minor, (
                            ell.size.width < params.minshape.minor
                            or ell.size.width > params.maxshape.minor)
                        print params.minshape.ecc, ell.eccentricity(
                        ), params.maxshape.ecc, (
                            ell.eccentricity() < params.minshape.ecc
                            or ell.eccentricity() > params.maxshape.ecc)

                    ell.size.height = 0
            est.deleteellipses(ellipses, L)

            if DEBUG_TRACKINGSETTINGS:
                print "minshape:", params.minshape
                print "maxshape:", params.maxshape
                print 'after enforcing min/max shapes, ellipses ='
                for i in range(len(ellipses)):
                    print 'ellipse[%d] = ' % i + str(ellipses[i])

    if return_vals:
        return (ellipsescopy, ellsmall, elllarge, didlowerthresh, didmerge,
                diddelete, didsplit)
    else:
        return ellipses