Skip to content

Instantly share code, notes, and snippets.

@lacan
Last active March 16, 2018 20:56
Show Gist options
  • Select an option

  • Save lacan/2643f2ce7e33d1bb07adafde9ff94101 to your computer and use it in GitHub Desktop.

Select an option

Save lacan/2643f2ce7e33d1bb07adafde9ff94101 to your computer and use it in GitHub Desktop.
2D K Nearest Neighbors Python script when we have a point selection in ImageJ #Fiji #Python #ImageJ
# @ImagePlus imp
# @Integer(label="Number of Neighbors") k
'''
Simple 2D KNN script
Olivier Burri, BioImaging & Optics Platform
Ecole Polytechnique Fédérale de Lausanne
July 12th 2016
Code provided as-is in reply to an ImageJ mailing list question
http://imagej.1557.x6.nabble.com/distance-between-adjacent-particles-td3699485.html#a5016864
'''
from ij.gui import Overlay, Line, OvalRoi
from ij import IJ
from ij.measure import ResultsTable
from ij.measure import Calibration
from java.awt import Color
import math
### Some functions ###
# Brute-Force KNN
def knn(data, k):
# Just take the data, find the K nearest neighbors to each point
the_knn=[]
for i in range(len(data)):
d = []
for j in range(len(data)):
d.append([j, dist(data[i], data[j])])
# Sort
d_sort = sorted(d, key=lambda thed: thed[1])
# Keep only the k nearest
the_knn.append(d_sort[1:(k+1)])
return the_knn
# Euclidean Distance 2D
def dist(p0, p1):
return math.sqrt((p0[0] - p1[0])**2 + (p0[1] - p1[1])**2)
# Convenience function to go from a ROI to points
def roiToPointList(image):
p = [image.getRoi().getFloatPolygon().xpoints, image.getRoi().getFloatPolygon().ypoints]
points = map(list, zip(*p))
return points
def showKNNResults(the_knn):
# Overlay
ov = Overlay()
the_avg = []
# Draw each neighbor as a line and draw the average as a circle
for i in range(len(the_knn)):
avg = sum([d[1] for d in the_knn[i]]) / k
the_avg.append(avg)
o = OvalRoi(points[i][0] - avg, points[i][1] - avg, 2*avg, 2*avg)
o.setStrokeColor(Color.decode("#00FFFF"))
ov.add(o)
for j in range(k):
# XY Coordinates of current point
a = points[i];
b = points[the_knn[i][j][0]]
# XY Coordinates of neighbor k
l = Line(a[0], a[1], b[0], b[1])
l.setStrokeColor(Color.decode("#FF00FF"))
ov.add(l)
# Build Results Table
cal = imp.getCalibration()
frt = ResultsTable()
for i in range(len(the_knn)):
frt.incrementCounter()
frt.addValue("Point", i)
frt.addValue("Average distance [px]", the_avg[i])
if( cal.scaled() ):
frt.addValue("Average distance ["+cal.getXUnit()+"]", cal.getX(the_avg[i]))
frt.show(str(k)+" Nearest Neightbors Average Distances")
imp.setOverlay(ov)
### Starting the script ###
# Get Coordinates
points = roiToPointList(imp)
# Compute K Nearest Neighbors
the_knn = knn(points,k)
# Display the result table and an overlay
showKNNResults(the_knn)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment