webcamROI.py 5.43 KB
# -*- coding: utf-8 -*-
"""
Created on Fri Aug 10 14:21:33 2018

@author: Martindrech
"""


from pyqtgraph.Qt import QtCore
import numpy as np
import pyqtgraph as pg
import cv2
from PyQt5.QtCore import QTimer
#from myWidgets import anal_control_signal
import sys
from PyQt5.QtWidgets import QMainWindow, QApplication, QMessageBox, QPushButton, QGraphicsProxyWidget
#from myWidgets import anal_control_signal



class roiWindow(QMainWindow):
    
    def __init__(self, aoScan):
        super().__init__()
        
        self.aoScan = aoScan
        print( 'Analog output selected for roi analysis: %s' % (self.aoScan.name) )
        
        
        self.cap = cv2.VideoCapture(0)

        self.n = int(1e2)
        self.data = np.zeros(self.n)
        self.i = 0
        
        self.rois = []
        #self.rois.append(pg.EllipseROI([110, 10], [30, 20], pen=(3,9)))
        self.rois.append(pg.TestROI([500,  500], [100, 100], pen=(0,9)))
        
        
        self.initUI()
        
    def initUI(self):               
        
        ## create GUI
        self.w = pg.GraphicsWindow(size=(800,800), border=True)
        self.v = self.w.addViewBox(colspan=2)
        self.v.invertY(True)  ## Images usually have their Y-axis pointing downward
        self.v.setAspectLocked(True)
        self.im1 = pg.ImageItem(self.capture())
        self.v.addItem(self.im1)


        self.imgTimer = QTimer()
        self.imgTimer.timeout.connect(self.updateImage)
        self.imgTimer.start(2)

        self.im2 = pg.ImageItem()
        self.v2 = self.w.addViewBox(1,0)
        self.v2.addItem(self.im2)

        #plot real time
        self.p = self.w.addPlot(row = 3, col = 0,  title="Time plot")
        self.p.setRange(QtCore.QRectF(0, -10, 5000, 20)) 
        self.p.setAutoPan(y=True)
        self.p.setRange(xRange = (0, self.n), yRange = (0, 255))

        self.curve = self.p.plot(pen='y')
        
        self.pv = self.w.addPlot(row = 4, col = 0,  title = "Voltage plot")
        self.pv.setRange(QtCore.QRectF(0, -10, 5000, 20)) 
        self.pv.setAutoPan(y=True)
        self.curveVoltage = self.pv.plot(pen='y')
        self.voltageDataX = []
        self.voltageDataY = []
        self.aoScan.ScanTimer.timeout.connect(self.updateVoltagePlotvsI)
    
        self.optionsLayout = pg.LayoutWidget()
        self.eraseButton = QPushButton('Erase plot')
        self.eraseButton.clicked.connect(self.erasePlot)
        self.autoScaleButton = QPushButton('Autoscale')
        self.autoScaleButton.clicked.connect(self.autoScalePlot)
        self.optionsLayout.addWidget(self.eraseButton, 0, 0)
        self.optionsLayout.addWidget(self.autoScaleButton, 0, 1)
        self.optionsLayout.setGeometry(10,10,300,200)
        
        
        
        proxy = QGraphicsProxyWidget()
        proxy.setWidget(self.optionsLayout)
        
        self.w.addItem(proxy,row=5,col=0)
        
        
        self.lastRoi = None
        self.newData = 0
        
        ## Add each ROI to the scene and link its data to a plot curve with the same color
        for r in self.rois:
            self.v.addItem(r)
            r.sigRegionChanged.connect(self.updateRoi)
    
        self.w.show()
        self.w.closeEvent = self.myCloseEvent
    
    def updateVoltagePlotvsI(self):
            #plot against voltage
            
            self.voltageDataX = np.append(self.voltageDataX, self.aoScan.scan_step)
            self.voltageDataY = np.append(self.voltageDataY, self.newData)
            #○print(' Roi: ', self.voltageDataX[-1], self.voltageDataY[-1])
            
            
            self.curveVoltage.setData(self.voltageDataX, self.voltageDataY)
                
    def erasePlot(self):
         self.voltageDataX = []
         self.voltageDataY = []
    
    def autoScalePlot(self):
        x_min = float(self.aoScan.scan_sb_start.val)
        x_max = float(self.aoScan.scan_sb_stop.val)
        y_min = 0
        y_max = self.newData
        self.pv.setRange(xRange = (x_min, x_max), yRange = (y_min, y_max))
        
    def myCloseEvent(self, event):
        # this overrides the closeEvent method
        reply = QMessageBox.question(self, 'Message',
            "Quit roi analysis screen?", QMessageBox.Yes | 
            QMessageBox.No, QMessageBox.No)

        if reply == QMessageBox.Yes:
            self.imgTimer.stop()
            self.cap.release()
            cv2.destroyAllWindows()
            event.accept()
            
        else:
            event.ignore() 
       
            
    def capture(self):
        ret, frame = self.cap.read()
        #frame = cv2.resize(frame, None, fx = 0.5, fy = 0.5, interpolation = cv2.INTER_CUBIC)
        
        return frame[:, :, 0]

    def updateImage(self):
        self.im1.setImage(self.capture(), cmap = 'Gray')
        self.updateRoi(self.lastRoi)
        
    def updateRoi(self, roi):
        
        if roi is None:
            return
        self.lastRoi = roi
        roiSlice = roi.getArrayRegion(self.im1.image, img=self.im1)
        self.im2.setImage(roiSlice)
        self.newData = np.mean(roiSlice)
        self.data[self.i] = self.newData
        self.i = np.mod(self.i + 1, len(self.data))
        self.curve.setData(self.data)
        

    def updateRoiPlot(self, data):
        self.curve.setData(data)
        #app.processEvents()  ## force complete redraw for every plot
        
    
  
        
if __name__ == '__main__':
    
    ao = anal_control_signal('ao', 0)
    app = QApplication(sys.argv)
    ex = roiWindow(ao)
    sys.exit(app.exec_())