Pyqtgraph 将选定的感兴趣区域放在不同颜色的地图中
Pyqtgraph Put the Selected Region of Interest in a Different Color Map
这是从一个 pyqtgraph 示例稍作修改的代码片段:
import numpy as np
import cv2
import pyqtgraph as pg
pg.setConfigOptions(imageAxisOrder='row-major')
## Create image to display
image = cv2.imread('panda.jpg')
#Transpose the image
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))
#arr = cv2.applyColorMap(arr, cv2.COLORMAP_JET)
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)
v1b = w1.addViewBox(row=2, col=0, lockAspect=True)
img1a = pg.ImageItem(arr)
v1a.addItem(img1a)
img1b = pg.ImageItem()
v1b.addItem(img1b)
rois = []
rois.append(pg.PolyLineROI([[80, 60], [90, 30], [60, 40]], pen=(6,9), closed=True))
def update(roi):
img1b.setImage(roi.getArrayRegion(arr, img1a), levels=(0, arr.max()))
for roi in rois:
roi.sigRegionChanged.connect(update)
v1a.addItem(roi)
update(rois[-1])
if __name__ == '__main__':
pg.exec()
此处图像“panda.jpg”由以下人员提供:
https://drive.google.com/drive/folders/1ejY0CjfEwS6SGS2qe_uRX2JvlruMKvPX?usp=sharing.
运行 上面的代码并稍微移动 ROI(感兴趣区域)将得到:
一切正常。我现在要做的是把选中的ROI做成不同的colormap。我的尝试如下:如果我在 arr
的定义之后添加 arr = cv2.applyColorMap(arr, cv2.COLORMAP_JET)
行,那么我将得到的是:
这成功地转换了色彩空间,但不是我想要的方式,因为我只需要将所选区域放在新的色彩图中。我的下一次尝试是用 img1b.setImage(cv2.applyColorMap(roi.getArrayRegion(arr, img1a), cv2.COLORMAP_JET), levels=(0, arr.max()))
代替 img1b.setImage(roi.getArrayRegion(arr, img1a), levels=(0, arr.max()))
。但这会导致错误消息:
我应该如何进行?
编辑:
通过写 arr2 = cv2.applyColorMap(arr, cv2.COLORMAP_JET)
并写 img1b.setImage(roi.getArrayRegion(arr2, img1a), levels=(0, arr.max()))
代替 img1b.setImage(roi.getArrayRegion(arr, img1a), levels=(0, arr.max()))
,我可以得到以下内容:
我现在还需要做的就是在不同颜色的地图中制作所选区域(我用红色标记)。最好是选择的区域在不同的颜色图中而不是边界矩形中。
编辑:
最后,我通过将 update
方法替换为以下方法解决了我的问题:
def update(roi):
arr_copy = arr.copy()
slices, tr = roi.getArraySlice(arr, img1a, returnSlice=True)
colormapped = roi.getArrayRegion(arr2, img1a)
newslices = (slice(slices[0].start, slices[0].start + colormapped.shape[0], None),
slice(slices[1].start, slices[1].start + colormapped.shape[1], None),
slice(None,None,None))
gray_original = np.dot(arr_copy[newslices][...,:3], [0.299, 0.587, 0.114])
gray_colormapped = np.dot(colormapped[...,:3], [0.299, 0.587, 0.114])
gray_original_masked = ma.array(gray_original,mask = gray_colormapped).filled(fill_value = 0)
complement = np.empty(gray_original_masked.shape)
complement[gray_original_masked == 0] = 1
complement[gray_original_masked != 0] = 0
interior_croped_0 = ma.array(arr_copy[newslices][:,:,0],mask = complement).filled(fill_value = 0)
interior_croped_1 = ma.array(arr_copy[newslices][:,:,1],mask = complement).filled(fill_value = 0)
interior_croped_2 = ma.array(arr_copy[newslices][:,:,2],mask = complement).filled(fill_value = 0)
original_color_masked = np.empty(arr_copy[newslices].shape)
original_color_masked[:,:,0] = interior_croped_0
original_color_masked[:,:,1] = interior_croped_1
original_color_masked[:,:,2] = interior_croped_2
final = original_color_masked + colormapped
arr_copy[newslices] = final
img1a.setImage(arr_copy, levels=(0, arr.max()))
感谢 D Malan 给了我使用切片的提示。
您可以使用 getArraySlice
.
获取需要更新的原始数组中的切片
将您的 update
方法更改为:
arr2 = cv2.applyColorMap(arr, cv2.COLORMAP_JET)
def update(roi):
img1b.setImage(roi.getArrayRegion(arr, img1a), levels=(0, arr.max()))
# Get a copy of the original array that can be modified
arr_copy = arr.copy()
# Get the slices of the ROI
slices, tr = roi.getArraySlice(arr, img1a, returnSlice=True)
# Update the slices to have the values of the colourmap
arr_copy[slices] = arr2[slices]
# Update the image with the new values
img1a.setImage(arr_copy, levels=(0, arr.max()))
这是从一个 pyqtgraph 示例稍作修改的代码片段:
import numpy as np
import cv2
import pyqtgraph as pg
pg.setConfigOptions(imageAxisOrder='row-major')
## Create image to display
image = cv2.imread('panda.jpg')
#Transpose the image
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))
#arr = cv2.applyColorMap(arr, cv2.COLORMAP_JET)
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)
v1b = w1.addViewBox(row=2, col=0, lockAspect=True)
img1a = pg.ImageItem(arr)
v1a.addItem(img1a)
img1b = pg.ImageItem()
v1b.addItem(img1b)
rois = []
rois.append(pg.PolyLineROI([[80, 60], [90, 30], [60, 40]], pen=(6,9), closed=True))
def update(roi):
img1b.setImage(roi.getArrayRegion(arr, img1a), levels=(0, arr.max()))
for roi in rois:
roi.sigRegionChanged.connect(update)
v1a.addItem(roi)
update(rois[-1])
if __name__ == '__main__':
pg.exec()
此处图像“panda.jpg”由以下人员提供: https://drive.google.com/drive/folders/1ejY0CjfEwS6SGS2qe_uRX2JvlruMKvPX?usp=sharing.
运行 上面的代码并稍微移动 ROI(感兴趣区域)将得到:
一切正常。我现在要做的是把选中的ROI做成不同的colormap。我的尝试如下:如果我在 arr
的定义之后添加 arr = cv2.applyColorMap(arr, cv2.COLORMAP_JET)
行,那么我将得到的是:
这成功地转换了色彩空间,但不是我想要的方式,因为我只需要将所选区域放在新的色彩图中。我的下一次尝试是用 img1b.setImage(cv2.applyColorMap(roi.getArrayRegion(arr, img1a), cv2.COLORMAP_JET), levels=(0, arr.max()))
代替 img1b.setImage(roi.getArrayRegion(arr, img1a), levels=(0, arr.max()))
。但这会导致错误消息:
我应该如何进行?
编辑:
通过写 arr2 = cv2.applyColorMap(arr, cv2.COLORMAP_JET)
并写 img1b.setImage(roi.getArrayRegion(arr2, img1a), levels=(0, arr.max()))
代替 img1b.setImage(roi.getArrayRegion(arr, img1a), levels=(0, arr.max()))
,我可以得到以下内容:
我现在还需要做的就是在不同颜色的地图中制作所选区域(我用红色标记)。最好是选择的区域在不同的颜色图中而不是边界矩形中。
编辑:
最后,我通过将 update
方法替换为以下方法解决了我的问题:
def update(roi):
arr_copy = arr.copy()
slices, tr = roi.getArraySlice(arr, img1a, returnSlice=True)
colormapped = roi.getArrayRegion(arr2, img1a)
newslices = (slice(slices[0].start, slices[0].start + colormapped.shape[0], None),
slice(slices[1].start, slices[1].start + colormapped.shape[1], None),
slice(None,None,None))
gray_original = np.dot(arr_copy[newslices][...,:3], [0.299, 0.587, 0.114])
gray_colormapped = np.dot(colormapped[...,:3], [0.299, 0.587, 0.114])
gray_original_masked = ma.array(gray_original,mask = gray_colormapped).filled(fill_value = 0)
complement = np.empty(gray_original_masked.shape)
complement[gray_original_masked == 0] = 1
complement[gray_original_masked != 0] = 0
interior_croped_0 = ma.array(arr_copy[newslices][:,:,0],mask = complement).filled(fill_value = 0)
interior_croped_1 = ma.array(arr_copy[newslices][:,:,1],mask = complement).filled(fill_value = 0)
interior_croped_2 = ma.array(arr_copy[newslices][:,:,2],mask = complement).filled(fill_value = 0)
original_color_masked = np.empty(arr_copy[newslices].shape)
original_color_masked[:,:,0] = interior_croped_0
original_color_masked[:,:,1] = interior_croped_1
original_color_masked[:,:,2] = interior_croped_2
final = original_color_masked + colormapped
arr_copy[newslices] = final
img1a.setImage(arr_copy, levels=(0, arr.max()))
感谢 D Malan 给了我使用切片的提示。
您可以使用 getArraySlice
.
将您的 update
方法更改为:
arr2 = cv2.applyColorMap(arr, cv2.COLORMAP_JET)
def update(roi):
img1b.setImage(roi.getArrayRegion(arr, img1a), levels=(0, arr.max()))
# Get a copy of the original array that can be modified
arr_copy = arr.copy()
# Get the slices of the ROI
slices, tr = roi.getArraySlice(arr, img1a, returnSlice=True)
# Update the slices to have the values of the colourmap
arr_copy[slices] = arr2[slices]
# Update the image with the new values
img1a.setImage(arr_copy, levels=(0, arr.max()))