def lightROIBtn(self): frame, frameCrop = ft.checkEditing(self, self.frameNumber) self.lightROI_HT = ft.cv2.selectROI(frame) ft.cv2.destroyAllWindows() self.lightROI_HT_recorded = True
def filterParticleSldr(self): frame, frameCrop = ft.checkEditing(self, self.frameNumber) getFilteredFrame(self, frameCrop) self.lbl1_HT.setPixmap(ft.QPixmap.fromImage(self.frame)) self.lbl2_HT.setPixmap(ft.QPixmap.fromImage(self.frameBW)) self.filterParticleSldr_HT.setMaximum(int(self.particleSldrMax.text()))
def HSVSlider_released(self): frame, frameCrop = ft.checkEditing(self, self.frameNumber) getFilteredFrame(self, frameCrop) self.lbl1_HT.setPixmap(ft.QPixmap.fromImage(self.frame)) self.lbl2_HT.setPixmap(ft.QPixmap.fromImage(self.frameBW))
def HSVTracking(self): scale = True if not self.scaleIn.text(): scale = False msg = ft.QMessageBox(self) msg.setText('The scale [px/mm] has not been specified') # if self.pyqtVer == '5': # msg.exec_() # elif self.pyqtVer == '6': msg.exec() firstFrame = int(self.firstFrameIn.text()) lastFrame = int(self.lastFrameIn.text()) self.connectivity = self.connectivityGroup.checkedAction() self.connectivity = self.connectivity.text() currentFrame = firstFrame self.xRight_px = list() self.xLeft_px = list() self.xRight_mm = list() self.xLeft_mm = list() flameLength_mm = list() self.frameCount = list() flameArea = list() if self.exportVideo_HT.isChecked() or self.exportTrackOverlay_HT.isChecked( ): fps = (float(self.vFps)) / (int(self.skipFrameIn.text()) + 1) vName = self.fPath + '-trackedVideo.' + str( self.vFormat ) # alternative: 'output.{}'.format(vFormat); self.fNameLbl.text() fourcc = ft.cv2.VideoWriter_fourcc(*self.codec) size = (int(self.roiThreeIn.text()), int(self.roiFourIn.text())) # open and set properties vout = ft.cv2.VideoWriter() vout.open(vName, fourcc, fps, size, True) if scale: #this condition prevents crashes in case the scale is not specified xAxis_lbl1 = self.xAxis_lbl1.currentText() yAxis_lbl1 = self.yAxis_lbl1.currentText() xAxis_lbl2 = self.xAxis_lbl2.currentText() yAxis_lbl2 = self.yAxis_lbl2.currentText() while (currentFrame < lastFrame): # print('Frame #:', currentFrame) frame, frameCrop = ft.checkEditing(self, currentFrame) if self.filterLight_HT.isChecked() == True: if self.lightROI_HT_recorded == True: # looking for frames with a light on (which would increase the red and green channel values of the background) low = ([5, 5, 10] ) # blueLow, greenLow, redLow (see color tracking) high = ([255, 255, 255]) # blueHigh, greenHigh, redHigh low = ft.np.array( low, dtype='uint8') #this conversion is necessary high = ft.np.array(high, dtype='uint8') currentLightROI = frame[self.lightROI_HT[1]:( self.lightROI_HT[1] + self.lightROI_HT[3]), self.lightROI_HT[0]:( self.lightROI_HT[0] + self.lightROI_HT[2])] newMask = ft.cv2.inRange(currentLightROI, low, high) frame_light = ft.cv2.bitwise_and(currentLightROI, currentLightROI, mask=newMask) grayFrame_light = ft.cv2.cvtColor(frame_light, ft.cv2.COLOR_BGR2GRAY) (thresh_light, frameBW_light) = ft.cv2.threshold(grayFrame_light, 0, 255, ft.cv2.THRESH_BINARY) flamePx_light = ft.np.where(frameBW_light == [255]) #beta area_lightROI = int(self.lightROI_HT[3] * self.lightROI_HT[2]) else: msg = ft.QMessageBox(self) msg.setText( 'Before the tracking, please click on "Pick a bright region" to select a region where the light is visible.' ) # if self.pyqtVer == '5': # msg.exec_() # elif self.pyqtVer == '6': msg.exec() break if len( flamePx_light[0] ) < 0.5 * area_lightROI: #if the bright area is larger than the ROI area getFilteredFrame(self, frameCrop) print('frame counted') else: currentFrame = currentFrame + 1 + int( self.skipFrameIn.text()) print('frame not counted') continue else: getFilteredFrame(self, frameCrop) self.xRight_px.append(self.xRight) self.xLeft_px.append(self.xLeft) self.xRight_mm.append(self.xRight / float(self.scaleIn.text())) self.xLeft_mm.append(self.xLeft / float(self.scaleIn.text())) flameArea.append(self.flameArea) self.frameCount.append(currentFrame) if self.exportVideo_HT.isChecked( ) and not self.exportTrackOverlay_HT.isChecked(): vout.write(self.currentFrameRGB_HT) elif self.exportTrackOverlay_HT.isChecked(): #CAS Add Track lines over cropped video trackframe = ft.np.copy(frameCrop) # frame is 1080 x 1920 trackframe[:, min( self.xRight - 1 - int(self.roiOneIn.text( )), ft.np.size(trackframe, 1) )] = 255 # white out line to mark where tracked flame, using relative distance vout.write(trackframe) # print('Progress: ', round((currentFrame - firstFrame)/(lastFrame - firstFrame) * 10000)/100, '%') print('Progress: ', round((currentFrame - firstFrame) / (lastFrame - firstFrame) * 10000) / 100, '%', '(Frame #: ', currentFrame, ')', end='\r') currentFrame = currentFrame + 1 + int(self.skipFrameIn.text()) try: self.flameArea = [ areaN / (float(self.scaleIn.text())**2) for areaN in flameArea ] self.flameArea = ft.np.round(self.flameArea, 3) self.flameArea = self.flameArea.tolist() self.timeCount = [ frameN / float(self.vFpsLbl.text()) for frameN in self.frameCount ] except: pass # CAS Add tracking line from flameTracker.py #if self.HSVTrackingValue == True: # # Start tracking for export # #HSVTracking(self) # # #findFlameEdges_HT(self, frameBW, flamePx) # getHSVFilteredFrame(self, currentFrame) # trackframe = frameCrop # frame is 1080 x 1920 # import numpy # #print(type(frame), numpy.size(frame, 0), 'x', numpy.size(frame, 1)) # #print(type(frameCrop), numpy.size(frameCrop, 0), 'x', numpy.size(frameCrop, 1)) # trackframe[:, min(self.xRight-1 - int(self.roiOneIn.text()), numpy.size(trackframe,1))] = 255 # white out line to mark where tracked flame, using relative distance # #if self.xRight-1 > numpy.size(trackframe,1): # # print('xRight would have errored here with value:', self.xRight) # #cv2.imshow('Frame_With_255_TrackLine', trackframe) for i in range(len(self.xRight_mm)): flameLength_mm.append(abs(self.xRight_mm[i] - self.xLeft_mm[i])) flameLength_mm = ft.np.round(flameLength_mm, 2) self.flameLength_mm = flameLength_mm.tolist() print('Progress: 100 % - Tracking completed') self.msgLabel.setText('Tracking completed') if self.exportVideo_HT.isChecked( ) or self.exportTrackOverlay_HT.isChecked(): vout.release() self.msgLabel.setText('Tracking completed and video created.') # the following approach to calculate the spread rate is the same one used for lumaTracking movAvgPt = int( self.movAvgIn_HT.text() ) #this number is half of the interval considered for the spread rate (movAvgPt = 2 means I am considering a total of 5 points (my point, 2 before and 2 after)) self.spreadRateRight = list() self.spreadRateLeft = list() if movAvgPt == 0: for i in range(len(self.timeCount) - 1): xCoeffRight = ft.np.polyfit(self.timeCount[(i):(i + 2)], self.xRight_mm[(i):(i + 2)], 1) xCoeffLeft = ft.np.polyfit(self.timeCount[(i):(i + 2)], self.xLeft_mm[(i):(i + 2)], 1) self.spreadRateRight.append(xCoeffRight[0]) self.spreadRateLeft.append(xCoeffLeft[0]) #repeat the last value self.spreadRateRight.append(xCoeffRight[0]) self.spreadRateLeft.append(xCoeffLeft[0]) else: #here we calculate the instantaneous spread rate based on the moving avg. I also included the initial and final points for i in range(len(self.timeCount)): if i - movAvgPt < 0: xCoeffRight = ft.np.polyfit( self.timeCount[0:(i + movAvgPt + 1)], self.xRight_mm[0:(i + movAvgPt + 1)], 1) xCoeffLeft = ft.np.polyfit( self.timeCount[0:(i + movAvgPt + 1)], self.xLeft_mm[0:(i + movAvgPt + 1)], 1) self.spreadRateRight.append(xCoeffRight[0]) self.spreadRateLeft.append(xCoeffLeft[0]) elif i >= movAvgPt: xCoeffRight = ft.np.polyfit( self.timeCount[(i - movAvgPt):(i + movAvgPt + 1)], self.xRight_mm[(i - movAvgPt):(i + movAvgPt + 1)], 1) xCoeffLeft = ft.np.polyfit( self.timeCount[(i - movAvgPt):(i + movAvgPt + 1)], self.xLeft_mm[(i - movAvgPt):(i + movAvgPt + 1)], 1) self.spreadRateRight.append(xCoeffRight[0]) self.spreadRateLeft.append(xCoeffLeft[0]) elif i + movAvgPt > len(self.timeCount): xCoeffRight = ft.np.polyfit( self.timeCount[(i - movAvgPt):], self.xRight_mm[(i - movAvgPt):], 1) xCoeffLeft = ft.np.polyfit(self.timeCount[(i - movAvgPt):], self.xLeft_mm[(i - movAvgPt):], 1) self.spreadRateRight.append(xCoeffRight[0]) self.spreadRateLeft.append(xCoeffLeft[0]) self.spreadRateRight = ft.np.round(self.spreadRateRight, 3) self.spreadRateRight = self.spreadRateRight.tolist() self.spreadRateLeft = ft.np.round(self.spreadRateLeft, 3) self.spreadRateLeft = self.spreadRateLeft.tolist() self.plot1_HT.setLabel('left', str(yAxis_lbl1), color='black', size=14) self.plot1_HT.setLabel('bottom', str(xAxis_lbl1), color='black', size=14) self.plot1_HT.getAxis('bottom').setPen(color=(0, 0, 0)) self.plot1_HT.getAxis('left').setPen(color=(0, 0, 0)) self.plot1_HT.addLegend( offset=[1, 0.1] ) # background color modified in line 122 and 123 of Versions/3.7/lib/python3.7/site-packages/pyqtgraph/graphicsItems self.plot2_HT.setLabel('left', str(yAxis_lbl2), color='black', size=14) self.plot2_HT.setLabel('bottom', str(xAxis_lbl2), color='black', size=14) self.plot2_HT.getAxis('bottom').setPen(color=(0, 0, 0)) self.plot2_HT.getAxis('left').setPen(color=(0, 0, 0)) self.plot2_HT.addLegend( offset=[1, 0.1] ) # background color modified in line 122 and 123 of Versions/3.7/lib/python3.7/site-packages/pyqtgraph/graphicsItems xPlot1, yRight1, yLeft1 = selectAxes(self, xAxis_lbl1, yAxis_lbl1) xPlot2, yRight2, yLeft2 = selectAxes(self, xAxis_lbl2, yAxis_lbl2) if yAxis_lbl1 == 'Flame length [mm]': HSVTrackingPlot(self.plot1_HT, xPlot1, yRight1, 'flame length', 'o', 'b') elif yAxis_lbl1 == 'Flame area [mm2]': HSVTrackingPlot(self.plot1_HT, xPlot1, yRight1, 'flame area', 'o', 'b') else: HSVTrackingPlot(self.plot1_HT, xPlot1, yRight1, 'right edge', 'o', 'b') HSVTrackingPlot(self.plot1_HT, xPlot1, yLeft1, 'left edge', 't', 'r') if yAxis_lbl2 == 'Flame length [mm]': HSVTrackingPlot(self.plot2_HT, xPlot2, yRight2, 'flame length', 'o', 'b') elif yAxis_lbl2 == 'Flame area [mm2]': HSVTrackingPlot(self.plot2_HT, xPlot2, yRight2, 'flame area', 'o', 'b') else: HSVTrackingPlot(self.plot2_HT, xPlot2, yRight2, 'right edge', 'o', 'b') HSVTrackingPlot(self.plot2_HT, xPlot2, yLeft2, 'left edge', 't', 'r') self.win1_HT.setCurrentIndex( 1) #to activate the preview tab in the analysis box self.win2_HT.setCurrentIndex(1)
def startTracking(self): global clk, nClicks #, flameDir # select the variables to plot based on user input xAxis_lbl1 = self.xAxis_lbl1.currentText() yAxis_lbl1 = self.yAxis_lbl1.currentText() xAxis_lbl2 = self.xAxis_lbl2.currentText() yAxis_lbl2 = self.yAxis_lbl2.currentText() self.plot1_MT.clear() self.plot1_MT.setLabel('left', str(yAxis_lbl1), color='black', size=14) self.plot1_MT.setLabel('bottom', str(xAxis_lbl1), color='black', size=14) self.plot1_MT.getAxis('bottom').setPen(color=(0, 0, 0)) self.plot1_MT.getAxis('left').setPen(color=(0, 0, 0)) self.plot1_MT.addLegend(offset=[1, 0.1]) firstFrame = int(self.firstFrameIn.text()) lastFrame = int(self.lastFrameIn.text()) # scale = True #Set up the first frame for analysis and clk for the mouse event currentFrame = firstFrame clk = False # False unless the mouse is clicked posX = dict() posX_mm = dict() posY = dict() posY_mm = dict() frameCount = dict() timeCount = dict() # find out how many points to be selected in each frame try: nClicks = int(self.nClicksLbl.text()) except: nClicks = 1 self.msgLabel.setText('Clicks not specified (=1)') while (currentFrame < lastFrame): print('Frame #:', currentFrame, end='\r') if not self.scaleIn.text(): # scale = False msg = ft.QMessageBox(self) msg.setText('The scale [px/mm] has not been specified') msg.exec() break frame, frameCrop = ft.checkEditing(self, currentFrame) if self.lightROI_MT_recorded == True: # looking for frames with a light on (which would increase the red and green channel values of the background) # low and high are the thresholds for each color channel low = ([5, 5, 10]) # blueLow, greenLow, redLow high = ([255, 255, 255]) # blueHigh, greenHigh, redHigh low = ft.np.array(low, dtype='uint8') #this conversion is necessary high = ft.np.array(high, dtype='uint8') currentLightROI = frame[self.lightROI_MT[1]:(self.lightROI_MT[1] + self.lightROI_MT[3]), self.lightROI_MT[0]:(self.lightROI_MT[0] + self.lightROI_MT[2])] newMask = ft.cv2.inRange(currentLightROI, low, high) frame_light = ft.cv2.bitwise_and(currentLightROI, currentLightROI, mask=newMask) grayFrame_light = ft.cv2.cvtColor(frame_light, ft.cv2.COLOR_BGR2GRAY) (thresh_light, BW_light) = ft.cv2.threshold(grayFrame_light, 0, 255, ft.cv2.THRESH_BINARY) flamePx_light = ft.np.where(BW_light == [255]) area_light = int(self.lightROI_MT[3] * self.lightROI_MT[2]) # if lightStatus == 'lightOff': if self.filterLight_MT.currentText() == 'Frames light off': if len(flamePx_light[0]) > 0.5 * area_light: #avoid this frame currentFrame = currentFrame + 1 + int( self.skipFrameIn.text()) continue # elif lightStatus == 'lightOn': elif self.filterLight_MT.currentText() == 'Frames light on': if len(flamePx_light[0]) < 0.5 * area_light: #avoid this frame currentFrame = currentFrame + 1 + int( self.skipFrameIn.text()) continue # create the window and the line over the first point clicked ft.cv2.namedWindow('manualTracking', ft.cv2.WINDOW_AUTOSIZE) ft.cv2.setWindowTitle('manualTracking', f'MT, frame #: {currentFrame}') # ft.cv2.namedWindow(f'ManualTracking; frame #: {currentFrame}', ft.cv2.WINDOW_AUTOSIZE) ft.cv2.setMouseCallback('manualTracking', click) # ft.cv2.setMouseCallback(f'ManualTracking; frame #: {currentFrame}', click) #if currentFrame > firstFrame: if len(posY) > 0: for n in range(nClicks): if self.showLines_MT.isChecked() == True: ft.cv2.line(frameCrop, (0, int(posY[str(n + 1)][0])), (int( self.roiThreeIn.text()), int(posY[str(n + 1)][0])), (0, 245, 184), 2) ft.cv2.imshow('manualTracking', frameCrop) # ft.cv2.imshow(f'ManualTracking; frame #: {currentFrame}',frameCrop) self.msgLabel.setText('Tracking started, press (Esc) to quit.') for n in range(nClicks): # wait for the mouse event or 'escape' key while (True): if clk == True: clk = False # the zero location changes based on the flame direction if self.directionBox.currentText() == 'Left to right': xClick = xPos + int(self.roiOneIn.text()) elif self.directionBox.currentText() == 'Right to left': xClick = self.vWidth - int(self.roiOneIn.text()) - xPos break if ft.cv2.waitKey(1) == 27: #ord('q') ft.cv2.destroyAllWindows() return # update each position and frame list for the current click if str(n + 1) in posX: posX[str(n + 1)].append(xClick) posX_mm[str(n + 1)].append(xClick / float(self.scaleIn.text())) posY[str(n + 1)].append(yPos) posY_mm[str(n + 1)].append(yPos / float(self.scaleIn.text())) if n == 0: #frames and time are the same for all the clicks frameCount[str(n + 1)].append(currentFrame) timeCount[str(n + 1)].append(currentFrame / float(self.vFpsLbl.text())) else: posX[str(n + 1)] = [xClick] posX_mm[str(n + 1)] = [xClick / float(self.scaleIn.text())] posY[str(n + 1)] = [yPos] posY_mm[str(n + 1)] = [yPos / float(self.scaleIn.text())] if n == 0: #frames and time are the same for all the clicks frameCount[str(n + 1)] = [currentFrame] timeCount[str(n + 1)] = [ currentFrame / float(self.vFpsLbl.text()) ] currentFrame = currentFrame + 1 + int(self.skipFrameIn.text()) print('Tracking completed') self.msgLabel.setText('Tracking completed') if len(timeCount) == 0: msg = ft.QMessageBox(self) msg.setText( 'No frames were detected, please check ROI size and light settings.' ) msg.exec() ft.cv2.destroyAllWindows() self.posX_px = posX self.posX_plot = posX_mm self.frames_plot = frameCount self.time_plot = timeCount # moving average of the spread rate values self.spreadRate = dict() # if scale: for n in range(nClicks): for i in range(len(timeCount['1']) - 1): xCoeff = ft.np.polyfit(timeCount['1'][(i):(i + 2)], posX_mm[str(n + 1)][(i):(i + 2)], 1) spreadRate = xCoeff[0] if str(n + 1) in self.spreadRate: self.spreadRate[str(n + 1)].append(spreadRate) else: self.spreadRate[str(n + 1)] = [spreadRate] #repeat the last value self.spreadRate[str(n + 1)].append(xCoeff[0]) self.lbl2_MT.clear() self.lbl2_MT.addLegend( offset=[1, 0.1] ) # background color modified in line 122 and 123 of python3.7/site-packages/pyqtgraph/graphicsItems color = ['b', 'r', 'k', 'g', 'c', 'y'] for n in range(nClicks): name = 'click{}'.format([n + 1]) try: clr = color[n] except: if n > len(color): self.msgLabel.setText('Not enough colors for plotting.') xPlot1, yPlot1 = selectAxes(self, xAxis_lbl1, yAxis_lbl1, n) xPlot2, yPlot2 = selectAxes(self, xAxis_lbl2, yAxis_lbl2, n) # manualTrackingPlot(self.lbl1_MT, self.time_plot['1'], self.posX_plot[str(n+1)], name, 'o', clr) manualTrackingPlot(self.plot1_MT, xPlot1, yPlot1, name, 'o', clr) # manualTrackingPlot(self.lbl2_MT, self.time_plot['1'], self.spreadRate[str(n+1)], name, 'o', clr) manualTrackingPlot(self.lbl2_MT, xPlot2, yPlot2, name, 'o', clr) self.plot1_MT.show() self.win1_MT.setCurrentIndex(1)
def RGBTracking(self): scale = True if not self.scaleIn.text(): scale = False msg = ft.QMessageBox(self) msg.setText('The scale [px/mm] has not been specified') msg.exec() firstFrame = int(self.firstFrameIn.text()) lastFrame = int(self.lastFrameIn.text()) self.connectivity = self.connectivityGroup.checkedAction() self.connectivity = self.connectivity.text() currentFrame = firstFrame self.xRight_px = list() self.xLeft_px = list() self.xRight_mm = list() self.xLeft_mm = list() flameLength_mm = list() self.frameCount = list() flameArea = list() if self.exportVideo_RT.isChecked(): fps = (float(self.vFps)) / (int(self.skipFrameIn.text()) + 1) vName = self.fPath + '-trackedVideo.' + str(self.vFormat) fourcc = ft.cv2.VideoWriter_fourcc(*self.codec) size = (int(self.roiThreeIn.text()), int(self.roiFourIn.text())) # open and set properties vout = ft.cv2.VideoWriter() vout.open(vName, fourcc, fps, size, True) if scale: #this condition prevents crashes in case the scale is not specified xAxis_lbl1 = self.xAxis_lbl1.currentText() yAxis_lbl1 = self.yAxis_lbl1.currentText() xAxis_lbl2 = self.xAxis_lbl2.currentText() yAxis_lbl2 = self.yAxis_lbl2.currentText() while (currentFrame < lastFrame): # print('Frame #:', currentFrame) frame, frameCrop = ft.checkEditing(self, currentFrame) if self.filterLight_RT.isChecked() == True: if self.lightROI_RT_recorded == True: #beta # looking for frames with a light on (which would increase the red and green channel values of the background) low = ([5, 5, 10]) # blueLow, greenLow, redLow high = ([255, 255, 255]) # blueHigh, greenHigh, redHigh low = ft.np.array( low, dtype='uint8') #this conversion is necessary high = ft.np.array(high, dtype='uint8') currentLightROI = frame[self.lightROI_RT[1]:( self.lightROI_RT[1] + self.lightROI_RT[3]), self.lightROI_RT[0]:( self.lightROI_RT[0] + self.lightROI_RT[2])] newMask = ft.cv2.inRange(currentLightROI, low, high) frame_light = ft.cv2.bitwise_and(currentLightROI, currentLightROI, mask=newMask) grayFrame_light = ft.cv2.cvtColor(frame_light, ft.cv2.COLOR_BGR2GRAY) (thresh_light, frameBW_light) = ft.cv2.threshold(grayFrame_light, 0, 255, ft.cv2.THRESH_BINARY) flamePx_light = ft.np.where(frameBW_light == [255]) #beta area_lightROI = int(self.lightROI_RT[3] * self.lightROI_RT[2]) else: msg = ft.QMessageBox(self) msg.setText( 'Before the tracking, please click on "Pick a bright region" to select a region where the light is visible.' ) msg.exec() break if len( flamePx_light[0] ) < 0.5 * area_lightROI: #if the bright area is larger than the ROI area getFilteredFrame(self, frameCrop) else: currentFrame = currentFrame + 1 + int( self.skipFrameIn.text()) continue else: getFilteredFrame(self, frameCrop) self.xRight_px.append(self.xRight) self.xLeft_px.append(self.xLeft) self.xRight_mm.append(self.xRight / float(self.scaleIn.text())) self.xLeft_mm.append(self.xLeft / float(self.scaleIn.text())) flameArea.append(self.flameArea) self.frameCount.append(currentFrame) if self.exportVideo_RT.isChecked(): vout.write(self.currentFrameRGB_RT) print('Progress: ', round((currentFrame - firstFrame) / (lastFrame - firstFrame) * 10000) / 100, '%', '(Frame #: ', currentFrame, ')', end='\r') currentFrame = currentFrame + 1 + int(self.skipFrameIn.text()) try: self.flameArea = [ areaN / (float(self.scaleIn.text())**2) for areaN in flameArea ] self.flameArea = ft.np.round(self.flameArea, 3) self.flameArea = self.flameArea.tolist() self.timeCount = [ frameN / float(self.vFpsLbl.text()) for frameN in self.frameCount ] except: pass for i in range(len(self.xRight_mm)): flameLength_mm.append(abs(self.xRight_mm[i] - self.xLeft_mm[i])) flameLength_mm = ft.np.round(flameLength_mm, 2) self.flameLength_mm = flameLength_mm.tolist() print('Progress: 100 % - Tracking completed') self.msgLabel.setText('Tracking completed') if self.exportVideo_RT.isChecked(): vout.release() self.msgLabel.setText('Tracking completed and video created.') # the following approach to calculate the spread rate is the same one used for lumaTracking movAvgPt = int( self.movAvgIn_RT.text() ) #this number is half of the interval considered for the spread rate (movAvgPt = 2 means I am considering a total of 5 points (my point, 2 before and 2 after)) self.spreadRateRight = list() self.spreadRateLeft = list() if movAvgPt == 0: for i in range(len(self.timeCount) - 1): xCoeffRight = ft.np.polyfit(self.timeCount[(i):(i + 2)], self.xRight_mm[(i):(i + 2)], 1) xCoeffLeft = ft.np.polyfit(self.timeCount[(i):(i + 2)], self.xLeft_mm[(i):(i + 2)], 1) self.spreadRateRight.append(xCoeffRight[0]) self.spreadRateLeft.append(xCoeffLeft[0]) #repeat the last value self.spreadRateRight.append(xCoeffRight[0]) self.spreadRateLeft.append(xCoeffLeft[0]) else: #here we calculate the instantaneous spread rate based on the moving avg. I also included the initial and final points for i in range(len(self.timeCount)): if i - movAvgPt < 0: xCoeffRight = ft.np.polyfit( self.timeCount[0:(i + movAvgPt + 1)], self.xRight_mm[0:(i + movAvgPt + 1)], 1) xCoeffLeft = ft.np.polyfit( self.timeCount[0:(i + movAvgPt + 1)], self.xLeft_mm[0:(i + movAvgPt + 1)], 1) self.spreadRateRight.append(xCoeffRight[0]) self.spreadRateLeft.append(xCoeffLeft[0]) elif i >= movAvgPt: xCoeffRight = ft.np.polyfit( self.timeCount[(i - movAvgPt):(i + movAvgPt + 1)], self.xRight_mm[(i - movAvgPt):(i + movAvgPt + 1)], 1) xCoeffLeft = ft.np.polyfit( self.timeCount[(i - movAvgPt):(i + movAvgPt + 1)], self.xLeft_mm[(i - movAvgPt):(i + movAvgPt + 1)], 1) self.spreadRateRight.append(xCoeffRight[0]) self.spreadRateLeft.append(xCoeffLeft[0]) elif i + movAvgPt > len(self.timeCount): xCoeffRight = ft.np.polyfit( self.timeCount[(i - movAvgPt):], self.xRight_mm[(i - movAvgPt):], 1) xCoeffLeft = ft.np.polyfit(self.timeCount[(i - movAvgPt):], self.xLeft_mm[(i - movAvgPt):], 1) self.spreadRateRight.append(xCoeffRight[0]) self.spreadRateLeft.append(xCoeffLeft[0]) self.spreadRateRight = ft.np.round(self.spreadRateRight, 3) self.spreadRateRight = self.spreadRateRight.tolist() self.spreadRateLeft = ft.np.round(self.spreadRateLeft, 3) self.spreadRateLeft = self.spreadRateLeft.tolist() self.plot1_RT.setLabel('left', str(yAxis_lbl1), color='black', size=14) self.plot1_RT.setLabel('bottom', str(xAxis_lbl1), color='black', size=14) self.plot1_RT.getAxis('bottom').setPen(color=(0, 0, 0)) self.plot1_RT.getAxis('left').setPen(color=(0, 0, 0)) self.plot1_RT.addLegend(offset=[1, 0.1]) self.plot2_RT.setLabel('left', str(yAxis_lbl2), color='black', size=14) self.plot2_RT.setLabel('bottom', str(xAxis_lbl2), color='black', size=14) self.plot2_RT.getAxis('bottom').setPen(color=(0, 0, 0)) self.plot2_RT.getAxis('left').setPen(color=(0, 0, 0)) self.plot2_RT.addLegend(offset=[1, 0.1]) xPlot1, yRight1, yLeft1 = selectAxes(self, xAxis_lbl1, yAxis_lbl1) xPlot2, yRight2, yLeft2 = selectAxes(self, xAxis_lbl2, yAxis_lbl2) if yAxis_lbl1 == 'Flame length [mm]': RGBTrackingPlot(self.plot1_RT, xPlot1, yRight1, 'flame length', 'o', 'b') elif yAxis_lbl1 == 'Flame area [mm2]': RGBTrackingPlot(self.plot1_RT, xPlot1, yRight1, 'flame area', 'o', 'b') else: RGBTrackingPlot(self.plot1_RT, xPlot1, yRight1, 'right edge', 'o', 'b') RGBTrackingPlot(self.plot1_RT, xPlot1, yLeft1, 'left edge', 't', 'r') if yAxis_lbl2 == 'Flame length [mm]': RGBTrackingPlot(self.plot2_RT, xPlot2, yRight2, 'flame length', 'o', 'b') elif yAxis_lbl2 == 'Flame area [mm2]': RGBTrackingPlot(self.plot2_RT, xPlot2, yRight2, 'flame area', 'o', 'b') else: RGBTrackingPlot(self.plot2_RT, xPlot2, yRight2, 'right edge', 'o', 'b') RGBTrackingPlot(self.plot2_RT, xPlot2, yLeft2, 'left edge', 't', 'r') self.win1_RT.setCurrentIndex( 1) #to activate the preview tab in the analysis box self.win2_RT.setCurrentIndex(1)