smooth image update: use monitor callbacks to avoid block of ui when waiting for frame
This commit is contained in:
30
camera.py
30
camera.py
@@ -107,6 +107,7 @@ class epics_cam(object):
|
||||
print('camera.new_frame_pv_cb')
|
||||
|
||||
def get_image(self):
|
||||
_log.warning('this can be very slow. Use callbacks if possible.')
|
||||
try:
|
||||
pv_pic=self.getPv('FPICTURE')
|
||||
except AttributeError:
|
||||
@@ -120,13 +121,7 @@ class epics_cam(object):
|
||||
pv_pic=self.getPv('FPICTURE')
|
||||
sz=self._sz
|
||||
pic = pv_pic.get(count=sz[0]*sz[1], as_numpy=True).reshape(sz[::-1])
|
||||
f=np.array(((0, 0, 0, 0, 0),
|
||||
(0, 1, 1, 1, 0),
|
||||
(0, 1, 0, 0, 0),
|
||||
(0, 1, 1, 0, 0),
|
||||
(0, 1, 0, 0, 0),
|
||||
(0, 0, 0, 0, 0),), pic.dtype)
|
||||
pic[0:6, 0:5]=f*255
|
||||
epics_cam.set_fiducial(pic,255)
|
||||
|
||||
except AttributeError as e:
|
||||
_log.warning("failed to fetch image")
|
||||
@@ -219,6 +214,16 @@ class epics_cam(object):
|
||||
pv_cam.put(CameraStatus.RUNNING, wait=True)
|
||||
self.update_size()
|
||||
|
||||
@staticmethod
|
||||
def set_fiducial(pic,val):
|
||||
# fiducial test
|
||||
f=np.array(((0, 0, 0, 0, 0),
|
||||
(0, 1, 1, 1, 0),
|
||||
(0, 1, 0, 0, 0),
|
||||
(0, 1, 1, 0, 0),
|
||||
(0, 1, 0, 0, 0),
|
||||
(0, 0, 0, 0, 0),), pic.dtype)
|
||||
pic[0:6, 0:5]=f*pic.max()
|
||||
|
||||
def sim_gen(self,sz=(1500,1000),t=100,mode=0):
|
||||
'generate simulation data'
|
||||
@@ -257,15 +262,8 @@ class epics_cam(object):
|
||||
assert(img.mode=='L') # 8 bit grayscale
|
||||
assert(sz==img.size)
|
||||
imgSeq[i,:,:]=np.array(img.getdata()).reshape(sz[::-1])
|
||||
f=np.array(((0,0,0,0,0),
|
||||
(0,1,1,1,0),
|
||||
(0,1,0,0,0),
|
||||
(0,1,1,0,0),
|
||||
(0,1,0,0,0),
|
||||
(0,0,0,0,0),),imgSeq.dtype)
|
||||
imgSeq[i,0:6,0:5]=f*255
|
||||
|
||||
|
||||
pic=imgSeq[i]
|
||||
epics_cam.set_fiducial(pic, 255)
|
||||
|
||||
self._sim['imgSeq']=imgSeq
|
||||
self._sim['imgIdx']=0
|
||||
|
||||
75
swissmx.py
75
swissmx.py
@@ -395,12 +395,32 @@ class Main(QMainWindow, Ui_MainWindow):
|
||||
app=QApplication.instance()
|
||||
app._camera.pause()
|
||||
|
||||
def updateImage(self, pause=False):
|
||||
#if not sample_camera.is_paused(): #ZAC: orig. code
|
||||
def new_frame_sim_cb(self, **kwargs):
|
||||
app=QApplication.instance()
|
||||
img = app._camera.get_image()
|
||||
if img is not None:
|
||||
self.img.setImage(img)
|
||||
sim=app._camera._sim
|
||||
imgSeq=sim['imgSeq']
|
||||
idx=sim['imgIdx']
|
||||
sim['imgIdx']=(idx+1)%imgSeq.shape[0]
|
||||
# _log.info('simulated idx:{}'.format(idx))
|
||||
pic=imgSeq[idx]
|
||||
self.img.setImage(pic)
|
||||
|
||||
delay=500 # ms -> 2fps
|
||||
QtCore.QTimer.singleShot(delay, self.new_frame_sim_cb)
|
||||
|
||||
def new_frame_pv_cb(self, **kwargs):
|
||||
app=QApplication.instance()
|
||||
sz=app._camera._sz
|
||||
if kwargs['count']==sz[0]*sz[1]:
|
||||
pic=kwargs['value'].reshape(sz[::-1])
|
||||
else:
|
||||
sz=self.update_size()
|
||||
pic=kwargs['value'].reshape(sz[::-1])
|
||||
_log.debug('new_frame_pv_cb count {}'.format(kwargs['count']))
|
||||
if pic.dtype==np.int16:
|
||||
pic.dtype=np.uint16
|
||||
camera.epics_cam.set_fiducial(pic, 255)
|
||||
self.img.setImage(pic)
|
||||
|
||||
def init_settings_tracker(self):
|
||||
_log.info("configuring widget persistence")
|
||||
@@ -527,15 +547,13 @@ class Main(QMainWindow, Ui_MainWindow):
|
||||
self.timer.timeout.connect(self.check_zescape)
|
||||
self.timer.start(20)
|
||||
else:
|
||||
#zescape.stop_listening() #ZAC: orig. code
|
||||
_log.warning("re-starting timer on camera update")
|
||||
app=QApplication.instance()
|
||||
try:
|
||||
self.timer.stop()
|
||||
except:
|
||||
pass
|
||||
self.timer = QtCore.QTimer(self)
|
||||
self.timer.timeout.connect(self.updateImage)
|
||||
self.timer.start(10)
|
||||
self.new_frame_sim_cb()
|
||||
except AttributeError:
|
||||
app._camera.run(self.new_frame_pv_cb)
|
||||
|
||||
|
||||
|
||||
def check_zescape(self):
|
||||
msg = zescape.check()
|
||||
@@ -3156,28 +3174,31 @@ class Main(QMainWindow, Ui_MainWindow):
|
||||
|
||||
def really_quit(self):
|
||||
"""called when user Ctrl-Q the app"""
|
||||
global user, just_quit
|
||||
if (just_quit
|
||||
or QMessageBox.question(self, "", "Are you sure you want to quit?", QMessageBox.Yes | QMessageBox.No, QMessageBox.No,) == QMessageBox.Yes
|
||||
):
|
||||
if QMessageBox.question(self, "", "Are you sure you want to quit?", QMessageBox.Yes | QMessageBox.No, QMessageBox.No,) == QMessageBox.Yes:
|
||||
self._do_quit = True
|
||||
self.close()
|
||||
|
||||
def closeEvent(self, event):
|
||||
"""this is called when the user clicks the window's cross icon"""
|
||||
global user, just_quit
|
||||
if (
|
||||
just_quit
|
||||
or self._do_quit
|
||||
self._do_quit
|
||||
or QMessageBox.question( self, "", "Are you sure you want to quit?", QMessageBox.Yes | QMessageBox.No, QMessageBox.No,) == QMessageBox.Yes
|
||||
):
|
||||
sample_camera.disconnect()
|
||||
app=QApplication.instance()
|
||||
try:
|
||||
pv=app._camera._pv['pic']
|
||||
pv.clear_auto_monitor() # disconnect PV monitor callback -> program exit faster.
|
||||
except AttributeError:
|
||||
_log.warning('disconnect PV callback failed.')
|
||||
|
||||
_log.info('disconnect PV callback')
|
||||
settings.setValue("window/geometry", self.saveGeometry())
|
||||
settings.setValue("window/windowState", self.saveState())
|
||||
settings.setValue("window/main_splitter", self._main_splitter.sizes())
|
||||
settings.setValue("last_active", time.time())
|
||||
|
||||
QMainWindow.closeEvent(self, event)
|
||||
_log.info('save settings')
|
||||
#QMainWindow.closeEvent(self, event)
|
||||
_log.info('closeEvent done')
|
||||
else:
|
||||
event.ignore()
|
||||
|
||||
@@ -3220,7 +3241,10 @@ def sigint_handler(*args):
|
||||
def main():
|
||||
import argparse
|
||||
|
||||
parser = argparse.ArgumentParser()
|
||||
#(h, t)=os.path.split(sys.argv[0]);cmd='\n '+(t if len(h)>20 else sys.argv[0])+' '
|
||||
#exampleCmd=('', '-m0xf -v0')
|
||||
epilog=__doc__ #+'\nExamples:'+''.join(map(lambda s:cmd+s, exampleCmd))+'\n'
|
||||
parser=argparse.ArgumentParser(epilog=epilog, formatter_class=argparse.RawDescriptionHelpFormatter)
|
||||
parser.add_argument("--sim", "-s", type=lambda x: int(x,0), help="simulate devices (see bitmasks) default=0x%(default)x", default=0)
|
||||
args = parser.parse_args()
|
||||
_log.info('Arguments:{}'.format(args.__dict__))
|
||||
@@ -3250,10 +3274,9 @@ def main():
|
||||
if args.sim&0x08:
|
||||
app._camera = camera.epics_cam(None)
|
||||
app._camera.sim_gen(mode=1)
|
||||
app._camera.run()
|
||||
else:
|
||||
app._camera = camera.epics_cam()
|
||||
app._camera.run()
|
||||
#app._camera.run() is called in center_piece_update
|
||||
|
||||
app_icon = QtGui.QIcon()
|
||||
app_icon.addFile("artwork/logo/16x16.png", QtCore.QSize(16, 16))
|
||||
|
||||
Reference in New Issue
Block a user