This commit is contained in:
2022-08-16 15:24:49 +02:00
parent a5b400208c
commit 7db60ba6ee
2 changed files with 211 additions and 53 deletions

View File

@@ -17,7 +17,7 @@ import pyqtgraph as pg
from pyqtgraph.Qt import QtCore, QtGui from pyqtgraph.Qt import QtCore, QtGui
import numpy as np import numpy as np
from PyQt5.QtGui import QPolygon,QPolygonF from PyQt5.QtGui import QPolygon,QPolygonF
from PyQt5.QtCore import QPointF,QLineF from PyQt5.QtCore import Qt,QPointF,QLineF
def obj_tree(obj,p=''): def obj_tree(obj,p=''):
obj_info(obj,p) obj_info(obj,p)
@@ -28,7 +28,12 @@ def obj_info(obj,p=''):
print(f"{p}obj_info:{obj}") print(f"{p}obj_info:{obj}")
try: try:
pos=obj.pos() pos=obj.pos()
print(f"{p}Pos:({pos.x():.6g},{pos.y():.6g})") # in coordinate value on the scene (no change by zooming) print(f"{p}pos:({pos.x():.6g},{pos.y():.6g})") # in coordinate value on the scene (no change by zooming)
except AttributeError:
pass
try:
sz=obj.size()
print(f"{p}size:({sz.x():.6g},{sz.y():.6g})") # in coordinate value on the scene (no change by zooming)
except AttributeError: except AttributeError:
pass pass
try: try:
@@ -53,11 +58,18 @@ def obj_info(obj,p=''):
except AttributeError: except AttributeError:
pass pass
class BeamMark(pg.ROI): class Marker(pg.ROI):
"""A crosshair ROI whose position is at the center of the crosshairs. By default, it is scalable, rotatable and translatable.""" """A crosshair ROI whose position is at the center of the crosshairs. By default, it is scalable, rotatable and translatable."""
def __init__(self, pos=None, size=None, **kargs): def __init__(self, pos, size, mode, **kargs):
pg.ROI.__init__(self, pos, size, **kargs) pg.ROI.__init__(self, pos, size, **kargs)
self._mode=mode
#widget.signal.connect(slot_function)
#self.sigRegionChangeFinished.connect(self.OnRgnChanged)
#def OnRgnChanged(self, event):
# print(event)
# obj_info(self)
def paint(self, p, *args): def paint(self, p, *args):
#pg.ROI.paint(self, p, *args) #pg.ROI.paint(self, p, *args)
@@ -65,12 +77,55 @@ class BeamMark(pg.ROI):
p.setRenderHint(QtGui.QPainter.Antialiasing) p.setRenderHint(QtGui.QPainter.Antialiasing)
p.setPen(self.currentPen) p.setPen(self.currentPen)
p.translate(r.left(), r.top()) p.translate(r.left(), r.top())
p.scale(r.width(), r.height()) #p.scale(r.width(), r.height()) # -> values x,y 0 to 1
p.drawEllipse(0, 0, 1, 1) #f=p.font();
p.drawRect(0, 0, 1, 1) #f.setPixelSize(50)
#p.setFont(f)
# p.drawText(0, 0, '{:.0f}x{:.0f}'.format(*tuple(self.size())))
#p.drawText(0, 0, 'Thierry')
p.scale(.01*r.width(), .01*r.height()) # -> values x,y 0 to 100
m=self._mode
if m==0:
p.drawEllipse(0, 0, 100, 100)
p.drawRect(0, 0, 100, 100)
p.setPen(pg.mkPen(width=3, color=[200, 100, 100])) p.setPen(pg.mkPen(width=3, color=[200, 100, 100]))
p.drawLine(pg.Point(.5, 0), pg.Point(.5, 1)) p.drawLine(pg.Point(50, 0), pg.Point(50, 100))
p.drawLine(pg.Point( 0,.5), pg.Point( 1,.5)) p.drawLine(pg.Point( 0,50), pg.Point(100, 50))
tr=p.transform()
tr.setMatrix(tr.m11(), tr.m12(), tr.m13(), tr.m21(), -tr.m22(), tr.m23(), tr.m31(), tr.m32(), tr.m33())
p.setTransform(tr)
f=p.font()
f.setPixelSize(10)
p.setFont(f)
p.drawText(24, -80, 'beam marker')
ctr=tuple(self.pos()+self.size()/2)
sz=tuple(self.size())
p.drawText(5, -55, '{:.1f}x{:.1f}'.format(*sz))
#p.drawText(5, -35, '{:.1f}'.format(ctr[0]))
p.drawText(5, -45,42,30,Qt.AlignRight, '{:.1f}'.format(ctr[0]))
p.drawText(55, -35, '{:.1f}'.format(ctr[1]))
elif m==1:
p.drawEllipse(20,20,60,60)
p.drawRect(0, 0, 100, 100)
p.setPen(pg.mkPen(width=2, color=[10, 255, 0]))
p.drawLine(pg.Point(50, 0), pg.Point( 50,100))
p.drawLine(pg.Point( 0,50), pg.Point(100, 50))
tr=p.transform()
tr.setMatrix(tr.m11(), tr.m12(), tr.m13(), tr.m21(), -tr.m22(), tr.m23(), tr.m31(), tr.m32(), tr.m33())
p.setTransform(tr)
f=p.font();
f.setPixelSize(10)
p.setFont(f)
px=tuple(self.pos()+self.size()/2)
p.drawText(5, -90, 'optical')
p.drawText(55,-90, 'center')
#p.drawText(5, -10, '{:.1f}/{:.1f}'.format(*px))
p.drawText(5, -10, '{:.1f}'.format(px[0]))
p.drawText(55, -10, '{:.1f}'.format(px[1]))
#p.drawText(0, 0, 'Thierry')
# w, h = self.getState()["size"] # w, h = self.getState()["size"]
# v1, v2 = -(h * 0.8) / 2, (h * 0.8) / 2 # v1, v2 = -(h * 0.8) / 2, (h * 0.8) / 2
# h1, h2 = -(w * 0.8) / 2, (w * 0.8) / 2 # h1, h2 = -(w * 0.8) / 2, (w * 0.8) / 2
@@ -83,7 +138,6 @@ class BeamMark(pg.ROI):
# p.drawRect(-w / 2, -h / 2, w, h) # p.drawRect(-w / 2, -h / 2, w, h)
# # p.drawText(-w, -h, '{:.0f}x{:.0f}'.format(*self._size)) # # p.drawText(-w, -h, '{:.0f}x{:.0f}'.format(*self._size))
class Grid(pg.ROI): class Grid(pg.ROI):
'''a grid''' '''a grid'''
@@ -182,20 +236,43 @@ class Path(pg.ROI):
fid=self._fiducial fid=self._fiducial
for i in range(fid.shape[0]): for i in range(fid.shape[0]):
x,y=fid[i,:];print(x,y) x,y=fid[i,:]#;print(x,y)
lh=QLineF(x-5*rx,y,x+5*rx,y) lh=QLineF(x-5*rx,y,x+5*rx,y)
lv=QLineF(x, y-5*ry, x, y+5*ry) lv=QLineF(x, y-5*ry, x, y+5*ry)
p.drawLines(lh,lv) p.drawLines(lh,lv)
class TxtROI(pg.ROI):
def __init__(self, pos, size, **kargs):
pg.ROI.__init__(self, pos, size, **kargs)
def paint(self, p, *args):
#pg.ROI.paint(self, p, *args)
r=QtCore.QRectF(0, 0, self.state['size'][0], self.state['size'][1]).normalized()
p.setRenderHint(QtGui.QPainter.Antialiasing)
p.setPen(self.currentPen)
#p.translate(r.left(), r.top())
#p.scale(r.width(), r.height())
#p.drawRect(0, 0, 1, 1)
p.drawRect(r)
tr=p.worldTransform()
obj_info(tr)
tr.setMatrix(tr.m11(),tr.m12(),tr.m13(),tr.m21(),-tr.m22(),tr.m23(),tr.m31(),tr.m32(),tr.m33())
p.setWorldTransform(tr)
obj_info(tr)
obj_info(p.transform())
obj_info(p.worldTransform())
f=p.font();
f.setPixelSize(15)
p.setFont(f)
p.drawText(0, 5, 'Thierry')
## Start Qt event loop unless running in interactive mode or using pyside. ## Start Qt event loop unless running in interactive mode or using pyside.
if __name__=='__main__': if __name__=='__main__':
import sys import sys
import argparse import argparse
#(h, t)=os.path.split(sys.argv[0]);cmd='\n '+(t if len(h)>20 else sys.argv[0])+' ' #(h, t)=os.path.split(sys.argv[0]);cmd='\n '+(t if len(h)>20 else sys.argv[0])+' '
#exampleCmd=('', '-m0xf -v0') #exampleCmd=('', '-m0xf -v0')
epilog=__doc__ #+'\nExamples:'+''.join(map(lambda s:cmd+s, exampleCmd))+'\n' epilog=__doc__ #+'\nExamples:'+''.join(map(lambda s:cmd+s, exampleCmd))+'\n'
@@ -234,13 +311,36 @@ if __name__=='__main__':
def mouse_click_event(event): def mouse_click_event(event):
#event.pos(): return Point(self.currentItem.mapFromScene(self._scenePos))
pos=event.pos() pos=event.pos()
scn=event.scenePos() # there is a small black border, that makes the difference scn=event.scenePos() # there is a small black border, that makes the difference
img=viImg.mapFromScene(scn) print(f'mouse-> scene pos:{pt2str(scn)} currentItem pos:{pt2str(pos)}')
roi=viUsrRoi.mapFromScene(scn) #img=viImg.mapFromScene(scn)
print(f'mouse:{pt2str(pos)} {pt2str(scn)} img:{pt2str(img)} roi:{pt2str(roi)}') #roi=viUsrRoi.mapFromScene(scn)
#print(f'mouse-> img:{pt2str(img)} roi:{pt2str(roi)}')
#childTree(vb) #childTree(vb)
obj_info(viUsrRoi) #obj_info(viImg)
m=int(event.modifiers())
o=event.currentItem
if m&Qt.ShiftModifier:
o.setPos((100,200))
o.setSize((200,100))
o.rotate(10)
pass
elif m&Qt.ControlModifier:
tr=o.transform()
obj_info(tr)
#tr.setMatrix(tr.m11(),tr.m12(),tr.m13()+100,tr.m21(),tr.m22(),tr.m23(),tr.m31(),tr.m32(),tr.m33())
#tr.setMatrix(tr.m11(),tr.m12(),tr.m13(),tr.m21(),tr.m22(),tr.m23(),tr.m31(),tr.m32()+20,tr.m33())
tr.setMatrix(tr.m11(),tr.m12(),tr.m13(),tr.m21(),-tr.m22(),tr.m23(),tr.m31(),tr.m32(),tr.m33())
obj_info(tr)
o.setTransform(tr)
elif m&Qt.AltModifier:
pass
else:
obj_info(o)
print(o.state)
## Create image to display ## Create image to display
arr=np.ones((100, 100), dtype=float) arr=np.ones((100, 100), dtype=float)
@@ -264,17 +364,23 @@ if __name__=='__main__':
w=pg.GraphicsLayoutWidget(show=True, size=(1000, 800), border=True) w=pg.GraphicsLayoutWidget(show=True, size=(1000, 800), border=True)
w.setWindowTitle('pyqtgraph example: ROI Examples') w.setWindowTitle('pyqtgraph example: ROI Examples')
vb=w.addViewBox(row=1, col=0, lockAspect=True) vb=w.addViewBox(row=1, col=0, lockAspect=True,invertY=False)
try:
g=pg.GridItem(pen=(0, 255, 0), textPen=(0, 255, 0)) # green grid and labels
except:
g=pg.GridItem() g=pg.GridItem()
vb.addItem(g) vb.addItem(g)
viImg=pg.ImageItem(arr, border='y') viImg=pg.ImageItem(arr, border='y')
vb.addItem(viImg) vb.addItem(viImg)
# Custom ROI for selecting an image region # Custom ROI for selecting an image region
viRoi=pg.ROI([20, -50], [60, 40]) #viRoi=pg.ROI([20, -50], [60, 40])
viRoi=TxtROI([20, -50], [60, 40])
vb.addItem(viRoi) vb.addItem(viRoi)
viUsrRoi=BeamMark([50, 120], [30, 20]) viUsrRoi=Marker([50, 120], [30, 20],mode=0)
vb.addItem(viUsrRoi) vb.addItem(viUsrRoi)
obj=Marker([250, 220], [30, 20],mode=1)
vb.addItem(obj)
vi=Grid( (120,-100), (200,150), (30,20),2) vi=Grid( (120,-100), (200,150), (30,20),2)
#vi=Grid( (50,10), (200,150), (6,4)) #vi=Grid( (50,10), (200,150), (6,4))
vb.addItem(vi) #vi= visual item vb.addItem(vi) #vi= visual item
@@ -283,11 +389,19 @@ if __name__=='__main__':
fiducial=np.array(((18, 7), (25, 16), (70, 20))) fiducial=np.array(((18, 7), (25, 16), (70, 20)))
path=gen_swissmx_points(ofs=(10, 5), width=200) path=gen_swissmx_points(ofs=(10, 5), width=200)
vi=Path((120,100),path,fiducial,fidScl) vi=Path((120,100),path,fiducial,fidScl)
#tr=QtGui.QTransform() # prepare ImageItem transformation:
#tr.setMatrix(1, 0, 0,
# 0, 1, 0,
# 10, 10, 1)
#vi.setTransform(tr) # assign transform
vb.addItem(vi) vb.addItem(vi)
childTree(vb) childTree(vb)
w.scene().sigMouseClicked.connect(mouse_click_event) w.scene().sigMouseClicked.connect(mouse_click_event)
#viImg.sigImageChanged
#print(vb.pos())
#vb.setPos(50,50)
if (sys.flags.interactive!=1) or not hasattr(QtCore, 'PYQT_VERSION'): if (sys.flags.interactive!=1) or not hasattr(QtCore, 'PYQT_VERSION'):
QtGui.QApplication.instance().exec_() QtGui.QApplication.instance().exec_()

View File

@@ -317,14 +317,16 @@ class Main(QMainWindow, Ui_MainWindow):
self.glw.scene().sigMouseClicked.connect(self.mouse_click_event) self.glw.scene().sigMouseClicked.connect(self.mouse_click_event)
#--- viewbox --- #--- viewbox ---
self.vb=vb=self.glw.addViewBox(invertY=False)#),border='r')#,enableMenu=False) #self.vb=vb=self.glw.addViewBox(invertY=False,border='r',enableMenu=False)
self.vb=vb=self.glw.addViewBox(invertY=False,border='r',enableMenu=False)
vb.setAspectLocked(True) vb.setAspectLocked(True)
vb.setBackgroundColor((120, 90, 90)) vb.setBackgroundColor((120, 90, 90))
#--- image ---
self.img=img=pg.ImageItem()
tr=QtGui.QTransform() # prepare ImageItem transformation: tr=QtGui.QTransform() # prepare ImageItem transformation:
#opt_ctr=app._geometry._opt_ctr opt_ctr=app._geometry._opt_ctr
#--- image ---
self._goImg=img=pg.ImageItem()
tr.setMatrix(-1, 0, 0, tr.setMatrix(-1, 0, 0,
0,-1, 0, 0,-1, 0,
0, 0, 1) 0, 0, 1)
@@ -334,19 +336,24 @@ class Main(QMainWindow, Ui_MainWindow):
#--- grid --- #--- grid ---
try: try:
grid=pg.GridItem(pen=(0,255,0),textPen=(0,255,0)) #green grid and labels self._goGrid=grid=pg.GridItem(pen=(0,255,0),textPen=(0,255,0)) #green grid and labels
except: except:
grid=pg.GridItem() self._goGrid=grid=pg.GridItem()
tr.reset() tr.reset()
grid.setTransform(tr) # assign transform grid.setTransform(tr) # assign transform
vb.addItem(grid) vb.addItem(grid)
#--- beam marker --- #--- beam marker ---
w, h = cfg.value(AppCfg.GEO_BEAM_SZ) bm_sz=np.array(tuple(map(int, cfg.value(AppCfg.GEO_BEAM_SZ))))
bm=UsrGO.BeamMark([50, 120], [30, 20]) self._goBeamMarker=bm=UsrGO.Marker(-opt_ctr-[50, 120],bm_sz,mode=0)
bm.setTransform(tr) # assign transform bm.setTransform(tr) # assign transform
self.vb.addItem(bm) self.vb.addItem(bm)
#--- opctical center ---
self._goOptCtr=obj=UsrGO.Marker(-opt_ctr, [50, 50],mode=1)
bm.setTransform(tr) # assign transform
self.vb.addItem(obj)
#--- testing scan grid --- #--- testing scan grid ---
vi=UsrGO.Grid((120, -100), (200, 150), (30, 22), 2) vi=UsrGO.Grid((120, -100), (200, 150), (30, 22), 2)
vi.setTransform(tr) # assign transform vi.setTransform(tr) # assign transform
@@ -426,7 +433,7 @@ class Main(QMainWindow, Ui_MainWindow):
sim['imgIdx']=(idx+1)%imgSeq.shape[0] sim['imgIdx']=(idx+1)%imgSeq.shape[0]
# _log.info('simulated idx:{}'.format(idx)) # _log.info('simulated idx:{}'.format(idx))
pic=imgSeq[idx] pic=imgSeq[idx]
self.img.setImage(pic) self._goImg.setImage(pic)
delay=500 # ms -> 2fps delay=500 # ms -> 2fps
QtCore.QTimer.singleShot(delay, self.new_frame_sim_cb) QtCore.QTimer.singleShot(delay, self.new_frame_sim_cb)
@@ -443,7 +450,7 @@ class Main(QMainWindow, Ui_MainWindow):
if pic.dtype==np.int16: if pic.dtype==np.int16:
pic.dtype=np.uint16 pic.dtype=np.uint16
camera.epics_cam.set_fiducial(pic, 255) camera.epics_cam.set_fiducial(pic, 255)
self.img.setImage(pic) self._goImg.setImage(pic)
def init_settings_tracker(self): def init_settings_tracker(self):
app=QApplication.instance() app=QApplication.instance()
@@ -1093,7 +1100,7 @@ class Main(QMainWindow, Ui_MainWindow):
app = QApplication.instance() app = QApplication.instance()
self._mouse_pos = pos self._mouse_pos = pos
task = self.active_task() task = self.active_task()
xy = self.img.mapFromScene(pos) xy = self._goImg.mapFromScene(pos)
z = app._zoom.get() z = app._zoom.get()
#_log.debug('mouse_pos:{} scene_pos:{} zoom:{}'.format(pos,xy,z)) #_log.debug('mouse_pos:{} scene_pos:{} zoom:{}'.format(pos,xy,z))
#TODO: implement mouse handling #TODO: implement mouse handling
@@ -1142,7 +1149,7 @@ class Main(QMainWindow, Ui_MainWindow):
raw=app._raw_pix2pos[zoom] raw=app._raw_pix2pos[zoom]
except KeyError as e: except KeyError as e:
raw=app._raw_pix2pos[zoom]=list() raw=app._raw_pix2pos[zoom]=list()
imgPos=self.img.mapFromScene(event.scenePos()) imgPos=self._goImg.mapFromScene(event.scenePos())
fx=fast_x.get_position(); fx=fast_x.get_position();
fy=fast_y.get_position() fy=fast_y.get_position()
x=imgPos.x();y=imgPos.y() x=imgPos.x();y=imgPos.y()
@@ -1153,7 +1160,7 @@ class Main(QMainWindow, Ui_MainWindow):
raw=app._raw_opt_ctr[zoom] raw=app._raw_opt_ctr[zoom]
except KeyError as e: except KeyError as e:
raw=app._raw_opt_ctr[zoom]=list() raw=app._raw_opt_ctr[zoom]=list()
imgPos=self.img.mapFromScene(event.scenePos()) imgPos=self._goImg.mapFromScene(event.scenePos())
x=imgPos.x();y=imgPos.y() x=imgPos.x();y=imgPos.y()
_log.debug('append calib: zoom:{} cam_pix_x_y:{}/{}'.format(zoom, x, y)) _log.debug('append calib: zoom:{} cam_pix_x_y:{}/{}'.format(zoom, x, y))
raw.append(( x, y)) raw.append(( x, y))
@@ -1161,24 +1168,61 @@ class Main(QMainWindow, Ui_MainWindow):
QMessageBox.warning(self, "calibration", "no calibration started yet.\nPress 'pix2pos' or 'opt_ctr' button first") QMessageBox.warning(self, "calibration", "no calibration started yet.\nPress 'pix2pos' or 'opt_ctr' button first")
def mouse_click_event(self, event): def mouse_click_event(self, event):
_log.debug("{}".format(event)) #_log.debug("{}".format(event))
_log.debug("screen pos {}".format(event.screenPos())) #pixel position on the whole screen #_log.debug("screen pos {}".format(event.screenPos())) #pixel position on the whole screen
_log.debug("scene pos {}".format(event.scenePos())) #pixel position on the scene (including black frame) #_log.debug("scene pos {}".format(event.scenePos())) #pixel position on the scene (including black frame)
#_log.debug(" pos {}".format(event.pos())) #pixel position of the ckicked object mapped to its coordinates #_log.debug(" pos {}".format(event.pos())) #pixel position of the ckicked object mapped to its coordinates
p=event.scenePos() #p=event.scenePos()
_log.debug(f"vb pos {self.vb.mapFromScene(p)}") #pixel position on the scene (including black frame) #_log.debug(f"vb pos {self.vb.mapFromScene(p)}") #pixel position on the scene (including black frame)
for o in self.vb.childGroup.childItems(): #for o in self.vb.childGroup.childItems():
_log.debug(f"{type(o)} pos {o.mapFromScene(p)}") #pixel position on the scene (including black frame) # _log.debug(f"{type(o)} pos {o.mapFromScene(p)}") #pixel position on the scene (including black frame)
task = self.active_task() task = self.active_task()
if task==TASK_SETUP_GEOMETRY_CALIB: if task==TASK_SETUP_GEOMETRY_CALIB:
self.mouse_click_event_geometry_calib(event) self.mouse_click_event_geometry_calib(event)
return return
#Ctrl-left : move to position
#Ctrl-left : move to position
#dblclick = event.double()
app=QApplication.instance()
mod=event.modifiers()
btn=event.button()
if btn==Qt.LeftButton:
if mod&Qt.ShiftModifier:
pass
elif mod&Qt.ControlModifier:
pos=event.scenePos()
_log.debug(f'move to position :scene pos {pos}')
geo=app._geometry
geo.interp_zoom(1)
bm=self._goBeamMarker
p1=self._goImg.mapFromScene(pos)
p2=bm.pos()+bm.size()/2
px=p2+p1
um=geo.pix2pos(px)
_log.debug(f'{px} -> {um}')
pass
elif mod&Qt.AltModifier:
pass
else:
pass
elif btn==Qt.RightButton:
if mod&Qt.ShiftModifier:
pass
elif mod&Qt.ControlModifier:
_log.debug('object tree')
UsrGO.obj_tree(self.vb)
pass
elif mod&Qt.AltModifier:
pass
else:
pass
return
return return
assert(event.currentItem==self.vb) assert(event.currentItem==self.vb)
UsrGO.obj_tree(self.vb)
#UsrGO.obj_info(self.img) #UsrGO.obj_info(self.img)
event.pos()# return Point(self.currentItem.mapFromScene(self._scenePos)) event.pos()# return Point(self.currentItem.mapFromScene(self._scenePos))
@@ -1203,7 +1247,7 @@ class Main(QMainWindow, Ui_MainWindow):
ctrl = Qt.ControlModifier & event.modifiers() ctrl = Qt.ControlModifier & event.modifiers()
alt = Qt.AltModifier & event.modifiers() alt = Qt.AltModifier & event.modifiers()
xy = self.img.mapFromScene(pos) xy = self._goImg.mapFromScene(pos)
x, y = xy.x(), xy.y() x, y = xy.x(), xy.y()
bx, by = self.get_beam_mark_on_camera_xy() bx, by = self.get_beam_mark_on_camera_xy()
a = np.asarray([x, y]) a = np.asarray([x, y])