def otsu_threshold(im, maxCount=255, verbose=False):
    """
    Function to turn an image into a binary split based on otus's method

    Args:
        im (array): image to threshold
        maxCount (int): maximum value of any element in the array
            For images this will be 255
        verbose (boolean): flag to visually show plot of histogram
            with threshold

    Returns:
        a tuple of a binary image (array), and the threshold (int)

    Raises:
        TypeError: if image is not a numpy ndarray
        ValueError: if image is not in the shape of a grayscale image
    """

    # type checking, look at the above Raises section
    if (not isinstance(im, np.ndarray)):
        raise TypeError("image is not a numpy ndarray; use openCV's imread")
    if (len(np.shape(im)) != 2):
        raise ValueError(
            "Shape of image is not a grayscale image or histogram")

    # get last non-zero pixel level
    hist = cv2.calcHist([im], [0], None, [255], [0, 255])
    # get the element pair, which contains an index and value (which is 0)
    firstPixelIndex = np.transpose(np.nonzero(hist))[0][0]
    lastPixelIndex = np.transpose(np.nonzero(hist))[-1][0]

    # evaluate sigma of b squared for all values from the first non zero pixel
    # level to the last non zero pixel level
    result = np.zeros(maxCount)
    for i in range(firstPixelIndex + 1, lastPixelIndex):
        sigma = class_variance_b_squared(im, i, maxCount)
        result[i] = sigma

    ipcv.plotHist(result)
    thresh = np.argmax(result)
    if (verbose):
        ipcv.plotHist(hist, [np.argmax(result)])

    # apply threshold to image
    binaryIm = np.ones(np.shape(im))
    binaryIm = binaryIm * im
    np.place(binaryIm, im < thresh, 0)
    np.place(binaryIm, im >= thresh, 1)

    return (binaryIm, thresh)
def otsu_threshold(im, maxCount=255, verbose=False):
    """
    Function to turn an image into a binary split based on otus's method

    Args:
        im (array): image to threshold
        maxCount (int): maximum value of any element in the array
            For images this will be 255
        verbose (boolean): flag to visually show plot of histogram
            with threshold

    Returns:
        a tuple of a binary image (array), and the threshold (int)

    Raises:
        TypeError: if image is not a numpy ndarray
        ValueError: if image is not in the shape of a grayscale image
    """

    # type checking, look at the above Raises section
    if (not isinstance(im, np.ndarray)):
        raise TypeError("image is not a numpy ndarray; use openCV's imread")
    if (len(np.shape(im)) != 2):
        raise ValueError("Shape of image is not a grayscale image or histogram")

    # get last non-zero pixel level
    hist = cv2.calcHist([im],[0],None,[255],[0,255])
    # get the element pair, which contains an index and value (which is 0)
    firstPixelIndex = np.transpose(np.nonzero(hist))[0][0]
    lastPixelIndex = np.transpose(np.nonzero(hist))[-1][0]

    # evaluate sigma of b squared for all values from the first non zero pixel
    # level to the last non zero pixel level
    result = np.zeros(maxCount)
    for i in range(firstPixelIndex+1, lastPixelIndex):
        sigma = class_variance_b_squared(im, i, maxCount)
        result[i] = sigma

    ipcv.plotHist(result)
    thresh = np.argmax(result)
    if (verbose):
        ipcv.plotHist(hist, [np.argmax(result)])

    # apply threshold to image
    binaryIm = np.ones(np.shape(im))
    binaryIm = binaryIm*im
    np.place(binaryIm, im<thresh, 0)
    np.place(binaryIm, im>=thresh, 1)

    return (binaryIm, thresh)
def u(im, k):
    """
    Function to evaulate the class mean levels

    Args:
        im (array): image to convert to histogram and evaluate
        k (int): pixel level to evaluating mean levels

    Returns:
        class mean level for k
    """

    # get histogram of probabilities
    hist = cv2.calcHist([im], [0], None, [255 + 1], [0, 255 + 1])
    histProbs = hist / np.cumprod(np.shape(im))[-1]

    # build array of indicies
    indHist = np.arange(256)

    histMean = indHist * histProbs

    ipcv.plotHist(histProbs)
    ipcv.plotHist(indHist)
    ipcv.plotHist(histMean)

    result = np.cumsum(histMean)[k]
    return result
def u(im, k):
    """
    Function to evaulate the class mean levels

    Args:
        im (array): image to convert to histogram and evaluate
        k (int): pixel level to evaluating mean levels

    Returns:
        class mean level for k
    """

    # get histogram of probabilities
    hist = cv2.calcHist([im],[0],None,[255+1],[0,255+1])
    histProbs = hist / np.cumprod(np.shape(im))[-1]

    # build array of indicies
    indHist = np.arange(256)

    histMean = indHist * histProbs

    ipcv.plotHist(histProbs)
    ipcv.plotHist(indHist)
    ipcv.plotHist(histMean)

    result = np.cumsum(histMean)[k]
    return result