~gcg/splithopkinsontools/trunk

« back to all changes in this revision

Viewing changes to trackROI_OpenCV.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:
 
1
import numpy as np
 
2
import copy
 
3
import cv2
 
4
 
 
5
class TrackROI():
 
6
    def __init__(self, image_data, ROI_start, ROI_stop):
 
7
        
 
8
        """
 
9
        track the displacement of a region of interest (ROI) over several frames 
 
10
        """
 
11
        
 
12
        self.ROI_start = ROI_start
 
13
        self.ROI_stop = ROI_stop
 
14
        
 
15
        # load files
 
16
        self.allFrames = copy.deepcopy(image_data)
 
17
        self.numFrames = np.shape(image_data)[0]
 
18
        #self.numFrames = 100
 
19
        print "number of frames in image: ", self.numFrames
 
20
        
 
21
        # load first frame and define ROI
 
22
        self.refFrame = self.yield_frame(0)
 
23
        self.numPixels = len(self.refFrame)
 
24
        
 
25
        # single out ROI by setting everything else in the first frame to zero
 
26
        self.ROI = self.refFrame
 
27
        self.ROI[:self.ROI_start] = 0.0
 
28
        self.ROI[self.ROI_stop:] = 0.0
 
29
        
 
30
        # create arrays to save data calculated by this program
 
31
        self.displacements = np.zeros(self.numFrames)
 
32
        self.optshift = 0
 
33
        
 
34
        
 
35
        template = self.refFrame[self.ROI_start:self.ROI_stop]
 
36
        halo = 20
 
37
        newShift = 0
 
38
        
 
39
        for i in xrange(self.numFrames):
 
40
            
 
41
            shiftedStart = self.ROI_start + newShift - halo
 
42
            shiftedStop = self.ROI_stop + newShift + halo
 
43
            #print "search area", shiftedStart, shiftedStop
 
44
            currentFrame = self.yield_frame(i)[shiftedStart:shiftedStop]
 
45
            res = cv2.matchTemplate(template,currentFrame,cv2.TM_CCOEFF_NORMED)
 
46
            #res = cv2.matchTemplate(template,currentFrame,cv2.TM_SQDIFF)
 
47
            #print np.shape(res)
 
48
    
 
49
            threshold = 0.1
 
50
            loc = np.where(res >= threshold)
 
51
            #print "loc:", loc[0] # indices mit ausreichend grossem Korrelationskoeffient
 
52
            #print "res@loc", res[loc]
 
53
            relative_shift = np.argmax(res) - halo # this is relative to the already shifted current image
 
54
            #print "most probable shift", shift, np.max(res)
 
55
            newShift += relative_shift
 
56
            print "newShift", i, newShift, np.max(res)
 
57
            self.displacements[i] = newShift
 
58
        
 
59
        #for i in xrange(self.numFrames):
 
60
        #    err, shifts, minerr, optshift = self.scan_all_possible_shifts(i)
 
61
        #    self.displacements[i] = optshift
 
62
            
 
63
        
 
64
       
 
65
    def yield_frame(self, i):
 
66
        """ read frame number i """
 
67
        
 
68
        image = self.allFrames[i,:]
 
69
        return image
 
70
        #return signal.detrend(image)
 
71
    
 
72
    
 
73
    def error(self, shift, currentFrame):
 
74
        """
 
75
        compute the error between the ROI defined in the reference image,
 
76
        and the current image, shifted by an integer number of pixels
 
77
        """
 
78
    
 
79
        # check that shift does not go beyond range of image (1024 pixels)
 
80
        assert self.ROI_start + shift >= 0    
 
81
        assert self.ROI_stop + shift <= self.numPixels
 
82
        
 
83
        # accumulate sum of differences between reference image and current image
 
84
        
 
85
        # SLOW version
 
86
        #sumDev = 0.0
 
87
        #for j in xrange(self.ROI_start, self.ROI_stop):
 
88
        #    sumDev += abs(currentFrame[j + shift] - self.refFrame[j])
 
89
        
 
90
        # FAST version
 
91
        cF = currentFrame[self.ROI_start+shift:self.ROI_stop+shift]
 
92
        rF = self.refFrame[self.ROI_start:self.ROI_stop]
 
93
        eVec = np.absolute(cF - rF)
 
94
        sumDev = np.sum(eVec)
 
95
            
 
96
        return sumDev
 
97
    
 
98
    def scan_all_possible_shifts(self, i):
 
99
        """
 
100
        Shift current frame i relative to reference frame throughout the entire possible shifting range.
 
101
        Compute the matching error within the ROI for each shift.
 
102
        Return errors and shifts arrays.
 
103
        """
 
104
        shift_start = -self.ROI_start
 
105
        shift_stop = self.numPixels - self.ROI_stop
 
106
        #print "shift start=%d, old optimum shift=%d, shift_stop=%d" % (shift_start, self.optshift, shift_stop)
 
107
        
 
108
        # restrict range of possible shifts
 
109
        shift_start = max(shift_start, self.optshift - 100) # bounded from the left by shift_start
 
110
        shift_stop = min(shift_stop, self.optshift + 100) # bounded on the right
 
111
        #print "RESTRICTED: shift start=%d, old optimum shift=%d, shift_stop=%d" % (shift_start, self.optshift, shift_stop)
 
112
    
 
113
        #print "shift range:", shift_start, shift_stop, shift_stop - shift_start
 
114
        currentFrame = self.yield_frame(i)
 
115
        err = np.zeros(shift_stop - shift_start)
 
116
        shifts = np.arange(shift_start, shift_stop)
 
117
        
 
118
        count = 0
 
119
        for shift in xrange(shift_start, shift_stop):
 
120
            thiserror =  self.error(shift, currentFrame)
 
121
            err[count] = thiserror
 
122
            count += 1 
 
123
            #print shift, thiserror
 
124
        
 
125
        # find the shift for which the error is minimal
 
126
        minidx = np.argmin(err) #index of minimum error 
 
127
        minerr = err[minidx] # min error
 
128
        optshift = shifts[minidx] #shift corresponding to min error
 
129
        self.optshift = optshift
 
130
        
 
131
        return np.asarray(err), shifts, minerr, optshift
 
 
b'\\ No newline at end of file'