我的目標是撰寫一個不能旋轉的橢圓 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”由:
通過單擊方形淺藍色手柄,可以更改 ROI 的大小。由于我設定rotatable = False,ROI 不能旋轉,點擊圓形手柄不會旋轉 ROI。
但是,該行x.removeHandle(0)應洗掉淺藍色圓形手柄,使其根本不會出現在螢屏上。這是一個錯誤嗎?我錯過了什么?
uj5u.com熱心網友回復:
創建 QGraphicsItem 時,它不會立即添加到場景中,并且在那個時間范圍內,一些與場景相關的方面被“存盤”,直到專案實際放入場景中。其中一些屬性非常明顯(例如專案位置),但其他屬性則不然。其中之一是添加子項。當一個“主要”專案被添加到場景中時,它的所有子項(以及孫子、曾孫等)也會隨之添加。
這就是創建 ROI 時發生的情況:它的句柄是在其中創建的__init__(參見源代碼),但removeHandle()只有在 ROI 實際具有scene().
請記住,PyQt(和 PySide)是對 Qt 的系結,這意味著我們始終使用圍繞 C 物件的 python 包裝器。即使洗掉了對 python 物件的最后一個參考,實際上也只洗掉了 python 物件,但如果該物件是 C 物件的包裝器并且該物件具有父物件,則實際物件畢竟不會被洗掉。
雖然 pyqtgraph 從其內部串列中洗掉了句柄,但表示句柄的 C 物件仍然作為 ROI 的子物件存在,因此,當將 ROI 添加到場景中時,句柄仍然存在。
一種可能的解決方案是在將 ROI 添加到場景后移除句柄:
for roi in rois:
roi.sigRegionChanged.connect(img1a.setImage(arr))
v1a.addItem(roi)
roi.removeHandle(0)
這是有效的,因為removeHandle只有在專案存在場景時才會移除句柄,并且通過這種方式,子專案可以實際從場景中移除。
請注意,根據訊息來源,EllipseROI添加了兩個句柄:旋轉和縮放。您可能希望洗掉所有這些:
for roi in rois:
roi.sigRegionChanged.connect(img1a.setImage(arr))
v1a.addItem(roi)
while roi.handles:
roi.removeHandle(0)
我建議你在pyqtgraph 存盤庫上提交一份報告,在他們這邊解決它應該很容易。
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/484520.html
標籤:Python python-3.x opencv pyqt5 pyqtgraph
