pyqtgraph图像点选择
pyqtgraph image point selection
我正在尝试为我的实验室制作一个用于手动图像配准的工具——用户可以在其中 select 两个不同图像上的一些点来对齐它们。我在 matplotlib 中做了这个,但是缩放 in/out 太慢了(我想是因为我们对齐的图像非常高分辨率)。在 pyqtgraph 中有没有好的方法来做到这一点?我只需要能够并排显示两个图像图上的 select 个点,并显示 select 个离子所在的位置。
目前我有 ImageView
s 中的图像,我尝试使用 imv.scene.sigMouseClicked.connect(mouse_click)
进行处理,但在 mouse_click(evt)
evt.pos()
、evt.scenePos()
和 evt.screenPos()
都给出了不在图像坐标中的坐标。我还尝试使用 ROI 自由手柄来完成 selection 点(因为我可以从中获得正确的坐标),但你似乎无法为手柄着色,这不是一个完整的交易-breaker 我想知道是否有更好的选择。有更好的方法吗?
你的问题不清楚你希望程序如何匹配点,这里我提供一个简单的解决方案让你(1)显示图像。 (2) 给图像加点。
基本思路是使用一个pg.GraphicsLayoutWidget
,然后添加一个pg.ImageItem
和一个pg.ScatterPlotItem
,每点击一次鼠标都会给ScatterPlotItem添加一个点。代码:
import sys
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import QApplication, QMainWindow, QWidget, QHBoxLayout
import pyqtgraph as pg
import cv2
pg.setConfigOption('background', 'w')
pg.setConfigOption('foreground', 'k')
class ImagePlot(pg.GraphicsLayoutWidget):
def __init__(self):
super(ImagePlot, self).__init__()
self.p1 = pg.PlotItem()
self.addItem(self.p1)
self.p1.vb.invertY(True) # Images need inverted Y axis
# Use ScatterPlotItem to draw points
self.scatterItem = pg.ScatterPlotItem(
size=10,
pen=pg.mkPen(None),
brush=pg.mkBrush(255, 0, 0),
hoverable=True,
hoverBrush=pg.mkBrush(0, 255, 255)
)
self.scatterItem.setZValue(2) # Ensure scatterPlotItem is always at top
self.points = [] # Record Points
self.p1.addItem(self.scatterItem)
def setImage(self, image_path, size):
self.p1.clear()
self.p1.addItem(self.scatterItem)
# pg.ImageItem.__init__ method takes input as an image array
# I use opencv to load image, you can replace with other packages
image = cv2.imread(image_path, 1)
# resize image to some fixed size
image = cv2.resize(image, size)
self.image_item = pg.ImageItem(image)
self.image_item.setOpts(axisOrder='row-major')
self.p1.addItem(self.image_item)
def mousePressEvent(self, event):
point = self.p1.vb.mapSceneToView(event.pos()) # get the point clicked
# Get pixel position of the mouse click
x, y = int(point.x()), int(point.y())
self.points.append([x, y])
self.scatterItem.setPoints(pos=self.points)
super().mousePressEvent(event)
if __name__ == "__main__":
QApplication.setAttribute(Qt.AA_EnableHighDpiScaling)
app = QApplication([])
win = QMainWindow()
central_win = QWidget()
layout = QHBoxLayout()
central_win.setLayout(layout)
win.setCentralWidget(central_win)
image_plot1 = ImagePlot()
image_plot2 = ImagePlot()
layout.addWidget(image_plot1)
layout.addWidget(image_plot2)
image_plot1.setImage('/home/think/image1.png', (310, 200))
image_plot2.setImage('/home/think/image2.jpeg', (310, 200))
# You can access points by accessing image_plot1.points
win.show()
if (sys.flags.interactive != 1) or not hasattr(Qt.QtCore, "PYQT_VERSION"):
QApplication.instance().exec_()
结果如下:
我正在尝试为我的实验室制作一个用于手动图像配准的工具——用户可以在其中 select 两个不同图像上的一些点来对齐它们。我在 matplotlib 中做了这个,但是缩放 in/out 太慢了(我想是因为我们对齐的图像非常高分辨率)。在 pyqtgraph 中有没有好的方法来做到这一点?我只需要能够并排显示两个图像图上的 select 个点,并显示 select 个离子所在的位置。
目前我有 ImageView
s 中的图像,我尝试使用 imv.scene.sigMouseClicked.connect(mouse_click)
进行处理,但在 mouse_click(evt)
evt.pos()
、evt.scenePos()
和 evt.screenPos()
都给出了不在图像坐标中的坐标。我还尝试使用 ROI 自由手柄来完成 selection 点(因为我可以从中获得正确的坐标),但你似乎无法为手柄着色,这不是一个完整的交易-breaker 我想知道是否有更好的选择。有更好的方法吗?
你的问题不清楚你希望程序如何匹配点,这里我提供一个简单的解决方案让你(1)显示图像。 (2) 给图像加点。
基本思路是使用一个pg.GraphicsLayoutWidget
,然后添加一个pg.ImageItem
和一个pg.ScatterPlotItem
,每点击一次鼠标都会给ScatterPlotItem添加一个点。代码:
import sys
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import QApplication, QMainWindow, QWidget, QHBoxLayout
import pyqtgraph as pg
import cv2
pg.setConfigOption('background', 'w')
pg.setConfigOption('foreground', 'k')
class ImagePlot(pg.GraphicsLayoutWidget):
def __init__(self):
super(ImagePlot, self).__init__()
self.p1 = pg.PlotItem()
self.addItem(self.p1)
self.p1.vb.invertY(True) # Images need inverted Y axis
# Use ScatterPlotItem to draw points
self.scatterItem = pg.ScatterPlotItem(
size=10,
pen=pg.mkPen(None),
brush=pg.mkBrush(255, 0, 0),
hoverable=True,
hoverBrush=pg.mkBrush(0, 255, 255)
)
self.scatterItem.setZValue(2) # Ensure scatterPlotItem is always at top
self.points = [] # Record Points
self.p1.addItem(self.scatterItem)
def setImage(self, image_path, size):
self.p1.clear()
self.p1.addItem(self.scatterItem)
# pg.ImageItem.__init__ method takes input as an image array
# I use opencv to load image, you can replace with other packages
image = cv2.imread(image_path, 1)
# resize image to some fixed size
image = cv2.resize(image, size)
self.image_item = pg.ImageItem(image)
self.image_item.setOpts(axisOrder='row-major')
self.p1.addItem(self.image_item)
def mousePressEvent(self, event):
point = self.p1.vb.mapSceneToView(event.pos()) # get the point clicked
# Get pixel position of the mouse click
x, y = int(point.x()), int(point.y())
self.points.append([x, y])
self.scatterItem.setPoints(pos=self.points)
super().mousePressEvent(event)
if __name__ == "__main__":
QApplication.setAttribute(Qt.AA_EnableHighDpiScaling)
app = QApplication([])
win = QMainWindow()
central_win = QWidget()
layout = QHBoxLayout()
central_win.setLayout(layout)
win.setCentralWidget(central_win)
image_plot1 = ImagePlot()
image_plot2 = ImagePlot()
layout.addWidget(image_plot1)
layout.addWidget(image_plot2)
image_plot1.setImage('/home/think/image1.png', (310, 200))
image_plot2.setImage('/home/think/image2.jpeg', (310, 200))
# You can access points by accessing image_plot1.points
win.show()
if (sys.flags.interactive != 1) or not hasattr(Qt.QtCore, "PYQT_VERSION"):
QApplication.instance().exec_()
结果如下: