pyqtgraph roi removehandle不会删除椭圆ROI的圆形手柄

发布于 2025-02-03 03:27:47 字数 1943 浏览 2 评论 0原文

我的目标是编码无法旋转的椭圆ROI。考虑从Pyqtgraph之一修改的以下代码示例:


import numpy as np
import cv2
import pyqtgraph as pg
from PyQt5 import QtGui
import numpy.ma as ma
from PyQt5.QtWidgets import QMessageBox

pg.setConfigOptions(imageAxisOrder='row-major')

## Create image to display
image = cv2.imread('panda.jpg')


def picturetranspose(picture):
    shape = picture.shape
    result = np.empty((shape[1],shape[0],shape[2]),dtype= np.uint8)
    for i in range(0,3):
        result[:,:,i] = np.transpose(picture[:,:,i])
    return result
    
arr = np.rot90(picturetranspose(image))
app = pg.mkQApp("ROI Examples")
w = pg.GraphicsLayoutWidget(show=True, size=(1000,800), border=True)
w.setWindowTitle('pyqtgraph example: ROI Examples')
w1 = w.addLayout(row=0, col=0)
v1a = w1.addViewBox(row=1, col=0, lockAspect = True)
v1a.setLimits(minXRange = arr.shape[0]//10, minYRange = arr.shape[1]//10, maxXRange = 5*arr.shape[0], maxYRange = 5*arr.shape[1])
img1a = pg.ImageItem(arr)
v1a.addItem(img1a)

rois = []
x=pg.EllipseROI([60, 10], [30, 20], pen=pg.mkPen('b', width=5),rotatable = False)
x.removeHandle(0)
rois.append(x)

for roi in rois:
    roi.sigRegionChanged.connect(img1a.setImage(arr))
    v1a.addItem(roi)

img1a.setImage(arr)

此处图像“ panda.jpg”由: https://drive.google.com/drive/folders/1ejy0cjfews6sgs2qe_urx2jvlrumkvpx?usp = sharing 。运行代码并移动ROI将给出:

”“在此处输入图像描述”

通过单击方形浅蓝色手柄,可以更改ROI的大小。由于我设置了旋转= false,因此无法旋转ROI,并且单击圆形手柄不会旋转ROI。

但是,线X.RemoveHandle(0)应删除浅蓝色的圆形手柄,以免它在屏幕上显示。这是一个错误吗?我想念什么?

My objective is code out an ellipse ROI that cannot be rotated. Consider the following piece of code modified from one of the PyQtGraph examples :


import numpy as np
import cv2
import pyqtgraph as pg
from PyQt5 import QtGui
import numpy.ma as ma
from PyQt5.QtWidgets import QMessageBox

pg.setConfigOptions(imageAxisOrder='row-major')

## Create image to display
image = cv2.imread('panda.jpg')


def picturetranspose(picture):
    shape = picture.shape
    result = np.empty((shape[1],shape[0],shape[2]),dtype= np.uint8)
    for i in range(0,3):
        result[:,:,i] = np.transpose(picture[:,:,i])
    return result
    
arr = np.rot90(picturetranspose(image))
app = pg.mkQApp("ROI Examples")
w = pg.GraphicsLayoutWidget(show=True, size=(1000,800), border=True)
w.setWindowTitle('pyqtgraph example: ROI Examples')
w1 = w.addLayout(row=0, col=0)
v1a = w1.addViewBox(row=1, col=0, lockAspect = True)
v1a.setLimits(minXRange = arr.shape[0]//10, minYRange = arr.shape[1]//10, maxXRange = 5*arr.shape[0], maxYRange = 5*arr.shape[1])
img1a = pg.ImageItem(arr)
v1a.addItem(img1a)

rois = []
x=pg.EllipseROI([60, 10], [30, 20], pen=pg.mkPen('b', width=5),rotatable = False)
x.removeHandle(0)
rois.append(x)

for roi in rois:
    roi.sigRegionChanged.connect(img1a.setImage(arr))
    v1a.addItem(roi)

img1a.setImage(arr)

Here the image "panda.jpg" is given by: https://drive.google.com/drive/folders/1ejY0CjfEwS6SGS2qe_uRX2JvlruMKvPX?usp=sharing. Running the code and moving the ROI will give:

enter image description here

By clicking on the square light blue handle, the size of ROI can be changed. Since I set rotatable = False, the ROI cannot be rotated and clicking on the circular handle will not rotate the ROI .

However, the line x.removeHandle(0) should delete the light blue circular handle so that it does not show up on the screen at all . Is this a bug? What am I missing ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

北风几吹夏 2025-02-10 03:27:47

当创建QGraphicSitem时,它没有立即添加到场景中,在那个时间范围内,与场景相关的方面被“存储”为“存储”,直到实际上将项目实际上放到场景中为止。其中一些属性很明显(例如项目位置),但其他属性则不是。其中之一是添加儿童项目。当现场添加“主要”项目时,将添加所有孩子(以及孙子,曾孙等)。

这就是创建ROI时发生的事情:其手柄是在其__ INT __中创建的(请参阅 sources ),但是 remove> removehandle() 如果ROI实际上有scene()

请记住,pyqt(和pyside)是 bindings ,这意味着我们始终与C ++对象周围的Python包装器一起使用。即使删除了对Python对象的最后一个引用,仅删除了Python对象,但是如果该对象是C ++对象周围的包装器,并且该对象具有父,则 em> faceal 对象不是毕竟被删除。
尽管Pyqtgraph从其内部列表中删除了句柄,但表示手柄的C ++对象仍然是ROI的孩子,因此,当ROI添加到场景中时,手柄仍然存在。

一种可能的解决方案是在 之后卸下句柄已将ROI添加到场景中:

for roi in rois:
    roi.sigRegionChanged.connect(img1a.setImage(arr))
    v1a.addItem(roi)
    roi.removeHandle(0)

这起作用是因为remove Handle仅在存在该项目的场景时才删除句柄这样,实际上可以将子项目从场景中删除。

请注意,根据消息来源,eLLIPSEROI添加两个手柄:旋转 scale 。您可能要删除所有内容:

for roi in rois:
    roi.sigRegionChanged.connect(img1a.setImage(arr))
    v1a.addItem(roi)
    while roi.handles:
        roi.removeHandle(0)

我建议您在关于此,将其解决在他们身边应该很容易。

When a QGraphicsItem is created it's not immediately added to a scene, and in that time frame some scene-related aspects are "stored" until the item is actually put to a scene. Some of those properties are pretty obvious (such as the item position), but others are not. One of them is adding child items. When a "main" item is added to the scene, all of its children (and grandchildren, great-grandchildren, etc.) are added along with it.

This is what happens when a ROI is created: its handles are created in its __init__ (see the sources), but removeHandle() only removes the handle from the scene if the ROI actually has a scene().

Remember that PyQt (and PySide) are bindings to Qt, meaning that we always work with python wrappers around C++ objects. Even when the last reference to a python object is deleted, only the python object is actually deleted, but if that object is a wrapper around a C++ object and that object has a parent, the actual object is not deleted after all.
While pyqtgraph removes the handle from its internal list, the C++ object that represents the handle still exists as a child of the ROI, so, when the ROI is added to the scene, the handle still exists.

A possible solution is to remove the handles after the ROI has been added to the scene:

for roi in rois:
    roi.sigRegionChanged.connect(img1a.setImage(arr))
    v1a.addItem(roi)
    roi.removeHandle(0)

This works because removeHandle only removes the handle when a scene exists for the item, and in this way the child item can be actually removed from the scene.

Note that, according to the sources, EllipseROI adds two handles: rotate and scale. You will probably want to remove all of them:

for roi in rois:
    roi.sigRegionChanged.connect(img1a.setImage(arr))
    v1a.addItem(roi)
    while roi.handles:
        roi.removeHandle(0)

I suggest you to file a report on the pyqtgraph repository about this, solving it on their side should be pretty easy.

可爱暴击 2025-02-10 03:27:47

解决此问题的方法:

pg.ROI(
    # arguments
    handlePen='#0000',
    handleHoverPen='#0000',
    # arguments
)

然后如您所描述的那样禁用手柄。这使手柄完全透明(即看不见)。

A workaround for this:

pg.ROI(
    # arguments
    handlePen='#0000',
    handleHoverPen='#0000',
    # arguments
)

then disable the handle as you described. This makes the handle fully transparent (i.e. invisible).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文