def identify_slab(im, sigma=<NUM_LIT>, region_size=<NUM_LIT:10>, masscut=<NUM_LIT>, asdict=False):
<EOL>fim = nd.filters.gaussian_filter(im, sigma)<EOL>trc, det = harris_feature(fim, region_size, to_return='<STR_LIT>')<EOL>dnrm = det / (trc*trc)<EOL>trc_cut = otsu_threshold(trc)<EOL>det_cut = otsu_threshold(dnrm)<EOL>slabs = (trc > trc_cut) & (dnrm < det_cut)<EOL>labeled, nslabs = nd.label(slabs)<EOL>masses = [(labeled == i).sum() for i in range(<NUM_LIT:1>, nslabs+<NUM_LIT:1>)]<EOL>good = np.array([m > masscut for m in masses])<EOL>inds = np.nonzero(good)[<NUM_LIT:0>] + <NUM_LIT:1>  <EOL>poses = np.array(nd.measurements.center_of_mass(trc, labeled, inds))<EOL>normals = []<EOL>z = np.arange(im.shape[<NUM_LIT:0>]).reshape(-<NUM_LIT:1>,<NUM_LIT:1>,<NUM_LIT:1>).astype('<STR_LIT:float>')<EOL>y = np.arange(im.shape[<NUM_LIT:1>]).reshape(<NUM_LIT:1>,-<NUM_LIT:1>,<NUM_LIT:1>).astype('<STR_LIT:float>')<EOL>x = np.arange(im.shape[<NUM_LIT:2>]).reshape(<NUM_LIT:1>,<NUM_LIT:1>,-<NUM_LIT:1>).astype('<STR_LIT:float>')<EOL>gim = [nd.sobel(fim, axis=i) for i in range(fim.ndim)]<EOL>for i, p in zip(range(<NUM_LIT:1>, nslabs+<NUM_LIT:1>), poses):<EOL><INDENT>wts = trc * (labeled == i)<EOL>wts /= wts.sum()<EOL>zc, yc, xc = [xi-pi for xi, pi in zip([z,y,x],p.squeeze())]<EOL>cov = [[np.sum(xi*xj*wts) for xi in [zc,yc,xc]] for xj in [zc,yc,xc]]<EOL>vl, vc = np.linalg.eigh(cov)<EOL>normal = vc[:,<NUM_LIT:0>]<EOL>gn = np.sum([n*g[tuple(p.astype('<STR_LIT:int>'))] for g,n in zip(gim, normal)])<EOL>normal *= np.sign(gn)<EOL>normals.append(normal)<EOL><DEDENT>if asdict:<EOL><INDENT>get_theta = lambda n: -np.arctan2(n[<NUM_LIT:1>], -n[<NUM_LIT:0>])<EOL>get_phi = lambda n: np.arcsin(n[<NUM_LIT:2>])<EOL>return [{'<STR_LIT>':p[<NUM_LIT:0>], '<STR_LIT>':(get_theta(n), get_phi(n))}<EOL>for p, n in zip(poses, normals)]<EOL><DEDENT>else:<EOL><INDENT>return poses, np.array(normals)<EOL><DEDENT>
Identifies slabs in an image.

Functions by running a Harris-inspired edge detection on the image,
thresholding the edge, then clustering.

Parameters
----------
    im : numpy.ndarray
        3D array of the image to analyze.
    sigma : Float, optional
        Gaussian blurring kernel to remove non-slab features such as
        noise and particles. Default is 5.
    region_size : Int, optional
        The size of region for Harris corner featuring. Default is 10
    masscut : Float, optional
        The minimum number of pixels for a feature to be identified as
        a slab. Default is 1e4; should be smaller for smaller images.
    asdict : Bool, optional
        Set to True to return a list of dicts, with keys of ``'theta'``
        and ``'phi'`` as rotation angles about the x- and z- axes, and
        of ``'zpos'`` for the z-position, i.e. a list of dicts which
        can be unpacked into a :class:``peri.comp.objs.Slab``

Returns
-------
    [poses, normals] : numpy.ndarray
        The positions and normals of each slab in the image; ``poses[i]``
        and ``normals[i]`` are the ``i``th slab. Returned if ``asdict``
        is False
    [list]
        A list of dictionaries. Returned if ``asdict`` is True