Esempio n. 1
0
def regionProps(mask, image=None):
    """Calculates some basic properties of ROIs in a mask.

    Properties calculated:  centroids, boxes, areas.  If the original image is passed in,
    this also calcluate the mean value in each region.

    Keys of returned dictionary:  'centroid', 'boundingBox', 'area', and optionally, 'meanIntensity'

    :param mask: a 2d labeled image
    :param image: an optional 2p numpy array, original image, for calculation of mean intensity values
    :returns: a dictionary of lists, each containing property values
    """

    if image is not None:
        if len(image.shape) >= 3:
            meanImage = np.mean(image, axis=2)
        else:
            meanImage = image

        min = meanImage.min()
        if min < 0:
            meanImage -= meanImage.min()

        means = pymorph.grain(meanImage,
                              labels=mask,
                              measurement='mean',
                              option='data')
    else:
        means = None

    numLabels = mask.max()
    centroids = pymorph.blob(mask, measurement='centroid', output='data')
    boxes = pymorph.blob(mask, measurement='boundingbox', output='data')
    area = pymorph.blob(mask, measurement='area', output='data')

    coms = []
    for i in range(1, numLabels + 1):
        coms.append(nd.measurements.center_of_mass(meanImage,
                                                   labels=mask == i))

    if means is not None:
        props = [{
            'meanIntensity': means[i],
            'centroid': centroids[i],
            'com': coms[i],
            'boundingBox': boxes[i],
            'area': area[i]
        } for i in range(numLabels)]
    else:
        props = [{
            'centroid': centroids[i],
            'com': coms[i],
            'boundingBox': boxes[i],
            'area': area[i]
        } for i in range(numLabels)]
    return props
def post_processing(image):
    image_post = image.copy()

    # get texte pixel
    illu = 255 * (np.sum(
        (image - [0, 0, 255])**2, axis=2) < 10).astype(np.uint8)
    # fill holes
    illu_out = binary_fill_holes(illu)
    image_post[illu_out > 0, :] = [0, 0, 255]

    # get illustration pixel
    illu = 255 * (np.sum(
        (image - [255, 0, 0])**2, axis=2) < 10).astype(np.uint8)
    # get bounding-box of connected components
    bbox = pymorph.blob(measure.label(illu), 'boundingbox', 'data')
    illu_out = illu.copy()
    # transform connected components into englobing rectangles
    for l in bbox:
        x1 = l[0]
        y1 = l[1]
        x2 = l[2]
        y2 = l[3]
        if ((y2 - y1) < image.shape[0] / 2) | ((x2 - x1) < image.shape[1] / 2):
            illu_out[y1:y2, x1:x2] = 255
    image_post[illu_out > 0, :] = [255, 0, 0]

    return image_post
Esempio n. 3
0
def post_processing(image):
    image_post = image.copy()

     # get texte pixel
    illu = 255*(np.sum((image -[0,0,255])**2,axis=2)<10).astype(np.uint8)
    # fill holes
    illu_out = binary_fill_holes(illu)
    image_post[illu_out>0,:] = [0,0,255]

   # get illustration pixel
    illu = 255*(np.sum((image -[255,0,0])**2,axis=2)<10).astype(np.uint8)
    # get bounding-box of connected components
    bbox = pymorph.blob(measure.label(illu),'boundingbox','data')
    illu_out = illu.copy()
    # transform connected components into englobing rectangles
    for l in bbox:
	x1 = l[0]
	y1 = l[1]
	x2 = l[2]
	y2 = l[3]
        if ((y2-y1)<image.shape[0]/2) | ((x2-x1)<image.shape[1]/2):
            illu_out[y1:y2,x1:x2]=255
    image_post[illu_out>0,:] = [255,0,0]

    return image_post
Esempio n. 4
0
    def corrMaskWithSourcePreConv(imageSeriesSmoothed, dilatedBinaryMask, sourceSmoothed):

        corrImage = np.zeros((imageSeries.shape[0], imageSeries.shape[1]))

        bounds = np.squeeze(pymorph.blob(dilatedMask, 'boundingbox', output='data'))
        for x in range(bounds[1], bounds[3]):
            for y in range(bounds[0], bounds[2]):
                if dilatedBinaryMask[x,y]>0:
                    corr = stats.pearsonr(sourceSmoothed[1:-1], imageSeriesSmoothed[x,y,:])[0]
                    corrImage[x,y] = corr
        return corrImage
def regionProps(mask, image=None):
    """Calculates some basic properties of ROIs in a mask.

    Properties calculated:  centroids, boxes, areas.  If the original image is passed in,
    this also calcluate the mean value in each region.

    Keys of returned dictionary:  'centroid', 'boundingBox', 'area', and optionally, 'meanIntensity'

    :param mask: a 2d labeled image
    :param image: an optional 2p numpy array, original image, for calculation of mean intensity values
    :returns: a dictionary of lists, each containing property values
    """

    if image is not None:
        if len(image.shape) >= 3:
            meanImage = np.mean(image, axis=2)
        else:
            meanImage = image

        min = meanImage.min()
        if min < 0:
            meanImage -= meanImage.min()

        means = pymorph.grain(meanImage, labels=mask, measurement='mean', option='data')
    else:
        means = None
        
    numLabels = mask.max()
    centroids = pymorph.blob(mask, measurement='centroid', output='data')
    boxes = pymorph.blob(mask, measurement='boundingbox', output='data')
    area = pymorph.blob(mask, measurement='area', output='data')

    coms = []
    for i in range(1, numLabels+1):
        coms.append(nd.measurements.center_of_mass(meanImage, labels=mask==i))

    if means is not None:
        props = [{'meanIntensity':means[i], 'centroid':centroids[i], 'com':coms[i], 'boundingBox':boxes[i], 'area':area[i]} for i in range(numLabels)]
    else:
        props = [{'centroid':centroids[i], 'com':coms[i], 'boundingBox':boxes[i], 'area':area[i]} for i in range(numLabels)]
    return props
Esempio n. 6
0
def test_blob():
    F = np.array([
            [0,1,1,0,0],
            [0,2,2,0,0],
            [0,3,3,3,0],
            [4,4,4,4,4],
            ])

    M = pymorph.blob(F, 'area', 'data')
    MI = pymorph.blob(F, 'area', 'image')

    assert np.all( M == np.array([2,2,3,5]))
    for m,i in zip(MI.ravel(), F.ravel()):
        if i == 0: assert m == 0
        else: assert m == M[i-1]

    B = pymorph.blob(F, 'boundingbox', 'data')
    BI = pymorph.blob(F, 'boundingbox')
    assert BI.max() == 1

    C = pymorph.blob(F, 'centroid')
    assert np.all(C.sum(1) == 1)
Esempio n. 7
0
def test_blob():
    F = np.array([
        [0, 1, 1, 0, 0],
        [0, 2, 2, 0, 0],
        [0, 3, 3, 3, 0],
        [4, 4, 4, 4, 4],
    ])

    M = pymorph.blob(F, 'area', 'data')
    MI = pymorph.blob(F, 'area', 'image')

    assert np.all(M == np.array([2, 2, 3, 5]))
    for m, i in zip(MI.ravel(), F.ravel()):
        if i == 0: assert m == 0
        else: assert m == M[i - 1]

    B = pymorph.blob(F, 'boundingbox', 'data')
    BI = pymorph.blob(F, 'boundingbox')
    assert BI.max() == 1

    C = pymorph.blob(F, 'centroid')
    assert np.all(C.sum(1) == 1)
def tracker(frames, event, thresh_amp, thresh_dis, blob_ext,
            direction='forward', plots=False, verbose=False):
    """
    Track the blob in a dynamic intervall forward or backward in time, as long
    as its amplitude is over a given threshold and the peak has detected less
    than a given threshold over consecutive frames.
    The maximum number of frames the blob is tracked for, is given by dim0 of
    frames

    Input:
        tau:        Maximum number of frames to track blob
        event:      ndarray, [I0, t0, R0, z0] Index of original feature to
                    track
        direction:  Traverse frames 'forward' or 'backward' in dimension 0
        thresh_amp: Threshold for amplitude decay relative to frame0
        thresh_dis: Threshold for blob movement relative to previous frame
        blob_ext:   Extend of the blob used for determining its average shape

    Returns:
        numframes:      Number of frames the blob was tracked
        xycom:          COM position of the blob in each frame
        amp:            Amplitude at COM in each frame
        fwhm_rad_idx:   Indices that mark left and right FWHM of the blob
        fwhm_pol_idx:   Indices that mark the lower and upper FWHM of the blob
        blob:           Array that stores the blob extend
    """
    if (verbose is True):
        print 'Called tracker with '
        print '\tevent = ', event
        print '\tthresh_amp = ', thresh_amp
        print '\tthresh_dis = ', thresh_dis
        print '\tblob_ext = ', blob_ext
        print '\tplots = ', plots

    assert (direction in ['forward', 'backward'])
    assert (blob_ext % 2 == 0)

    # Maximum number of frames the blob is tracked for is given by
    # dimension 0 of frames
    # tau_max = np.shape(frames)[0]
    tau_max = frames.shape[0]
    I0, z0_last, R0_last = event[0], event[2], event[3]

    # I0 is the threshold amplitude we use for detecting blobs
    # i.e. for blob tracking, we identify later all connected regions that are larger than 
    # I0 * thresh_amp

    if (direction is 'forward'):
        f_idx = 0  # Index used to access frames
        tau = 0  # Start with zero offset
    elif (direction is 'backward'):
        f_idx = -1  # Start at the second to last frame, 0 based indexing
        tau = 1  # Start with one frame offset

    if (verbose):
        print 'Tracking blob %s, t_idx %d x = %d, y = %d, I0 = %f' %\
            (direction, tau, R0_last, z0_last, I0)
        print 'thresh_amp = %f, thresh_dis = %f' %\
            (thresh_amp * I0, thresh_dis)
    xycom = np.zeros([tau_max, 2])  # Return values: COM position of peak
    xymax = np.zeros([tau_max, 2])  # Position of the blob peak
    fwhm_pol_idx = np.zeros([tau_max, 2], dtype='int')  # Poloidal FWHM
    fwhm_rad_idx = np.zeros([tau_max, 2], dtype='int')  # Radial FWHM
    amp = np.zeros([tau_max])  # Amplitude at COM position

    good_blob = True
    while (good_blob and tau < tau_max):
        if (verbose):
            print 'f_idx %d, blob from x = %d, y = %d, I0 = %f' %\
                (f_idx, R0_last, z0_last, frames[f_idx, z0_last, R0_last])

        event_frame = frames[f_idx, :, :]
        #plt.figure()
        #plt.contourf(event_frame, 64)
        #plt.title('direction: %s, fidx=%d' % (direction, f_idx))
        #plt.colorbar()
        
        # Label all contiguous regions with ore than 60% of the original intensity
        labels = pm.label(event_frame > thresh_amp * I0)
        # Get the area of all contiguous regions
        blob_area = pm.blob(labels, 'area', output='data')
        # Get the controid of all contiguous regions
        blob_cent = pm.blob(labels, 'centroid', output='data')
        if (verbose):
            print 'Centroid analysis:'
            print '    -> blob_cent = ', blob_cent
            print '    -> shape = ', blob_cent.shape

        if (blob_cent.size < 1):
            # No peak here, quit tracking
            good_blob = False
            print 'Frame %d, %ss: lost track of blob' % (f_idx, direction)
            break

        # We now have a bunch of contiguous regions.
        # Loop over the regions that are at least 10% of the largest region
        # and find the one, whose centroid is closest to the  last known position 
        # of the blob

        loop_area = np.where(blob_area > 0.1 * blob_area.max())[0]
        min_idx = -1                        #
        min_dist_frame = np.sqrt(event_frame.shape[0] * event_frame.shape[1])     # Maximal distance on a 64x64 grid
        for d_idx, i in enumerate(loop_area):
            dist = np.sqrt((blob_cent[i, 1] - R0_last) ** 2 +
                           (blob_cent[i, 0] - z0_last) ** 2)
            if (verbose):
                print 'Region %d, distance to last peak: %f' % (d_idx, dist)
            if (dist < min_dist_frame and dist < thresh_dis):
                min_dist_frame = dist
                min_idx = i
                if (verbose):
                    print 'Accepted'

        # If min_dist_frame is still sqrt(8192), no area was selected and the
        # blob could not be tracked successfully
        if (min_dist_frame is np.sqrt(event_frame.shape[0] * event_frame.shape[1])):
            print 'No peak satisfying criteria.'
            print '\tFound: dist = %f, Stopping %s tracking after %d frames' %\
                (min_dist_frame, direction, tau)
            break
        if (min_idx is -1):
            print 'This should not happen'
            raise ValueError

        # Compute the x and y COM coordinates of the blob, store
        blob_mask = labels != (min_idx + 1)
        event_masked = np.ma.MaskedArray(event_frame,
                                         mask=blob_mask,
                                         fill_value=0)

        # When used to index frames[:,:,:]:
        #      xymax[tau,:] = [index for axis 2, index for axis 1]
        # Maximum in the blob mask
        xymax[tau, :] = np.unravel_index(event_masked.argmax(),
                                         np.shape(labels))
        # When used to index frames[:,:,:]:
        #     xycom[tau,:] = [index for axis 1, index for axis 2]
        # To be consistent with indexing from xymax, flip this array
        # COM returns com along second dimension at index 0
        xycom[tau, ::-1] = com(event_masked)
        ycom_off, xcom_off = xycom[tau, :].round().astype('int')

        if (verbose):
            print 'Peak at (%d,%d), COM at (%d,%d)' %\
                (xymax[tau, 0], xymax[tau, 1],
                 xycom[tau, 0], xycom[tau, 1])

        amp[tau] = event_frame[z0_last, R0_last]
        # Follow the peak
        z0_last, R0_last = xymax[tau, :].astype('int')

        if (plots):
            plt.figure()
            plt.title('%s, frame %d' % (direction, f_idx))
            plt.contour(event_frame, 16, colors='k', linewidth=0.5)
            plt.contourf(event_frame, 16, cmap=plt.cm.hot)
            plt.plot(xycom[tau, 1], xycom[tau, 0], 'wo')
            plt.plot(xymax[tau, 1], xymax[tau, 0], 'w^')
            plt.colorbar()
            plt.xlabel('x / px')
            plt.ylabel('y / px')

        if (direction is 'forward'):
            tau += 1                              # Frame accepted, advance indices
            f_idx += 1
        elif (direction is 'backward'):
            # We started at tau=1, subtract one to return correct number of frame
            # tracked in one direction, ignoring the starting frame
            # Ignore this for forward frame as we count the original frame here
            tau -= 1
            f_idx -= 1


    if (plots):
        plt.show()

    return tau, amp, xycom, xymax, fwhm_rad_idx, fwhm_pol_idx
count = 0
for file_mask in list_mask:
    file_image = glob.glob(file_mask[:-6] + '.*')[0]
    print "currently processing " + file_image
    dummy, filename = os.path.split(file_image)
    mask = cv2.imread(file_mask)
    mask = cv2.resize(
        mask,
        (mask.shape[1] / resizing_factor, mask.shape[0] / resizing_factor))
    height, width, c = mask.shape
    ground_truth_ = np.zeros((height, width))
    # get text bounding boxes
    ground_truth_text = ground_truth_ + np.where(
        np.linalg.norm(mask - [255, 0, 0], axis=2) < 10, 1, 0)
    label_text = label(ground_truth_text)
    bbox_text = blob(label_text, measurement='boundingbox', output="data")
    if bbox_text.size > 0:
        anno_text_x1 = bbox_text[:, 0].tolist()
        anno_text_y1 = bbox_text[:, 1].tolist()
        anno_text_x2 = bbox_text[:, 2].tolist()
        anno_text_y2 = bbox_text[:, 3].tolist()
        anno_text_label = list('t' * len(anno_text_x1))
    else:
        anno_text_x1 = []
        anno_text_y1 = []
        anno_text_x2 = []
        anno_text_y2 = []
        anno_text_label = []
    # get illustration bounding boxes
    ground_truth_illu = ground_truth_ + np.where(
        np.linalg.norm(mask - [0, 0, 255], axis=2) < 10, 1, 0)
Esempio n. 10
0
def find_closest_region(frame, thresh_amp, x0, max_dist=2.0, verbose=False):
    """
    Returns the contiguous area above a threshold in a frame, whose centroid coordinates 
    are closest to x0

    Input:
        frame       : Input frame
        thresh_amp  : Threshold for area separation
        x0          : Distance to centroid
        max_dist    : Maximal distance to centroid

    Output:
        Binary image with contiguous area marked with 1
    """

    # Label all contiguous regions with ore than 60% of the original intensity
    labels = pm.label(frame > thresh_amp)
    # Get the area of all contiguous regions
    blob_area = pm.blob(labels, 'area', output='data')
    # Get the controid of all contiguous regions
    blob_cent = pm.blob(labels, 'centroid', output='data')
    if (verbose):
        print 'x0 = (%f, %f)' % (x0[0], x0[1])
        print 'Labelling found %d regions: ' % labels.max()
        for i in np.arange(labels.max()):
            print 'Region: %d, centroid at %d, %d, area: %d' % (i, blob_cent[i, 1], blob_cent[i, 0], blob_area[i])

    if (blob_cent.size < 1):
        raise TrackingError

    # We now have a bunch of contiguous regions.
    # Loop over the regions that are at least 10% of the largest region
    # and find the one, whose centroid is closest to the  last known position 
    # of the blob

    min_idx = -1   
    min_dist_frame = np.sqrt(frame.shape[0] * frame.shape[1])     # Maximal distance on a 64x64 grid

    for d_idx, i in enumerate(blob_area):
        # Compute distance of current areas centroid to the last centroids position
        dist = np.sqrt((blob_cent[d_idx, 1] - x0[1]) ** 2 +
                       (blob_cent[d_idx, 0] - x0[0]) ** 2)
        if (verbose):
            print 'Region %d, center: x=%d, y=%d, A=%f, distance to last centroid: %f' %\
                (d_idx, blob_cent[d_idx, 0], blob_cent[d_idx, 1], i, dist)

        # Skip areas who are less than 10% of the original
        if (i < 0.1 * blob_area.max()):
            if(verbose):
                print 'passing blob with area %f, d_idx = %d' % (i, d_idx)
            continue

        if (dist < min(max_dist, min_dist_frame)):
            min_dist_frame = dist
            min_idx = d_idx
            if (verbose):
                print 'Accepted'

    # If min_dist_frame is still sqrt(8192), no area was selected and the
    # blob could not be tracked successfully
    if (min_idx is -1):
        print 'No peak satisfying criteria.'
        raise TrackingError

    x_centroid = blob_cent[min_idx]

    # Compute the x and y COM coordinates of the blob, store
    blob_mask = labels != (min_idx + 1)
    event_masked = np.ma.MaskedArray(frame,
                                     mask=blob_mask,
                                     fill_value=0)
#    plt.figure()
#    plt.subplot(131)
#    plt.contourf(labels)
#    plt.colorbar()
#
#    plt.subplot(132)
#    plt.contourf(frame, 64)
#    plt.colorbar()
#
#    plt.subplot(133)
#    plt.contourf(event_masked)
#    plt.colorbar()
#
#    plt.show()

    return (x_centroid, event_masked)