8
8
from scipy import misc, signal, stats
11
11
from pyqtgraph.Qt import QtGui, QtCore
13
13
import pyqtgraph as pg
14
14
from pyqtgraph.parametertree import Parameter, ParameterTree
15
from trackROI_OpenCV import TrackROI # produces same data as Timo
16
17
# only edit lines below:
17
path = "/home/gcg/SHTB/20171005_PP"
18
path = "/home/gcg/SHTB/Probe6.2"
19
params = [{'name': 'px2mm', 'type': 'float', 'value': 0.02439, 'step': 1.0e-3, 'siPrefix': False, 'suffix': 'mm/px'},
20
{'name': 'scan rate', 'type': 'float', 'value': 200, 'step': 1, 'suffix': 'kHz'},
20
params = [{'name': 'px2mm', 'type': 'float', 'value': 0.021277, 'step': 1.0e-3, 'siPrefix': False, 'suffix': 'mm/px'},
21
{'name': 'scan rate', 'type': 'float', 'value': 200.0, 'step': 1, 'suffix': 'kHz'},
21
22
{'name': 'width ROI 1 in px', 'type': 'float', 'value': 1, 'suffix': ' px'},
22
23
{'name': 'width ROI 1 in mm', 'type': 'float', 'value': 1, 'suffix': ' mm'},
23
24
{'name': 'velocity ROI 1', 'type': 'float', 'value': 0, 'suffix': ' m/s'},
24
25
{'name': 'width ROI 2 in px', 'type': 'float', 'value': 1, 'suffix': ' px'},
25
26
{'name': 'width ROI 2 in mm', 'type': 'float', 'value': 1, 'suffix': ' mm'},
26
27
{'name': "distance ROI1 -- ROI2", 'type': 'float', 'value': 0, 'suffix': ' mm'},
28
{'name': "ROI1 start", 'type': 'float', 'value': 2564.0448385397744, 'suffix': ' px'},
29
{'name': "ROI1 stop", 'type': 'float', 'value': 2600.7122370880443, 'suffix': ' px'},
30
{'name': "ROI2 start", 'type': 'float', 'value': 2644.9711630257034, 'suffix': ' px'},
31
{'name': "ROI2 stop", 'type': 'float', 'value': 2685.8212880711058, 'suffix': ' px'},
35
40
files = glob.glob("*.bmp")
36
42
if not (len(files) == 1):
37
print "There are have multiple .bmp files in the working directory."
38
print "This program expects only a single .bmp image file containing linescan data."
43
print("There are have multiple .bmp files in the working directory.")
44
print("This program expects only a single .bmp image file containing linescan data.")
43
49
image_data = misc.imread(os.path.join(path,files[0]), flatten=1)
44
print np.shape(image_data)
50
print(np.shape(image_data))
46
53
# average every two subsequent lines
47
nx, ny = np.shape(image_data)
48
new_data = np.zeros((nx/2, ny))
49
for i in xrange(nx/2 - 1):
52
new_data[i,:] = 0.5 * (image_data[j,:] + image_data[k,:])
54
print "*** AVERAGED EVERY TWO LINES ***"
54
# nx, ny = np.shape(image_data)
55
# new_data = np.zeros((int(nx/2), ny))
56
# for i in xrange(nx/2 - 1):
59
# new_data[i,:] = 0.5 * (image_data[j,:] + image_data[k,:])
61
# print("*** AVERAGED EVERY TWO LINES ***")
61
start1, end1 = ROI1.getRegion()
62
width1 = end1 - start1
63
start2, end2 = ROI2.getRegion()
64
width2 = end2 - start2
65
p["width ROI 1 in px"] = width1
66
p["width ROI 1 in mm"] = width1 * p["px2mm"]
67
p["width ROI 2 in px"] = width2
68
p["width ROI 2 in mm"] = width2 * p["px2mm"]
68
p["ROI1 start"], p["ROI1 stop"] = ROI1.getRegion()
69
p["width ROI 1 in px"] = p["ROI1 stop"] - p["ROI1 start"]
70
p["width ROI 1 in mm"] = p["width ROI 1 in px"] * p["px2mm"]
72
p["ROI2 start"], p["ROI2 stop"] = ROI2.getRegion()
73
p["width ROI 2 in px"] = p["ROI2 stop"] - p["ROI2 start"]
74
p["width ROI 2 in mm"] = p["width ROI 2 in px"] * p["px2mm"]
70
76
p["distance ROI1 -- ROI2"] = (np.mean(ROI2.getRegion()) - np.mean(ROI1.getRegion())) * p["px2mm"]
87
93
layoutVL.addWidget(btnROI1) # button goes in upper-left
88
94
layoutVL.addWidget(btnROI2) # button goes in upper-left
89
95
layoutVL.addWidget(btnSave)
96
layoutVL.addWidget(btnSaveConfig)
97
layoutVL.addWidget(btnRestoreConfig)
90
98
#layout.addWidget(listw) # list widget goes in bottom-left
91
99
layoutVR.addWidget(plotAll)
92
100
layoutVR.addWidget(plot) # plot goes on right side, spanning 3 rows
97
105
def clickedBtnROI1(btnROI1):
98
106
print("button clicked!", ROI1.getRegion())
99
from trackROI import TrackROI
107
#from trackROI_OpenCV import TrackROI
100
108
with pg.BusyCursor():
101
109
t1 = TrackROI(data, int(ROI1.getRegion()[0]), int(ROI1.getRegion()[1]))
103
111
curve1.setData(x, t1.displacements * p["px2mm"])
114
# --- indicate the path of displaced ROI1 on image ---
116
x0 = np.mean(ROI1.getRegion())
118
checkROI1 = pg.ScatterPlotItem(size=2, pen=pg.mkPen(None), brush=pg.mkBrush(0, 255, 0, 120))
121
for i in xrange(numFrames):
122
spot = {'pos': (x0 + t1.displacements[i], i)}
125
checkROI1.addPoints(spots)
126
plotAll.addItem(checkROI1)
105
128
xmin, xmax = velRange1.getRegion()
106
129
indices = np.where(np.logical_and(x > xmin, x < xmax))
107
130
slope, intercept, r_value, p_value, std_err = stats.linregress(x[indices],t1.displacements[indices]* p["px2mm"])
108
print "linear velocity of ROI1 in selected range is ", slope
131
print("linear velocity of ROI1 in selected range is ", slope)
109
132
p["velocity ROI 1"] = slope
110
133
plotTrack1.plot((xmin, xmax), (intercept + slope * xmin, intercept + slope * xmax))
112
135
# also update difference of ROI1 and ROI2
113
136
x1, y1 = curve1.getData()
114
137
x2, y2 = curve2.getData()
115
curve3.setData(x, y2 - y1)
138
curve3.setData(x, (y2 - y1))
117
140
def clickedBtnROI2(btnROI2):
118
141
print("button 2 clicked!", ROI2.getRegion())
119
from trackROI import TrackROI
142
#from trackROI import TrackROI
120
143
with pg.BusyCursor():
121
144
t2 = TrackROI(data, int(ROI2.getRegion()[0]), int(ROI2.getRegion()[1]))
126
149
x1, y1 = curve1.getData()
127
150
x2, y2 = curve2.getData()
128
151
curve3.setData(x, (y2 - y1))
153
# --- indicate the path of displaced ROI1 on image ---
155
x0 = np.mean(ROI2.getRegion())
157
checkROI2 = pg.ScatterPlotItem(size=2, pen=pg.mkPen(None), brush=pg.mkBrush(255, 255, 0, 120))
160
for i in xrange(numFrames):
161
spot = {'pos': (x0 + t2.displacements[i], i)}
164
checkROI2.addPoints(spots)
165
plotAll.addItem(checkROI2)
130
168
def saveToFile(btn):
131
169
x1, y1 = curve1.getData() # displacement of ROI1
137
L0 = np.mean(ROI2.getRegion()) - np.mean(ROI1.getRegion())
175
L0 = p["distance ROI1 -- ROI2"]
176
print "Saving with L0 = ", L0
138
177
strain = (y2 - y1) / L0
140
179
header = "linescan frequency = %f kHz\npixel length = %f mm\ngauge length = %f\ntime [msec], ROI1 displacement [mm], ROI2 displacement [mm], relative displacement [mm], strain [-]" % (p["scan rate"], p["px2mm"], L0*p["px2mm"])
141
np.savetxt(os.path.join(path, "linescan_analysis.dat"), np.column_stack((2*x, y1, y2, y3, strain)),
180
np.savetxt(os.path.join(path, "linescan_analysis.dat"), np.column_stack((x, y1, y2, y3, strain)),
143
print "wrote output file linescan_analysis.dat to directory [%s]" % (path)
182
print("wrote output file linescan_analysis.dat to directory [%s]" % (path))
185
state = p.saveState()
186
outfile = os.path.join(path, "configuration.pkl")
187
output = open(outfile, 'wb')
188
pickle.dump(state, output)
190
print "saved configuration state to file %s" % (outfile)
195
infile = os.path.join(path, "configuration.pkl")
196
pkl_file = open(infile, 'rb')
197
state = pickle.load(pkl_file)
198
p.restoreState(state) #, addChildren=False, removeChildren=False)
200
print "restored configuration state from file %s" % (infile)
201
print p["ROI1 start"]
202
ROI1.setRegion([p["ROI1 start"], p["ROI1 stop"]])
203
print ROI1.getRegion()
209
# p.restoreState(state, addChildren=add)
145
211
def change(param, changes):
146
212
""" called whenever a value in the parameter tree is changed
156
222
childName = '.'.join(path)
158
224
childName = param.name()
159
print(' path: %s' % path)
160
print(' parameter: %s' % childName)
161
print(' change: %s' % change)
162
print(' data: %s' % str(data))
225
print('* path: %s' % path)
226
print('* parameter: %s' % childName)
227
print('* change: %s' % change)
228
print('* data: %s' % str(data))
163
229
print(' ----------')
165
231
if childName == "Save Stress/Strain":
197
263
btnROI2 = QtGui.QPushButton('track ROI 2')
198
264
btnROI2.clicked.connect(clickedBtnROI2)
200
btnSave = QtGui.QPushButton('save to file')
266
btnSave = QtGui.QPushButton('save results to file')
201
267
btnSave.clicked.connect(saveToFile)
269
btnSaveConfig = QtGui.QPushButton('save config to file')
270
btnSaveConfig.clicked.connect(saveState)
272
btnRestoreConfig = QtGui.QPushButton('load config to file')
273
btnRestoreConfig.clicked.connect(loadState)
203
275
plotAll = pg.PlotWidget(title="all linescan frames")
204
276
imgAll = pg.ImageItem(np.transpose(data))
277
checkROI1 = pg.ScatterPlotItem(size=2, pen=pg.mkPen(None), brush=pg.mkBrush(0, 255, 0, 120))
278
checkROI2 = pg.ScatterPlotItem(size=2, pen=pg.mkPen(None), brush=pg.mkBrush(0, 255, 0, 120))
205
279
plotAll.addItem(imgAll)
206
280
plotAll.setLabel('left', "frame no.")
207
281
plotAll.setLabel('bottom', "pixel no.")
210
284
plot.setLabel('left', "no unit")
211
285
plot.setLabel('bottom', "pixel no.")
213
ROI1 = pg.LinearRegionItem([2413,2580])
214
ROI2 = pg.LinearRegionItem([3476,3800])
287
ROI1 = pg.LinearRegionItem([p["ROI1 start"],p["ROI1 stop"]])
288
ROI2 = pg.LinearRegionItem([p["ROI2 start"],p["ROI2 stop"]])
215
289
ROI1.setZValue(10)
216
290
ROI2.setZValue(10)
217
291
plot.addItem(ROI1)