~gcg/splithopkinsontools/trunk

« back to all changes in this revision

Viewing changes to LineScanAnalysis.py

  • Committer: gcg
  • Date: 2018-03-16 16:21:26 UTC
  • Revision ID: gcg-20180316162126-uwdmokuwqfljive0
switched LineScanAnalysis to OpenCV

Show diffs side-by-side

added added

removed removed

Lines of Context:
6
6
import numpy as np
7
7
import os, sys
8
8
from scipy import misc, signal, stats
9
 
import glob
 
9
import glob, pickle
10
10
import copy
11
11
from pyqtgraph.Qt import QtGui, QtCore
12
12
import numpy as np
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
15
16
 
16
17
# only edit lines below:
17
 
path = "/home/gcg/SHTB/20171005_PP"
 
18
path = "/home/gcg/SHTB/Probe6.2"
18
19
 
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'},
27
32
          ]
28
33
 
29
34
 
33
38
    
34
39
    os.chdir(path)
35
40
    files = glob.glob("*.bmp")
 
41
    print(files)
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.")
39
45
        sys.exit(1)
40
46
    
41
 
    print files[0]
 
47
    print(files[0])
42
48
    
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))
 
51
    return image_data
45
52
    
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):
50
 
        j = 2*i
51
 
        k = j + 1
52
 
        new_data[i,:] = 0.5 * (image_data[j,:] + image_data[k,:])
53
 
        
54
 
    print "*** AVERAGED EVERY TWO LINES ***"
55
 
    
56
 
    #return image_data
 
54
#    nx, ny = np.shape(image_data)
 
55
#    new_data = np.zeros((int(nx/2), ny))
 
56
#    for i in xrange(nx/2 - 1):
 
57
#        j = 2*i
 
58
#        k = j + 1
 
59
#        new_data[i,:] = 0.5 * (image_data[j,:] + image_data[k,:])
 
60
#        
 
61
#    print("*** AVERAGED EVERY TWO LINES ***")
 
62
    
 
63
    
57
64
    return new_data
58
65
 
59
66
def updatePlot():
60
67
    global x
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"]
 
71
    
 
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"]
69
75
    
70
76
    p["distance ROI1 -- ROI2"] = (np.mean(ROI2.getRegion()) - np.mean(ROI1.getRegion())) * p["px2mm"]
71
77
    
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
96
104
 
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]))
102
110
        global curve1
103
111
        curve1.setData(x, t1.displacements * p["px2mm"])
104
112
        
 
113
        
 
114
        # --- indicate the path of displaced ROI1 on image ---
 
115
        global checkROI1
 
116
        x0 = np.mean(ROI1.getRegion())
 
117
        checkROI1.clear()
 
118
        checkROI1 = pg.ScatterPlotItem(size=2, pen=pg.mkPen(None), brush=pg.mkBrush(0, 255, 0, 120))
 
119
 
 
120
        spots = []
 
121
        for i in xrange(numFrames):
 
122
            spot = {'pos': (x0 + t1.displacements[i], i)}
 
123
            spots.append(spot)
 
124
        
 
125
        checkROI1.addPoints(spots)
 
126
        plotAll.addItem(checkROI1)
 
127
                
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))
111
134
        
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))
116
139
        
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]))
122
145
        global curve2
126
149
        x1, y1 = curve1.getData()
127
150
        x2, y2 = curve2.getData()
128
151
        curve3.setData(x, (y2 - y1))
 
152
        
 
153
        # --- indicate the path of displaced ROI1 on image ---
 
154
        global checkROI2
 
155
        x0 = np.mean(ROI2.getRegion())
 
156
        checkROI2.clear()
 
157
        checkROI2 = pg.ScatterPlotItem(size=2, pen=pg.mkPen(None), brush=pg.mkBrush(255, 255, 0, 120))
 
158
 
 
159
        spots = []
 
160
        for i in xrange(numFrames):
 
161
            spot = {'pos': (x0 + t2.displacements[i], i)}
 
162
            spots.append(spot)
 
163
        
 
164
        checkROI2.addPoints(spots)
 
165
        plotAll.addItem(checkROI2)
 
166
        
129
167
 
130
168
def saveToFile(btn):
131
169
    x1, y1 = curve1.getData() # displacement of ROI1
134
172
    
135
173
    #print x
136
174
    
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  
139
178
    
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)),
142
181
                header=header)
143
 
    print "wrote output file linescan_analysis.dat to directory [%s]" % (path)
 
182
    print("wrote output file linescan_analysis.dat to directory [%s]" % (path))
 
183
    
 
184
def saveState():
 
185
    state = p.saveState()
 
186
    outfile = os.path.join(path, "configuration.pkl")
 
187
    output = open(outfile, 'wb')
 
188
    pickle.dump(state, output)
 
189
    output.close()
 
190
    print "saved configuration state to file %s" % (outfile)
 
191
    
 
192
def loadState():
 
193
    #global p
 
194
    global ROI1
 
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)
 
199
    pkl_file.close()
 
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()
 
204
    updatePlot()
 
205
    
 
206
    
 
207
#def restore():
 
208
#    global state
 
209
#    p.restoreState(state, addChildren=add) 
144
210
    
145
211
def change(param, changes):
146
212
    """ called whenever a value in the parameter tree is changed
148
214
    global x
149
215
    x =  np.arange(N) * (1.0 / p["scan rate"])
150
216
    
151
 
    updatePlot()
 
217
    #updatePlot() # ... does not seem to work
152
218
    
153
219
    for param, change, data in changes:
154
220
        path = p.childPath(param)
156
222
            childName = '.'.join(path)
157
223
        else:
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('  ----------')
164
230
        
165
231
        if childName == "Save Stress/Strain":
197
263
btnROI2 = QtGui.QPushButton('track ROI 2')
198
264
btnROI2.clicked.connect(clickedBtnROI2)
199
265
 
200
 
btnSave = QtGui.QPushButton('save to file')
 
266
btnSave = QtGui.QPushButton('save results to file')
201
267
btnSave.clicked.connect(saveToFile)
202
268
 
 
269
btnSaveConfig = QtGui.QPushButton('save config to file')
 
270
btnSaveConfig.clicked.connect(saveState)
 
271
 
 
272
btnRestoreConfig = QtGui.QPushButton('load config to file')
 
273
btnRestoreConfig.clicked.connect(loadState)
 
274
 
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.")
212
286
 
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)