/
Cortical_Depth_IJ.py
176 lines (131 loc) · 5.33 KB
/
Cortical_Depth_IJ.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
## This program calculates the distance of ROI points in an image to an ROI line (or two).
## It does this by generating a perpendicular line that can be made to pass through the ROI point.
## It then calculates the distance between your point and the intersection of this perpendicular
## line with the reference ROI line. The functions called in the program are at the top.
## Please note that before running the program, the first ROI line must already be drawn. Have fun.
## Java-Python (Jython) sucks.
## Late note: The program only seems to work when the image is of the right hemisphere, ie. the pial and wm lines are drawn
## as sloping down and to the right. I'm not sure why. Most likely due to the way the angle is calculated.
## I get around this by just reflecting the image to accomodate this if necessary.
import java.lang.Math as math
import ij.measure as measure
import ij.plugin
from java.awt import Color
from java.awt import Frame
from java.awt import Font
from java.lang import String
from java.awt.event import MouseAdapter
from java.awt.event import TextListener
from ij import IJ
import ij.gui as gui
def Get_Line_Info(line):
## Gets all parameters associated with an ROI line
## Unpacks them and returns them for later use
angle = line.getAngle()
xbase = line.getXBase()
ybase = -line.getYBase()
width = line.getFloatWidth()
height = line.getFloatHeight()
if angle < 0:
xend = xbase + width
yend = ybase - height
slope = -(height / width)
else:
ybase = ybase - height
xend = xbase + width
yend = -line.getYBase()
slope = (height / width)
return(angle, xbase, ybase, width,
height, xend, yend, slope)
def Perpendicular_line(imp, line_info):
## Calculates the parameters for a line that is
## perpendicular to an ROI line. This is the line
## that acts as the depth reference.
angle, xbase, ybase, width, height, xend, yend, slope = line_info
width, height, nChannels, nSlices, nFrames = imp.getDimensions()
b = ybase - (slope*xbase)
perp_angle = math.toRadians(angle - 90)
slope_new_line = math.tan(perp_angle)
return(slope_new_line, b)
def Distance_point_to_line(line_info, new_slope, b, cell_points):
## This function calculates the euclidean distance of an
## ROI point to an ROI line. Returns the distance value.
angle, xbase, ybase, width, height, xend, yend, slope = line_info
cell_distance = []
for index in range(len(cell_points)):
x_coor, y_coor = cell_points[index]
y_coor = -y_coor
b_new_line = y_coor - (new_slope * x_coor)
x_intercept = (b - b_new_line) / (new_slope - slope)
y_intercept = (new_slope * x_intercept + b_new_line)
distance = ((x_intercept- x_coor)**2
+ (y_intercept - y_coor)**2)**0.5
cell_distance.append(distance)
return(cell_distance)
def Generate_table(table, cell_distance_pia, cell_distance_wm, cell_points):
## Creates table with output data that is popped up at the end
## of analysis. Does not return value. Just shows table.
for i in range(len(cell_distance_pia)):
xcoor, ycoor = cell_points[i]
table.incrementCounter()
table.addValue("Cell number", "Cell # " + str(i + 1))
table.addValue("X coordinate", xcoor)
table.addValue("Y coordinate", ycoor)
table.addValue("Distance from Pia", cell_distance_pia[i])
table.addValue("Distance from WM", cell_distance_wm[i])
pia = cell_distance_pia[i]
wm = cell_distance_wm[i]
percent_distance = (pia/(wm + pia)) * 100
table_data.addValue("Percent depth from Pia", percent_distance)
table_data.show("Results in Pixels")
table_data = measure.ResultsTable()
imp = IJ.getImage()
line_pia = imp.getRoi()
overlay = gui.Overlay(line_pia)
if line_pia is None:
window = gui.NonBlockingGenericDialog("Pial Surface")
window.addMessage("Please draw straight line to represent pia.\r\nThen click OK")
window.showDialog()
if window.wasCanceled():
raise NameError("Try again")
line_info_pia = Get_Line_Info(line_pia)
window = gui.NonBlockingGenericDialog("Draw white matter line")
window.addMessage("Draw the next line to outline white matter.\r\nThen click OK")
window.showDialog()
if window.wasCanceled():
raise NameError("Try again")
line_wm = imp.getRoi()
overlay.add(line_wm)
line_info_wm = Get_Line_Info(line_wm)
window = gui.NonBlockingGenericDialog("Cell selection")
window.addMessage("Using the multi-point tool, select each cell to be analyzed.\r\nThen click OK")
window.showDialog()
if window.wasCanceled():
raise NameError("Try again")
cells = imp.getRoi()
overlay.add(cells)
xpoints = cells.getXCoordinates()
ypoints = cells.getYCoordinates()
xbase = cells.getXBase()
ybase = cells.getYBase()
cell_coordinates = []
for item in xpoints:
n = xpoints.index(item)
x = xpoints[n] + xbase
y = ypoints[n] + ybase
coordinate = (x, y)
cell_coordinates.append(coordinate)
new_slope_pia, b = Perpendicular_line(imp, line_info_pia)
cell_distance_from_pia = Distance_point_to_line(line_info_pia, new_slope_pia, b, cell_coordinates)
new_slope_wm, b = Perpendicular_line(imp, line_info_wm)
cell_distance_from_wm = Distance_point_to_line(line_info_wm, new_slope_pia, b, cell_coordinates)
Generate_table(table_data, cell_distance_from_pia, cell_distance_from_wm, cell_coordinates)
imp.setOverlay(overlay)
new_rgb = imp.flatten()
new_rgb.show()
#print(cell_coordinates)
#print(new_slope_pia)
#print(new_slope_wm)
#print(b)
#print(cell_distance_from_pia)
#print(cell_distance_from_wm)