try:
  modelFound = model.filterRansac(candidates, inliers, 1000,
                                  maxEpsilon, minInlierRatio, minNumInliers)
  if modelFound:
    # Apply the transformation defined by the model to the first point
    # of each pair (PointMatch) of points. That is, to the point from
    # the first image.
    PointMatch.apply(inliers, model)
except NotEnoughDataPointsException, e:
  print e

if modelFound:
  # Store inlier pointmatches: the spatially coherent subset
  roi1pm = PointRoi()
  roi1pm.setName("matches in cut1")
  roi2pm = PointRoi()
  roi2pm.setName("matches in cut2")

  for pm in inliers:
    p1 = pm.getP1()
    roi1pm.addPoint(p1.getL()[0], p1.getL()[1])
    p2 = pm.getP2()
    roi2pm.addPoint(p2.getL()[0], p2.getL()[1])

  roi_manager.addRoi(roi1pm)
  roi_manager.addRoi(roi2pm)

  # Register images  
  # Transform the top-left and bottom-right corner of imp2
  # (use applyInverse: the model describes imp1 -> imp2)
def run():

    mask_ip = impSkel.getProcessor()
    part_ip = impPart.getProcessor()

    if not mask_ip.isBinary():
        error(impSkel.getTitle() + " is not a binary mask.")
        return

    # Mask grayscale image and skeletonize mask
    try:
        mask_pixels = mask_ip.getPixels()
        part_pixels = part_ip.getPixels()
        for i in xrange(len(part_pixels)):
            if mask_pixels[i] == 0:
                part_pixels[i] = 0
        part_ip.setPixels(part_pixels)
    except IndexError:
        error("Chosen images are not the same size.")
    skeletonize(impSkel)

    # Get skeleton features
    end_points, junctions, junction_voxels, total_len = skeleton_properties(impSkel)
    if not end_points and not junction_voxels:
        error(impSkel.getTitle() + " does not seem a valid skeleton.")
        return

    # Retrieve centroids from IJ1
    threshold_lower = get_threshold(impPart, thres_method)
    cx, cy, n_particles = get_centroids(impPart, threshold_lower)
    if None in (cx, cy):
        error("Verify parameters: No particles detected.")
        return

    # Loop through each centroids and categorize its position
    # according to its distance to skeleton features
    n_bp = n_tip = n_none = n_both = 0

    overlay = cleanse_overlay(impPart.getOverlay())
    for i in range(n_particles):

        j_dist = ep_dist = sys.maxint

        # Retrieve the distance between this particle and the closest junction voxel
        for jvoxel in junction_voxels:
            dist = distance(cx[i], cy[i], jvoxel.x, jvoxel.y)
            if (dist <= cutoff_dist and dist < j_dist):
                j_dist = dist

        # Retrieve the distance between this particle and the closest end-point
        for end_point in end_points:
            dist = distance(cx[i], cy[i], end_point.x, end_point.y)
            if (dist <= cutoff_dist and dist < ep_dist):
                ep_dist = dist

        roi_id = str(i).zfill(len(str(n_particles)))
        roi_name = "Unknown:" + roi_id
        roi_color = Color.ORANGE
        roi_type = 2  # dot

        # Is particle associated with neither junctions nor end-points?
        if j_dist > cutoff_dist and ep_dist > cutoff_dist:
            roi_name = "Unc:" + roi_id
            #n_none += 1
        # Is particle associated with both?
        elif abs(j_dist - ep_dist) <= pixel_size(impPart) / 2:
            roi_name = "J+T:" + roi_id
            roi_color = Color.CYAN
            #roi_type = 1  # crosshair
            n_both += 1
        # Is particle associated with an end-point?
        elif ep_dist < j_dist:
            roi_name = "Tip:" + roi_id
            roi_color = Color.GREEN
            #roi_type = 0  # hybrid
            n_tip += 1
        # Is particle associated with a junction?
        elif ep_dist > j_dist:
            roi_name = "Junction:" + roi_id
            roi_color = Color.MAGENTA
            #roi_type = 3  # circle
            n_bp += 1

        roi = PointRoi(cx[i], cy[i])
        roi.setName(roi_name)
        roi.setStrokeColor(roi_color)
        roi.setPointType(roi_type)
        roi.setSize(2)  # medium
        overlay.add(roi)

    # Display result
    impSkel.setOverlay(overlay)
    impPart.setOverlay(overlay)

    # Output some measurements
    if "table" in output:

        t = ResultsTable.getResultsTable() if "IJ1" in output else DefaultGenericTable()
        addToTable(t, "Part. image", "%s (%s)" % (impPart.getTitle(), impPart.getCalibration().getUnits()))
        addToTable(t, "Skel. image", "%s (%s)" % (impSkel.getTitle(), impSkel.getCalibration().getUnits()))
        addToTable(t, "Junction particles", n_bp)
        addToTable(t, "Tip particles", n_tip)
        addToTable(t, "J+T particles", n_both)
        addToTable(t, "Unc. particles", n_none)
        addToTable(t, "Junctions w/ particles", n_bp + n_both)
        addToTable(t, "Tips w/ particles", n_tip + n_both)
        addToTable(t, "Total skel. lenght", total_len)
        addToTable(t, "Total end points", len(end_points))
        addToTable(t, "Total junctions", sum(junctions))
        addToTable(t, "Unc. particles / Total skel. lenght)", n_none/total_len)
        addToTable(t, "Snap-to dist.", str(cutoff_dist) + impPart.getCalibration().getUnits())
        addToTable(t, "Threshold", "%d (%s)" % (threshold_lower, thres_method))
        showTable(t, "Results")