class QTiffStackView(QWidget): #the view which the user of the videoviewer sees. #This class contains relevant 'client side' attributes e.g. buttons to get a frame, a slide bar and a timer. These attributes submit requests to the QTiffStackController to give the next frame etc. The controller returns either the requested frame or an error message def __init__(self): super(QTiffStackView, self).__init__() #add the image display. This is a subclass of QLabel, where paintEvent is overriden. self.frame_view = FrameView() #self.frame_view.setSizePolicy(QSizePolicy.Expanding,QSizePolicy.Expanding) #add the slide bar which allows the user to manual flick through self.slideBar = QSlider(Qt.Horizontal) self.slideBar.setTickPosition(QSlider.TicksAbove) self.slideBar.setTracking(True) self.slideBar.setTickInterval(100) #add a counter which displays the frame which is currently displayed self.counter = QSpinBox() self.counter.setSingleStep(1) self.counter.setRange(self.slideBar.minimum(), self.slideBar.maximum()) #self explanatory self.play = QPushButton('Play') #when play button is pressed the timer takes control of the displaying of frames self.frametimer = QTimer() frame_rate = 30 self.frametimer.setInterval(frame_rate) #Add a sublayout to align the slidebar and frame counter next to eachother slidelyt = QHBoxLayout() slidelyt.addWidget(self.slideBar) slidelyt.addWidget(self.counter) #Add the main layout for the widget lyt = QVBoxLayout() lyt.addWidget(self.frame_view) lyt.addLayout(slidelyt) lyt.addWidget(self.play) self.setLayout(lyt) def updateRanges(self, maximum): assert type(maximum) == int self.slideBar.setMaximum(maximum) self.counter.setRange(self.slideBar.minimum(), self.slideBar.maximum())
class livestream(QWidget): i = 0 def __init__(self,qnd,images = None,annotations_on = True,annotate_coords = None,threshold_switch = False): QWidget.__init__(self) self.threshold_switch = threshold_switch self.video = images #frames buffer self.videobox = Label() if annotations_on and annotate_coords is not None: self.coords = annotate_coords self.videobox.switch = annotations_on self.videobox.activecoord = self.coords[0] if self.video is not None: self.videobox.activeframe = self.video[0] self.videobox.maxintens = self.video.shape[0] else: self.videobox.activeframe = np.loadtxt(os.getcwd() + '/defaultimage.txt') print(self.videobox.activeframe.shape) self.videobox.maxintens = np.max(self.videobox.activeframe) self.videobox.setGeometry(QtCore.QRect(70, 80, 310, 310)) self.videobox.h = 310 self.videobox.w = 310 self.lyt = QVBoxLayout() self.lyt.addWidget(self.videobox,5) self.setLayout(self.lyt) self.sl = QSlider(Qt.Horizontal) self.sl.setMinimum(0.0) if self.video is not None: self.sl.setMaximum(self.video.shape[0]) self.sl.valueChanged.connect(self.whenslidechanges) self.sl.setTickPosition(QSlider.TicksAbove) self.sl.setTracking(True) self.sl.setTickInterval(100) self.frame_counter = QDoubleSpinBox() if images is not None: self.frame = images[0] self.frame_counter.valueChanged.connect(self.video_time_update) self.frame_counter.setSingleStep(1) self.frame_counter.setRange(self.sl.minimum(),self.sl.maximum()) self.frame_counter.valueChanged.connect(self.sl.setValue) self.video_time = QDoubleSpinBox() self.video_time.setSingleStep(30) self.video_time.setRange(self.sl.minimum(),30*self.sl.maximum()) self.frameratetimer = QTimer() self.frameratetimer.setInterval(30) if self.video is not None: self.frameratetimer.timeout.connect(self.update_display) self.play_button = QPushButton('Play Video') self.play_button.clicked.connect(self.frameratetimer.start) self.stop_button = QPushButton('Stop Video') self.stop_button.clicked.connect(self.frameratetimer.stop) if self.video is not None: self.sl.valueChanged.connect(self.whenslidechanges) self.lyt.addWidget(self.play_button,0) self.lyt.addWidget(self.stop_button,1) self.lyt.addWidget(self.sl,2) self.lyt.addWidget(self.frame_counter,3) self.lyt.addWidget(self.video_time,4) self.show() def assign_images(self,images,centres = None): '''#first disconnect signals from eachother so nothing should change whilst video data is being updated self.sl.valueChanged.disconnect(self.video_time_update) self.frameratetimer.timeout.disconnect(self.update_display) self.frame_counter.valueChanged.disconnect(self.whenslidechanges) ''' self.video = images self.coords = centres self.videobox.activeframe = self.video[0] if self.coords is not None: self.videobox.activecoord = self.coords[0] #readjust slider and ticker values to dimensions of video self.sl.setMaximum(len(self.video)-1) self.frame_counter.setRange(self.sl.minimum(),self.sl.maximum()) self.video_time.setRange(self.sl.minimum(),30*self.sl.maximum()) #connect slider and timer etc. self.sl.valueChanged.connect(self.whenslidechanges) self.frameratetimer.timeout.connect(self.update_display) self.frame_counter.valueChanged.connect(self.video_time_update) self.videobox.maxintens = np.max(self.video) self.videobox.update() def update_display(self): if self.threshold_switch: frame = self.video[livestream.i] threshold = threshold_otsu(frame) mask = np.zeros_like(frame) mask[frame > threshold] = 1 self.videobox.maxintens = 1 self.videobox.activeframe = mask else: #if threshold switch is off display usual video, so change active frame source and reset maximum intensity for passing to qimage2ndarray self.videobox.activeframe = self.video[livestream.i] self.videobox.maxintens = np.max(self.video) try: self.videobox.activecoord = self.coords[livestream.i] if not self.videobox.switch: self.videobox.switch = True except: self.videobox.activecoord = None self.videobox.switch = False self.videobox.update() self.frame_counter.setValue(float(livestream.i)) livestream.i+=1 def whenslidechanges(self): if self.frameratetimer.isActive(): self.frameratetimer.stop() livestream.i = self.sl.value() self.update_display() livestream.i -=1 self.frameratetimer.start() else: livestream.i = self.sl.value() self.update_display() livestream.i -=1 def video_time_update(self): self.video_time.setValue(30*self.frame_counter.value()) def turn_on_threshold(self,threshold_switch): self.threshold_switch = threshold_switch self.update_display()
class TrapViewer(QWidget): i = 0 def __init__(self, qnd, images, trap_positions=None, labels=None): QWidget.__init__(self) self.video = images # This is a file object buffer containing the images self.trap_positions = trap_positions self.labels = labels self.videobox = Label(trap_positions, labels) self.videobox.activeframe = images.asarray(key=TrapViewer.i) try: self.videobox.maxintens = int(images.imagej_metadata['max']) self.videobox.maxintens = 15265 print(images.imagej_metadata) except KeyError: self.videobox.maxintens = int(np.max(self.videobox.activeframe)) self.videobox.setGeometry(QtCore.QRect(70, 80, 200, 200)) self.lyt = QVBoxLayout() self.lyt.addWidget(self.videobox, 5) self.setLayout(self.lyt) self.sl = QSlider(Qt.Horizontal) self.sl.setMinimum(0.0) self.sl.setMaximum(self.video.imagej_metadata['frames'] - 1) self.sl.setTickPosition(QSlider.TicksAbove) self.sl.setTracking(True) self.sl.setTickInterval(100) self.sl.valueChanged.connect(self.whenslidechanges) self.frame_counter = QDoubleSpinBox() self.frame = self.videobox.activeframe self.frame_counter.setSingleStep(1) self.frame_counter.setRange(self.sl.minimum(), self.sl.maximum() - 1) self.frame_counter.valueChanged.connect(self.sl.setValue) self.frame_counter.valueChanged.connect(self.video_time_update) self.video_time = QDoubleSpinBox() self.video_time.setSingleStep(30) self.video_time.setRange(self.sl.minimum(), 30 * self.sl.maximum() - 1) self.frameratetimer = QTimer() self.frameratetimer.setInterval(50) self.frameratetimer.timeout.connect(self.update_display) self.play_button = QPushButton('Play Video') self.play_button.clicked.connect(self.frameratetimer.start) self.stop_button = QPushButton('Stop Video') self.stop_button.clicked.connect(self.frameratetimer.stop) self.sl.valueChanged.connect(self.whenslidechanges) self.lyt.addWidget(self.play_button, 0) self.lyt.addWidget(self.stop_button, 1) self.lyt.addWidget(self.sl, 2) self.lyt.addWidget(self.frame_counter, 3) self.lyt.addWidget(self.video_time, 4) self.show() def update_display(self): self.frame = self.video.asarray(key=TrapViewer.i) self.videobox.activeframe = self.frame self.videobox.update() self.frame_counter.setValue(float(TrapViewer.i)) if TrapViewer.i < self.video.imagej_metadata['frames']: TrapViewer.i += 1 def whenslidechanges(self): if self.frameratetimer.isActive(): self.frameratetimer.stop() TrapViewer.i = self.sl.value() self.update_display() TrapViewer.i -= 1 self.frameratetimer.start() else: TrapViewer.i = self.sl.value() self.update_display() TrapViewer.i -= 1 def video_time_update(self): self.video_time.setValue(30 * self.frame_counter.value())