Ejemplo n.º 1
0
def test_mismatched_dims():
    f = np.arange(128 * 128, dtype=float).reshape((128, 128))
    filter = np.arange(17, dtype=float) - 8
    filter **= 2
    filter /= -16
    np.exp(filter, filter)
    mahotas.convolve(f, filter)
Ejemplo n.º 2
0
def test_mismatched_dims():
    f = np.arange(128*128, dtype=float).reshape((128,128))
    filter = np.arange(17,dtype=float)-8
    filter **= 2
    filter /= -16
    np.exp(filter,filter)
    mahotas.convolve(f,filter)
Ejemplo n.º 3
0
def test_22():
    A = np.arange(1024).reshape((32,32))
    B = np.array([
        [0,1],
        [2,3],
        ])
    C = np.array([
        [0,1,0],
        [2,3,0],
        [0,0,0],
        ])
    AB = mahotas.convolve(A,B)
    AC = mahotas.convolve(A,C)
    assert AB.shape == AC.shape
    assert np.all(AB == AC)
Ejemplo n.º 4
0
def test_22():
    A = np.arange(1024).reshape((32, 32))
    B = np.array([
        [0, 1],
        [2, 3],
    ])
    C = np.array([
        [0, 1, 0],
        [2, 3, 0],
        [0, 0, 0],
    ])
    AB = mahotas.convolve(A, B)
    AC = mahotas.convolve(A, C)
    assert AB.shape == AC.shape
    assert np.all(AB == AC)
Ejemplo n.º 5
0
def test_compare_w_ndimage():
    from scipy import ndimage
    A = np.arange(34*340, dtype='float64').reshape((34,340))%3
    B = np.ones((3,3), A.dtype)
    for mode in mahotas._filters.modes:
        if mode == 'ignore':
            continue
        assert np.all(mahotas.convolve(A, B, mode=mode) == ndimage.convolve(A, B, mode=mode))
Ejemplo n.º 6
0
def test_convolve1d():
    ws = [
        np.array([-.1, .5,.7,.7,.5]),
        np.array([.1,.7,.5]),
        ]
    for i in range(8):
        for w in ws:
            f = np.random.random((128,96))
            ww = np.atleast_2d(w)
            fw = mh.convolve(f, ww)
            fww = mh.convolve(f, ww.T)

            f0w = mh.convolve1d(f, w, 0)
            f1w = mh.convolve1d(f, w, 1)

            assert np.all(fw == f1w)
            assert np.all(fww == f0w)
Ejemplo n.º 7
0
def test_compare_w_ndimage():
    from scipy import ndimage
    A = np.arange(34 * 340).reshape((34, 340)) % 3
    B = np.ones((3, 3), A.dtype)
    for mode in mahotas._filters.modes:
        assert np.all(
            mahotas.convolve(A, B, mode=mode) == ndimage.convolve(
                A, B, mode=mode))
def test_convolve1d():
    ws = [
        np.array([-.1, .5, .7, .7, .5]),
        np.array([.1, .7, .5]),
    ]
    for i in range(8):
        for w in ws:
            f = np.random.random((128, 96))
            ww = np.atleast_2d(w)
            fw = mh.convolve(f, ww)
            fww = mh.convolve(f, ww.T)

            f0w = mh.convolve1d(f, w, 0)
            f1w = mh.convolve1d(f, w, 1)

            assert np.all(fw == f1w)
            assert np.all(fww == f0w)
Ejemplo n.º 9
0
def perimeter(bwimage, n=4, mode="constant"):
    """
    p = perimeter(bwimage, n=4, mode="constant")

    Calculate total perimeter of all objects in binary image.

    Parameters
    ----------
    bwimage : array
        binary image
    n : int, optional
        passed to ``bwperim`` as is
    mode : str, optional
        passed to ``bwperim`` as is

    Returns
    -------
    p : float
        total perimeter of all objects in binary image

    See Also
    --------
    bwperim : function
        Finds the perimeter region

    References
    ----------
    .. [1] K. Benkrid, D. Crookes. Design and FPGA Implementation of
           a Perimeter Estimator. The Queen's University of Belfast.
           http://www.cs.qub.ac.uk/~d.crookes/webpubs/papers/perimeter.doc
    """
    global _perimeter_values
    perim = bwperim(bwimage, n, mode)
    perim = perim.astype(np.uint8)

    histogram = mh.fullhistogram(
                    mh.convolve(perim, _perimeter_magic))

    if _perimeter_values is None:
        _perimeter_values = np.zeros(34, float)
        _perimeter_values[[5, 7, 15, 17, 25, 27]] = 1
        _perimeter_values[[21, 33]] = np.sqrt(2)
        _perimeter_values[[13, 23]] = (1 + np.sqrt(2)) / 2

    size = min(34, len(histogram))
    return np.dot(histogram[:size], _perimeter_values[:size])
Ejemplo n.º 10
0
def perimeter(bwimage, n=4, mode="constant"):
    """
    p = perimeter(bwimage, n=4, mode="constant")

    Calculate total perimeter of all objects in binary image.

    Parameters
    ----------
    bwimage : array
        binary image
    n : int, optional
        passed to ``bwperim`` as is
    mode : str, optional
        passed to ``bwperim`` as is

    Returns
    -------
    p : float
        total perimeter of all objects in binary image

    See Also
    --------
    bwperim : function
        Finds the perimeter region

    References
    ----------
    .. [1] K. Benkrid, D. Crookes. Design and FPGA Implementation of
           a Perimeter Estimator. The Queen's University of Belfast.
           http://www.cs.qub.ac.uk/~d.crookes/webpubs/papers/perimeter.doc
    """
    global _perimeter_values
    perim = bwperim(bwimage, n, mode)
    perim = perim.astype(np.uint8)

    histogram = mh.fullhistogram(
                    mh.convolve(perim, _perimeter_magic))

    if _perimeter_values is None:
        _perimeter_values = np.zeros(34, float)
        _perimeter_values[[5, 7, 15, 17, 25, 27]] = 1
        _perimeter_values[[21, 33]] = np.sqrt(2)
        _perimeter_values[[13, 23]] = (1 + np.sqrt(2)) / 2

    size = min(34, len(histogram))
    return np.dot(histogram[:size], _perimeter_values[:size])
Ejemplo n.º 11
0
from pylab import imshow
import mahotas
import numpy as np

wally = mahotas.imread('data/DepartmentStore.jpg')
wfloat = wally.astype(float)
r, g, b = wfloat.transpose((2, 0, 1))
w = wfloat.mean(2)
pattern = np.ones((24, 16), float)
for i in range(2):
    pattern[i::4] = -1
v = mahotas.convolve(r - w, pattern)
mask = (v == v.max())
mask = mahotas.dilate(mask, np.ones((48, 24)))
wally -= .8 * wally * ~mask[:, :, None]
imshow(wally)
Ejemplo n.º 12
0
                        gap_completion_distances * gap_completion_factor
                    combined_outflow = outflow_smooth * smoothing_factor + \
                        outflow_gap * gap_completion_factor
                    combined_inflow = inflow_smooth * smoothing_factor + \
                        inflow_gap * gap_completion_factor

                    # Find ignorable nodes - those where full 3x3 neighborhood has
                    # source_sink_cap > 0 and sum of source_sink_cap in
                    # neighborhood (except center) is greater than neighborhood
                    # outflow.  Similar for inflow.
                    hollow = np.ones((3, 3))
                    hollow[1, 1] = 0
                    ignorable = np.logical_and(
                        mahotas.erode(source_sink_cap > 0, np.ones((3, 3))),
                        (mahotas.convolve(source_sink_cap,
                                          hollow,
                                          mode='ignore') > combined_outflow))
                    np.logical_or(
                        ignorable,
                        np.logical_and(
                            mahotas.erode(source_sink_cap < 0, np.ones(
                                (3, 3))),
                            (mahotas.convolve(
                                source_sink_cap, hollow, mode='ignore') <
                             -combined_inflow)),  # careful with signs
                        out=ignorable)

                    print "Can ignore {0} of {1}".format(
                        np.sum(ignorable), ignorable.size)

                    ## Load the adjacency matrix
Ejemplo n.º 13
0
                 combined_distances = smooth_distances * smoothing_factor + \
                     gap_completion_distances * gap_completion_factor
                 combined_outflow = outflow_smooth * smoothing_factor + \
                     outflow_gap * gap_completion_factor
                 combined_inflow = inflow_smooth * smoothing_factor + \
                     inflow_gap * gap_completion_factor
 
 
                 # Find ignorable nodes - those where full 3x3 neighborhood has
                 # source_sink_cap > 0 and sum of source_sink_cap in
                 # neighborhood (except center) is greater than neighborhood
                 # outflow.  Similar for inflow.
                 hollow = np.ones((3, 3))
                 hollow[1, 1] = 0
                 ignorable = np.logical_and(mahotas.erode(source_sink_cap > 0, np.ones((3,3))),
                                            (mahotas.convolve(source_sink_cap, hollow, mode='ignore') >
                                             combined_outflow))
                 np.logical_or(ignorable,
                               np.logical_and(mahotas.erode(source_sink_cap < 0, np.ones((3,3))),
                                              (mahotas.convolve(source_sink_cap, hollow, mode='ignore') <
                                               - combined_inflow)),  # careful with signs
                               out=ignorable)
 
                 print "Can ignore {0} of {1}".format(np.sum(ignorable), ignorable.size)
 
                 ## Load the adjacency matrix
                 for di, direction in enumerate(directions[:4]):
                     dest_coords = shift_coords(coords, direction)
 
                     source_coords, dest_coords = validate_and_broadcast(coords, dest_coords)
                     mask = np.logical_or(ignorable[source_coords],
from pylab import imshow
import numpy as np
import mahotas

wally = mahotas.imread('waldo.jpg')
imshow(wally)

wfloat = wally.astype(float)
r,g,b = wfloat.transpose((2,0,1)) # split into rgb channels, better to use floats
w = wfloat.mean(2)	# w is the white channel

pattern = np.ones((24,16),float)
for i in xrange(2):
	pattern[i::4] = -1 # build a pattern of +1,+1,-1,-1 on vertical axis -> Wally's shirt.

v = mahotas.convolve(r-w, pattern) # convolve red-white, will give strong response where shirt
mask = (v == v.max())
mask = mahotas.dilate(mask,np.ones((48,24))) # look for max and dilate it to make it visible

wally -= .8*wally * ~mask[:,:,None]
imshow(wally)# imshow(wally)
Ejemplo n.º 15
0
def _patch_ms(patch, args):
    histogram = np.histogram(patch,bins=256,range=(0,256))[0]
    # np.set_printoptions(precision=2,threshold=256)
    # print(histogram)
    thresholds = threshold.multi_kapur(histogram, 2)
    tee.log('Maximum entropy discretization (Kapur et al. 1985, 3 bins):', thresholds)
    minint = thresholds[0]
    if minint != thresholds[0]:
        tee.log('Warning: minint was lowered')
    if minint <= 1:
        tee.log('minint threshold too low (%d) - I believe there are no cells in this substack' % minint)
        return None
    if thresholds[1] < args.min_second_threshold:
        tee.log('thresholds[1] threshold too low (%d) - I believe there are no cells in this substack' % thresholds[1])
        return None

    (Lx,Ly,Lz) = np.where(patch > minint)

    intensities = patch[(Lx,Ly,Lz)]
    L = np.array(list(zip(Lx,Ly,Lz)), dtype=np.uint16)
    tee.log('Found', len(L), 'voxels above the threshold', minint)
    if len(L) < 10:
        tee.log('Too few points (%d) - I believe there are no cells in this substack' % len(L))
        return None

    bandwidth = args.mean_shift_bandwidth
    radius = args.hi_local_max_radius
    reg_maxima = mh.regmax(patch.astype(np.int))
    if args.seeds_filtering_mode == 'hard':
        xx, yy, zz = np.mgrid[:2*radius+1, :2*radius+1, :2*radius+1]
        sphere = (xx - radius) ** 2 + (yy - radius) ** 2 + (zz - radius) ** 2
        se = sphere <= radius*radius
        f = se.astype(np.float64)
    elif args.seeds_filtering_mode == 'soft':
        f=np.zeros((int(radius+1)*2+1,int(radius+1)*2+1,int(radius+1)*2+1), dtype=np.float64);f[int(radius+1),int(radius+1),int(radius+1)]=1
        f=gaussian_filter(f, radius/2.,mode='constant', cval=0.0);f=f/np.amax(f)
    else:
        raise ValueError("Invalid seeds filtering mode", args.seeds_filtering_mode)

    min_mass = np.sum(f)*minint
    local_mass = mh.convolve(patch, weights=f, mode='constant', cval=0.0)
    above = local_mass > min_mass
    himaxima = np.logical_and(reg_maxima,above)


    if np.sum(himaxima) > args.max_expected_cells:
        tee.log('Too many candidates,', np.sum(himaxima), 'I believe this substack is messy and give up')
        return None

    C = [volume.Center(x,y,z) for (x,y,z) in zip(*np.where(himaxima))]
    if len(C) == 0:
        tee.log('No maxima above. #himaxima=', np.sum(himaxima), '#above=', np.sum(above), '. Giving up')
        return None
    seeds = np.array([[c.x, c.y, c.z] for c in C])
    # Save seeds with some info for debugging purposes
    for c in C:
        c.name = 'seed'
        c.mass = patch[c.x,c.y,c.z]
        c.volume = thresholds[0]
    cluster_centers, labels, volumes, masses, trajectories = mean_shift(L, intensities=intensities,
                                                                        bandwidth=bandwidth, seeds=seeds)
    if cluster_centers is None:
        return None
    masses = np.zeros(len(cluster_centers))
    for i,c in enumerate(cluster_centers):
        masses[i] = local_mass[int(c[0]+0.5),int(c[1]+0.5),int(c[2]+0.5)]
    PatchMSRet = namedtuple('PatchMSRet',
                            ['cluster_centers','labels','masses','L','seeds'])
    r = PatchMSRet(cluster_centers=cluster_centers,
                   labels=labels, masses=masses, L=L, seeds=C)
    return r
Ejemplo n.º 16
0
def sujoy(img, kernel_nhood=0, just_filter=False):
    '''
	edges = sujoy(img, kernel_nhood=0, just_filter=False)
	Compute edges using Sujoy's algorithm
	`edges` is a binary image of edges computed according to Sujoy's algorithm.
	PAPER LINK: https://www.ijert.org/research/a-better-first-derivative-approach-for-edge-detection-IJERTV2IS110616.pdf
	
	Parameters
	----------
	img : Any 2D-ndarray
	kernel_nhood : 0(default) or 1
		if 0, kernel is based on 4-neighborhood
		else , kernel is based on 8-neighborhood
	just_filter : boolean, optional
		If true, then return the result of filtering the image with the Sujoy's
		filters, but do not threshold (default is False).
	Returns
	-------
	edges : ndarray
		Binary image of edges, unless `just_filter`, in which case it will be
		an array of floating point values.
	'''

    img = np.array(img, dtype=np.float)
    if img.ndim != 2:
        raise ValueError(
            'mahotas.sujoy: Only available for 2-dimensional images')
    img -= img.min()
    ptp = img.ptp()
    if ptp == 0:
        return img
    img /= ptp

    if kernel_nhood:
        krnl_h = np.array([[0, -1, -1, -1, 0], [0, -1, -1, -1, 0],
                           [0, 0, 0, 0, 0], [0, 1, 1, 1, 0], [0, 1, 1, 1, 0]
                           ]) / 12.
        krnl_v = np.array([[0, 0, 0, 0, 0], [-1, -1, 0, 1, 1], [
            -1, -1, 0, 1, 1
        ], [-1, -1, 0, 1, 1], [0, 0, 0, 0, 0]]) / 12.
    else:
        krnl_h = np.array([[0, 0, -1, 0, 0], [0, -1, -1, -1, 0], [
            0, 0, 0, 0, 0
        ], [0, 1, 1, 1, 0], [0, 0, 1, 0, 0]]) / 8.
        krnl_v = np.array([[0, 0, 0, 0, 0], [0, -1, 0, 1, 0], [
            -1, -1, 0, 1, 1
        ], [0, -1, 0, 1, 0], [0, 0, 0, 0, 0]]) / 8.

    grad_h = mh.convolve(img, krnl_h, mode='nearest')
    grad_v = mh.convolve(img, krnl_v, mode='nearest')

    grad_h **= 2
    grad_v **= 2

    grad = grad_h
    grad += grad_v
    if just_filter:
        return grad
    t = np.sqrt(grad.mean())

    return mh.regmax(grad) * (np.sqrt(grad) > t)
Ejemplo n.º 17
0
import mahotas
import mahotas.demos
from pylab import gray, imshow, show
import numpy as np

# loading image(input image file name inplace of 'lena')
img = mahotas.demos.load('lena')
img = img.max(2)
T_otsu = mahotas.otsu(img)
img = img > T_otsu

print("Image threshold using Otsu Mehtod")
imshow(img)
show()
weight = np.ones((5, 5), float)
new_img = mahotas.convolve(img, weight)
print("Convolved Image")
imshow(new_img)
show()
wally = mahotas.demos.load('Wally')
imshow(wally)
show()

wfloat = wally.astype(float)
r, g, b = wfloat.transpose((2,0,1)) #transpose 시킴. 인덱스 번호는 0, 1, 2 순서로 갑니다. 그런데 지금 '2'가 면으로 왔습니다. ???????????????


w = wfloat.mean(2)# 2개씩 평균을 취해감.
pattern = np.ones((24, 16), float)#직삭각형을 만든 것 입니다. 직사각형 패턴

#셔츠의 패턴
for i in np.arange(2): # i에는 0, 1
    pattern[i::4] = -1 # 4칸씩 건너뛰면서 -1

v = mahotas.convolve(r-w, pattern) #컨볼루션 연산을 패턴을 가지고 합니다. 위에 셔츠의 패턴이 '필터'가 됩니다. #여기에는 stride 개념이 있습니다. 몇칸씩 건너뛸것이냐. 지금 지정이 없으니까 '1픽셀씩 건너뛰면서 = -1 '
mask = (v == v.max()) # v값과, v최고값인 것

mask = mahotas.dilate(mask, np.ones((48, 24))) #dilate 확장=키우라.  원래 24,16인데 48,24로 키웠음.
np.subtract(wally, .8*wally * ~mask[:, :, None], out=wally, casting='unsafe')
imshow(wally)
show()


##
from PIL import Image
img = Image.open('C:/Users/Hyungi/Desktop/workplace/img/image.png')
dim = (100, 100, 400, 400)
crop_img = img.crop(dim)
crop_img.show()
Ejemplo n.º 19
0
def _patch_ms(patch, args):
    histogram = np.histogram(patch,bins=256,range=(0,256))[0]
    # np.set_printoptions(precision=2,threshold=256)
    # print(histogram)
    thresholds = threshold.multi_kapur(histogram, 2)
    tee.log('Maximum entropy discretization (Kapur et al. 1985, 3 bins):', thresholds)
    minint = thresholds[0]
    if minint != thresholds[0]:
        tee.log('Warning: minint was lowered')
    if minint <= 1:
        tee.log('minint threshold too low (%d) - I believe there are no cells in this substack' % minint)
        return None
    if thresholds[1] < args.min_second_threshold:
        tee.log('thresholds[1] threshold too low (%d) - I believe there are no cells in this substack' % thresholds[1])
        return None

    (Lx,Ly,Lz) = np.where(patch > minint)

    intensities = patch[(Lx,Ly,Lz)]
    L = np.array(zip(Lx,Ly,Lz), dtype=np.uint16)
    tee.log('Found', len(L), 'voxels above the threshold', minint)
    if len(L) < 10:
        tee.log('Too few points (%d) - I believe there are no cells in this substack' % len(L))
        return None

    bandwidth = args.mean_shift_bandwidth
    radius = args.hi_local_max_radius
    reg_maxima = mh.regmax(patch.astype(np.int))
    if args.seeds_filtering_mode == 'hard':
        xx, yy, zz = np.mgrid[:2*radius+1, :2*radius+1, :2*radius+1]
        sphere = (xx - radius) ** 2 + (yy - radius) ** 2 + (zz - radius) ** 2
        se = sphere <= radius*radius
        f = se.astype(np.float64)
    elif args.seeds_filtering_mode == 'soft':
        f=np.zeros((int(radius+1)*2+1,int(radius+1)*2+1,int(radius+1)*2+1), dtype=np.float64);f[int(radius+1),int(radius+1),int(radius+1)]=1
        f=gaussian_filter(f, radius/2.,mode='constant', cval=0.0);f=f/np.amax(f)
    else:
        raise ValueError("Invalid seeds filtering mode", args.seeds_filtering_mode)

    min_mass = np.sum(f)*minint
    local_mass = mh.convolve(patch, weights=f, mode='constant', cval=0.0)
    above = local_mass > min_mass
    himaxima = np.logical_and(reg_maxima,above)
    if np.sum(himaxima) > args.max_expected_cells:
        tee.log('Too many candidates,', np.sum(himaxima), 'I believe this substack is messy and give up')
        return None
    C = [volume.Center(x,y,z) for (x,y,z) in zip(*np.where(himaxima))]

    if len(C) == 0:
        tee.log('No maxima above. #himaxima=', np.sum(himaxima), '#above=', np.sum(above), '. Giving up')
        return None
    seeds = np.array([[c.x, c.y, c.z] for c in C])
    # Save seeds with some info for debugging purposes
    for c in C:
        c.name = 'seed'
        c.mass = patch[c.x,c.y,c.z]
        c.volume = thresholds[0]
    cluster_centers, labels, volumes, masses, trajectories = mean_shift(L, intensities=intensities,
                                                                        bandwidth=bandwidth, seeds=seeds)
    if cluster_centers is None:
        return None
    masses = np.zeros(len(cluster_centers))
    for i,c in enumerate(cluster_centers):
        masses[i] = local_mass[int(c[0]+0.5),int(c[1]+0.5),int(c[2]+0.5)]
    PatchMSRet = namedtuple('PatchMSRet',
                            ['cluster_centers','labels','masses','L','seeds'])
    r = PatchMSRet(cluster_centers=cluster_centers,
                   labels=labels, masses=masses, L=L, seeds=C)
    return r
Ejemplo n.º 20
0
def main(image, mask, threshold=25,
         mean_size=6, min_size=10,
         filter_type='log_2d',
         minimum_bead_intensity=150,
         z_step=0.333, pixel_size=0.1625,
         alpha=0, plot=False):
    '''Converts an image stack with labelled cell surface to a cell
    `volume` image

    Parameters
    ----------
    image: numpy.ndarray[Union[numpy.uint8, numpy.uint16]]
        grayscale image in which beads should be detected (3D)
    mask: numpy.ndarray[Union[numpy.int32, numpy.bool]]
        binary or labeled image of cell segmentation (2D)
    threshold: int, optional
        intensity of bead in filtered image (default: ``25``)
    mean_size: int, optional
        mean size of bead (default: ``6``)
    min_size: int, optional
        minimal number of connected voxels per bead (default: ``10``)
    filter_type: str, optional
        filter used to emphasise the beads in 3D
        (options: ``log_2d`` (default) or ``log_3d``)
    minimum_bead_intensity: int, optional
        minimum intensity in the original image of an identified bead
        centre. Use to filter low intensity beads.
    z_step: float, optional
        distance between consecutive z-planes (um) (default: ``0.333``)
    pixel_size: float, optional
        size of pixel (um) (default: ``0.1625``)
    alpha: float, optional
        value of parameter for 3D alpha shape calculation
        (default: ``0``, no vertex filtering performed)
    plot: bool, optional
        whether a plot should be generated (default: ``False``)

    Returns
    -------
    jtmodules.generate_volume_image.Output
    '''

    # Check that there are cells identified in image
    if (np.max(mask) > 0):
        volume_image_calculated = True

        n_slices = image.shape[-1]
        logger.debug('input image has z-dimension %d', n_slices)

        # Remove high intensity pixels
        detect_image = image.copy()
        p = np.percentile(detect_image, 99.9)
        detect_image[detect_image > p] = p

        # Perform LoG filtering in 3D to emphasise beads
        if filter_type == 'log_2d':
            logger.info('using stacked 2D LoG filter to detect beads')
            f = -1 * log_2d(size=mean_size, sigma=float(mean_size - 1) / 3)
            filt = np.stack([f for _ in range(mean_size)], axis=2)

        elif filter_type == 'log_3d':
            logger.info('using 3D LoG filter to detect beads')
            filt = -1 * log_3d(mean_size, (float(mean_size - 1) / 3,
                                           float(mean_size - 1) / 3,
                                           4 * float(mean_size - 1) / 3))
        else:
            logger.info('using unfiltered image to detect beads')

        if filter_type == 'log_2d' or filter_type == 'log_3d':
            logger.debug('convolve image with filter kernel')
            detect_image = mh.convolve(detect_image.astype(float), filt)
            detect_image[detect_image < 0] = 0

        logger.debug('threshold beads')
        labeled_beads, n_labels = mh.label(detect_image > threshold)
        logger.info('detected %d beads', n_labels)

        logger.debug('remove small beads')
        sizes = mh.labeled.labeled_size(labeled_beads)
        too_small = np.where(sizes < min_size)
        labeled_beads = mh.labeled.remove_regions(labeled_beads, too_small)
        mh.labeled.relabel(labeled_beads, inplace=True)
        logger.info(
            '%d beads remain after removing small beads', np.max(labeled_beads)
        )

        logger.debug('localise beads in 3D')
        localised_beads = localise_bead_maxima_3D(
            image, labeled_beads, minimum_bead_intensity
        )

        logger.debug('mask beads inside cells')
        '''NOTE: localised_beads.coordinate image is used only for beads
        outside cells and can therefore be modified here. For beads
        inside cells, localised_beads.coordinates are used instead.
        '''
        # expand mask to ensure slide-beads are well away from cells
        slide = localised_beads.coordinate_image
        expand_mask = mh.dilate(
            A=mask > 0,
            Bc=np.ones([25,25], bool)
        )
        slide[expand_mask] = 0

        logger.debug('determine coordinates of slide surface')
        try:
            bottom_surface = slide_surface_params(slide)
        except InvalidSlideError:
            logger.error('slide surface calculation is invalid' +
                         ' returning empty volume image')
            volume_image = np.zeros(shape=image[:,:,0].shape,
                                    dtype=image.dtype)
            figure = str()
            return Output(volume_image, figure)

        logger.debug('subtract slide surface to get absolute bead coordinates')
        bead_coords_abs = []
        for i in range(len(localised_beads.coordinates)):
            bead_height = (
                localised_beads.coordinates[i][2] -
                plane(localised_beads.coordinates[i][0],
                      localised_beads.coordinates[i][1],
                      bottom_surface.x)
            )
            if bead_height > 0:
                bead_coords_abs.append(
                    (localised_beads.coordinates[i][0],
                     localised_beads.coordinates[i][1],
                     bead_height)
                )

        logger.debug('convert absolute bead coordinates to image')
        coord_image_abs = coordinate_list_to_array(
            bead_coords_abs, shape=image[:,:,0].shape, dtype=np.float32
        )

        filtered_coords_global = filter_vertices_per_cell_alpha_shape(
            coord_image_abs=coord_image_abs,
            mask=mask,
            alpha=alpha,
            z_step=z_step,
            pixel_size=pixel_size
        )

        logger.info('interpolate cell surface')
        volume_image = interpolate_surface(
            coords=np.asarray(filtered_coords_global, dtype=np.uint16),
            output_shape=np.shape(image[:,:,0]),
            method='linear'
        )

        volume_image = volume_image.astype(image.dtype)

        logger.debug('set regions outside mask to zero')
        volume_image[mask == 0] = 0

    else:
        logger.warn(
            'no objects in input mask, skipping cell volume calculation.'
        )
        volume_image_calculated = False
        volume_image = np.zeros(shape=image[:,:,0].shape, dtype=image.dtype)

    if (plot and volume_image_calculated):
        logger.debug('convert bottom surface plane to image for plotting')
        dt = np.dtype(float)
        bottom_surface_image = np.zeros(slide.shape, dtype=dt)
        for ix in range(slide.shape[0]):
            for iy in range(slide.shape[1]):
                bottom_surface_image[ix, iy] = plane(
                    ix, iy, bottom_surface.x)
        logger.info('create plot')
        from jtlib import plotting
        plots = [
            plotting.create_intensity_image_plot(
                np.max(image, axis=-1), 'ul', clip=True
            ),
            plotting.create_float_image_plot(
                bottom_surface_image, 'll', clip=True
            ),
            plotting.create_intensity_image_plot(
                volume_image, 'ur', clip=True
            )

        ]
        figure = plotting.create_figure(
            plots, title='Convert stack to volume image'
        )
    else:
        figure = str()

    return Output(volume_image, figure)
Ejemplo n.º 21
0
from pylab import imshow
import mahotas as mh
import numpy as np

wally = mh.demos.load('DepartmentStore')
wfloat = wally.astype(float)
r, g, b = wfloat.transpose((2, 0, 1))
w = wfloat.mean(2)
pattern = np.ones((24, 16), float)
for i in range(2):
    pattern[i::4] = -1
v = mh.convolve(r - w, pattern)
mask = (v == v.max())
mask = mh.dilate(mask, np.ones((48, 24)))
wally -= np.array(.8 * wally * ~mask[:, :, None], dtype=wally.dtype)
imshow(wally)
Ejemplo n.º 22
0
def main(image,
         mask,
         threshold=1,
         min_area=3,
         mean_area=5,
         max_area=1000,
         clip_percentile=99.999,
         plot=False):
    '''Detects blobs in `image` using an implementation of
    `SExtractor <http://www.astromatic.net/software/sextractor>`_ [1].
    The `image` is first convolved with a Laplacian of Gaussian filter of size
    `mean_area` to enhance blob-like structures. The enhanced image is
    then thresholded at `threshold` level and connected pixel components are
    subsequently deplended.

    Parameters
    ----------
    image: numpy.ndarray[Union[numpy.uint8, numpy.uint16]]
        grayscale image in which blobs should be detected
    mask: numpy.ndarray[Union[numpy.int32, numpy.bool]]
        binary or labeled image that specifies pixel regions of interest
        in which blobs should be detected
    threshold: int, optional
        threshold level for pixel values in the convolved image
        (default: ``1``)
    min_area: int, optional
        minimal size a blob is allowed to have (default: ``3``)
    mean_area: int, optional
        estimated average size of a blob (default: ``5``)
    max_area: int, optional
        maximal size a blob is allowed to have to be subject to deblending;
        no attempt will be made to deblend blobs larger than `max_area`
        (default: ``100``)
    clip_percentile: float, optional
        clip intensity values in `image` above the given percentile; this may
        help in attenuating artifacts
    plot: bool, optional
        whether a plot should be generated (default: ``False``)

    Returns
    -------
    jtmodules.detect_blobs.Output[Union[numpy.ndarray, str]]

    References
    ----------
    .. [1] Bertin, E. & Arnouts, S. 1996: SExtractor: Software for source
    extraction, Astronomy & Astrophysics Supplement 317, 393
    '''

    logger.info('detect blobs above threshold {0}'.format(threshold))

    detect_image = image.copy()

    p = np.percentile(image, clip_percentile)
    detect_image[image > p] = p

    # Enhance the image for blob detection by convoling it with a LOG filter
    f = -1 * log_2d(size=mean_area, sigma=float(mean_area - 1) / 3)
    detect_image = mh.convolve(detect_image.astype(float), f)
    detect_image[detect_image < 0] = 0

    # Mask regions of too big blobs
    pre_blobs = mh.label(detect_image > threshold)[0]
    bad_blobs, n_bad = mh.labeled.filter_labeled(pre_blobs, min_size=max_area)
    logger.info(
        'remove {0} blobs because they are bigger than {1} pixels'.format(
            n_bad, max_area))
    detect_mask = np.invert(mask > 0)
    detect_mask[bad_blobs > 0] = True
    detect_image[bad_blobs > 0] = 0

    logger.info('deblend blobs')
    blobs, centroids = detect_blobs(image=detect_image,
                                    mask=detect_mask,
                                    threshold=threshold,
                                    min_area=min_area)

    n = len(np.unique(blobs[blobs > 0]))

    logger.info('{0} blobs detected'.format(n))

    if plot:
        logger.info('create plot')
        from jtlib import plotting

        colorscale = plotting.create_colorscale('Spectral',
                                                n=n,
                                                permute=True,
                                                add_background=True)
        plots = [
            plotting.create_float_image_plot(detect_image, 'ul', clip=True),
            plotting.create_mask_image_plot(blobs, 'ur', colorscale=colorscale)
        ]
        figure = plotting.create_figure(
            plots,
            title=('detected #{0} blobs above threshold {1}'
                   ' in LOG filtered image'.format(n, threshold)))
    else:
        figure = str()

    return Output(centroids, blobs, figure)
Ejemplo n.º 23
0
import mahotas as mh
import numpy as np
import cv2

# Imported mahotas & numpy with standard abbreviations
im = mh.imread('./images/pool-table-above-17031042.jpg', as_grey=1)

# Load the image & convert to gray
# im2 = im[::2,::2]
im2 = mh.gaussian_filter(im, 1.2)
cv2.imshow('gaussian', im)
# save first step
# mh.imsave('1.png', im2.astype(np.uint8))

# Mean filtering is implemented "by hand" with a convolution.
mean_filtered = mh.convolve(im2.astype(float), np.ones((9, 9))/81.)

# iminv = 255 - mean_filtered
# mh.imsave('binarized1.png', iminv.astype(np.uint8))

# You might need to adjust the number 4 here, but it worked well for this image.
imc = im2 > mean_filtered - 4
# cv2.imshow('open circles', (imc*255).astype(np.uint8));
# cv2.waitKey(0)

# mh.imsave('1.png', im2.astype(np.uint8))
# print(im2)

# imc = mh.convolve(imc.astype(float), np.ones((9, 9))/81.)

# imc = im2 > mean_filtered - 6
Ejemplo n.º 24
0
from pylab import imshow
import mahotas
wally = mahotas.imread('data/DepartmentStore.jpg')
wfloat = wally.astype(float)
r,g,b = wfloat.transpose((2,0,1))
w = wfloat.mean(2)
pattern = np.ones((24,16), float)
for i in xrange(2):
    pattern[i::4] = -1
v = mahotas.convolve(r-w, pattern)
mask = (v == v.max())
mask = mahotas.dilate(mask, np.ones((48,24)))
wally -= .8*wally * ~mask[:,:,None]
imshow(wally)


Ejemplo n.º 25
0
def main(image, mask, threshold=1, min_area=3, mean_area=5, max_area=1000,
        clip_percentile=99.999, plot=False):
    '''Detects blobs in `image` using an implementation of
    `SExtractor <http://www.astromatic.net/software/sextractor>`_ [1].
    The `image` is first convolved with a Laplacian of Gaussian filter of size
    `mean_area` to enhance blob-like structures. The enhanced image is
    then thresholded at `threshold` level and connected pixel components are
    subsequently deplended.

    Parameters
    ----------
    image: numpy.ndarray[Union[numpy.uint8, numpy.uint16]]
        grayscale image in which blobs should be detected
    mask: numpy.ndarray[Union[numpy.int32, numpy.bool]]
        binary or labeled image that specifies pixel regions of interest
        in which blobs should be detected
    threshold: int, optional
        threshold level for pixel values in the convolved image
        (default: ``1``)
    min_area: int, optional
        minimal size a blob is allowed to have (default: ``3``)
    mean_area: int, optional
        estimated average size of a blob (default: ``5``)
    max_area: int, optional
        maximal size a blob is allowed to have to be subject to deblending;
        no attempt will be made to deblend blobs larger than `max_area`
        (default: ``100``)
    clip_percentile: float, optional
        clip intensity values in `image` above the given percentile; this may
        help in attenuating artifacts
    plot: bool, optional
        whether a plot should be generated (default: ``False``)

    Returns
    -------
    jtmodules.detect_blobs.Output[Union[numpy.ndarray, str]]

    References
    ----------
    .. [1] Bertin, E. & Arnouts, S. 1996: SExtractor: Software for source
    extraction, Astronomy & Astrophysics Supplement 317, 393
    '''

    logger.info('detect blobs above threshold {0}'.format(threshold))

    detect_image = image.copy()

    p = np.percentile(image, clip_percentile)
    detect_image[image > p] = p

    # Enhance the image for blob detection by convoling it with a LOG filter
    f = -1 * log_2d(size=mean_area, sigma=float(mean_area - 1)/3)
    detect_image = mh.convolve(detect_image.astype(float), f)
    detect_image[detect_image < 0] = 0

    # Mask regions of too big blobs
    pre_blobs = mh.label(detect_image > threshold)[0]
    bad_blobs, n_bad = mh.labeled.filter_labeled(pre_blobs, min_size=max_area)
    logger.info(
        'remove {0} blobs because they are bigger than {1} pixels'.format(
            n_bad, max_area
        )
    )
    detect_mask = np.invert(mask > 0)
    detect_mask[bad_blobs > 0] = True
    detect_image[bad_blobs > 0] = 0

    logger.info('deblend blobs')
    blobs, centroids = detect_blobs(
        image=detect_image, mask=detect_mask, threshold=threshold,
        min_area=min_area
    )

    n = len(np.unique(blobs[blobs>0]))

    logger.info('{0} blobs detected'.format(n))

    if plot:
        logger.info('create plot')
        from jtlib import plotting

        colorscale = plotting.create_colorscale(
            'Spectral', n=n, permute=True, add_background=True
        )
        plots = [
            plotting.create_float_image_plot(
                detect_image, 'ul', clip=True
            ),
            plotting.create_mask_image_plot(
                blobs, 'ur', colorscale=colorscale
            )
        ]
        figure = plotting.create_figure(
            plots,
            title=(
                'detected #{0} blobs above threshold {1}'
                ' in LOG filtered image'.format(n, threshold)
            )
        )
    else:
        figure = str()

    return Output(centroids, blobs, figure)