コード例 #1
0
def threshold_otsu_median(datafield, pts=256):
    """
    Compute Otsu's threshold with median classifier (histogram mode).

    Parameters
    ----------
    datafield: gwy.DataField
        Datafield over which threshold will be computed.
    pts: int
        Number of points in histogram. Default 256.

    Returns
    -------
    threshold: float

    """
    # number of pts for histogram
    cdf = gwy.DataLine(pts, 0, True)
    # compute z-scale CDF from image
    datafield.cdh(cdf, pts)

    # sort all intensity values
    vals = sorted(datafield.get_data())

    # sort out hist data
    dx = cdf.get_real() / cdf.get_res()  # pixel spacing in data line
    offset = cdf.get_offset()  # dataline offset, ie. 0 index point value in x
    x = [(i * dx) + offset for i in range(pts)]  # construct bin locations

    # get cdf data as list
    weight1 = [int(round(i * len(vals))) for i in cdf.get_data()]
    weight2 = [len(vals) - i for i in weight1[::-1]][::-1]

    # class medians for all possible thresholds
    median1 = [vals[:weight1[i]][weight1[i] // 2] for i in range(pts - 1)]
    median2 = [
        vals[::-1][:weight2[i]][weight2[i] // 2] for i in range(pts - 1)
    ]

    # median for whole image
    medianT = vals[len(vals) // 2]

    # Clip ends to align class 1 and class 2 variables:
    # The last value of `weight1`/`mean1` should pair with zero values in
    # `weight2`/`mean2`, which do not exist.
    variance = [
        weight1[i] * (median1[i] - medianT)**2 + weight2[i + 1] *
        (median2[i] - medianT)**2 for i in range(pts - 1)
    ]
    # get index of maximum variance to index x array
    threshold = x[:-1][variance.index(max(variance))]

    return threshold
コード例 #2
0
def threshold_otsu_mode(datafield, pts=256):
    """
    Compute Otsu's threshold with median classifier (histogram mode).

    Parameters
    ----------
    datafield: gwy.DataField
        Datafield over which threshold will be computed.
    pts: int
        Number of points in histogram. Default 256.

    Returns
    -------
    threshold: float

    """
    # number of pts for histogram
    dl = gwy.DataLine(pts, 0, True)
    # compute z-scale histogram from image
    datafield.dh(dl, pts)

    # sort out hist data
    dx = dl.get_real() / dl.get_res()  # pixel spacing in data line
    offset = dl.get_offset()  # dataline offset, ie. 0 index point value in x
    x = [(i * dx) + offset for i in range(pts)]  # construct bin locations
    y = dl.get_data()  # get histogram values

    weights = dl.duplicate()
    weights.cumulate()  # calculate cdf
    weights.multiply(dx)  # make sure cdf sums to 1
    weights = weights.get_data()  # get cdf data as list

    # holder lists for modal values at different thresholds
    mode1 = []
    mode2 = []
    modeT = x[y.index(dl.get_max())]  # get modal value for distribution

    # for each possible threshold value in histogram
    for i in range(1, pts):
        mode1.append(x[y.index(dl.part_extract(0, i).get_max())])
        mode2.append(x[i + y[i:].index(dl.part_extract(i, pts - i).get_max())])

    # calculate intraclass variance depending on the thresholds used
    variance = []
    for i in range(len(mode1)):  # should be same as mode2, ie. pts-1
        variance.append(weights[:-1][i] * (mode1[i] - modeT)**2 +
                        (1 - weights[1:][i]) * (mode2[i] - modeT)**2)

    # get index of maximum variance to index x array
    threshold = x[:-1][variance.index(max(variance))]

    return threshold
コード例 #3
0
def line_correct_median(data):
  """ corrected = line_correct_median(data)
  
  Does a median line correction on the passed gwy.DataField.
  
  """
  
  xres = data.get_xres()
  yres = data.get_yres()
  line = gwy.DataLine(xres,1.0,False)
  modi = gwy.DataLine(yres,1.0,False)
  
  for i in range(yres):
    data.get_row(line,i)
    median = line.get_median()
    modi.set_val(i,median)
  
  median = modi.get_median()
  
  for i in range(yres):
    data.area_add(0, i, xres, 1, median - modi.get_val(i))
    
  return data