尝试对屏蔽数组执行 skimage.equalize_hist 时出错
Error while trying to perform skimage.equalize_hist over a masked array
我有一个表示为 numpy 掩码数组的图像。图片由前景和背景组成,我对背景不感兴趣,所以我把它遮住了。这是一张对比度很差的图像,我想使用 skimage.exposure.equalize_hist
增加前景的对比度
我注意到 equalize_hist 函数采用命名参数 mask
,以忽略未屏蔽的数据。
我的代码是这样的
import numpy as np
import skimage.exposure as ske
import matplotlib.pyplot as plt
# doesn't really exist
from proprietary import openImage, findForeground
imagePath = "...." # path to the image file
# image format is proprietary, so we have a custom function open it for us
# it returns a regular numpy uint16 2d array
# print(type(img), img.dtype, img.shape) shows
# `
# <class 'numpy.ndarray'> float64 (2688, 1151)
# `
img = openImage(imagePath)
foreground = findForeground(img) # this function sets all background pixels to white
# 65535 == white for a uint16 array
masked_img = np.ma.masked_where(foreground==65535, foreground)
# plotting this `masked_img` using plt.imshow works perfectly, the background is completely white
# and the foreground is shown as it is supposed to
# this goes wrong
mask = np.ma.getmask(masked_img)
equalized = ske.equalize_hist(masked_img, mask=mask)
ske.equalize_hist
调用生成此错误,我不确定原因。
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-4-e2b4f8e60ef9> in <module>()
37 print(type(mask))
38 print(mask)
---> 39 equalized = ske.equalize_hist(fg, mask=mask)
40 plt.imshow(equalized, cmap=cmap)
41 plt.set_title("Equalized histogram with colormap {cmap}".format(cmap=cmap))
C:\Users\myuser\AppData\Local\Continuum\Anaconda3\lib\site-packages\skimage\exposure\exposure.py in equalize_hist(image, nbins, mask)
165 cdf, bin_centers = cumulative_distribution(image[mask], nbins)
166 else:
--> 167 cdf, bin_centers = cumulative_distribution(image, nbins)
168 out = np.interp(image.flat, bin_centers, cdf)
169 return out.reshape(image.shape)
C:\Users\myuser\AppData\Local\Continuum\Anaconda3\lib\site-packages\skimage\exposure\exposure.py in cumulative_distribution(image, nbins)
125 True
126 """
--> 127 hist, bin_centers = histogram(image, nbins)
128 img_cdf = hist.cumsum()
129 img_cdf = img_cdf / float(img_cdf[-1])
C:\Users\myuser\AppData\Local\Continuum\Anaconda3\lib\site-packages\skimage\exposure\exposure.py in histogram(image, nbins)
86 return hist[idx:], bin_centers[idx:]
87 else:
---> 88 hist, bin_edges = np.histogram(image.flat, bins=nbins)
89 bin_centers = (bin_edges[:-1] + bin_edges[1:]) / 2.
90 return hist, bin_centers
C:\Users\myuser\AppData\Local\Continuum\Anaconda3\lib\site-packages\numpy\lib\function_base.py in histogram(a, bins, range, normed, weights, density)
495 mn, mx = 0.0, 1.0
496 else:
--> 497 mn, mx = a.min() + 0.0, a.max() + 0.0
498 else:
499 mn, mx = [mi + 0.0 for mi in range]
TypeError: unsupported operand type(s) for +: 'MaskedIterator' and 'float'
有人知道为什么会这样吗?我很茫然。
正如@hpaulij 建议的那样,当您计划传递数据时,请尽可能远离屏蔽数组。鉴于您在此处显示的用法,没有特别的理由不只维护一个单独的掩码:
import numpy as np
import skimage.exposure as ske
import matplotlib.pyplot as plt
# doesn't really exist
from proprietary import openImage, findForeground
imagePath = "...." # path to the image file
# image format is proprietary, so we have a custom function open it for us
# it returns a regular numpy uint16 2d array
# print(type(img), img.dtype, img.shape) shows
# `
# <class 'numpy.ndarray'> float64 (2688, 1151)
# `
img = openImage(imagePath)
foreground = findForeground(img) # this function sets all background pixels to white
# 65535 == white for a uint16 array
mask = (foreground != 65536)
# plotting this `masked_img` using plt.imshow works perfectly, the background is completely white
# and the foreground is shown as it is supposed to
# foreground should work as well as the original img here
equalized = ske.equalize_hist(img, mask=mask)
还要记住,掩码数组的掩码与 equalize_hist
is expecting. numpy.ma.MaskedArray
sets invalid elements 和 True
的意义相反,而 equalize_hist 期望 valid 元素为 True
.
proprietary.findForeground
只是 return 一个蒙版可能对您有益,而不是弄乱原始图像。这样做的好处是不会将掩码值绑定到图像的 dtype
,而不是将 运行 绑定到饱和前景像素的问题上。如果您有能力做到这一点,您的代码将类似于:
mask = findForeground(img) # Now returns a boolean array of the correct size
...
equalized = ske.equalize_hist(img, mask=mask)
如您所见,这将从您的流程中删除步骤。
我有一个表示为 numpy 掩码数组的图像。图片由前景和背景组成,我对背景不感兴趣,所以我把它遮住了。这是一张对比度很差的图像,我想使用 skimage.exposure.equalize_hist
我注意到 equalize_hist 函数采用命名参数 mask
,以忽略未屏蔽的数据。
我的代码是这样的
import numpy as np
import skimage.exposure as ske
import matplotlib.pyplot as plt
# doesn't really exist
from proprietary import openImage, findForeground
imagePath = "...." # path to the image file
# image format is proprietary, so we have a custom function open it for us
# it returns a regular numpy uint16 2d array
# print(type(img), img.dtype, img.shape) shows
# `
# <class 'numpy.ndarray'> float64 (2688, 1151)
# `
img = openImage(imagePath)
foreground = findForeground(img) # this function sets all background pixels to white
# 65535 == white for a uint16 array
masked_img = np.ma.masked_where(foreground==65535, foreground)
# plotting this `masked_img` using plt.imshow works perfectly, the background is completely white
# and the foreground is shown as it is supposed to
# this goes wrong
mask = np.ma.getmask(masked_img)
equalized = ske.equalize_hist(masked_img, mask=mask)
ske.equalize_hist
调用生成此错误,我不确定原因。
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-4-e2b4f8e60ef9> in <module>()
37 print(type(mask))
38 print(mask)
---> 39 equalized = ske.equalize_hist(fg, mask=mask)
40 plt.imshow(equalized, cmap=cmap)
41 plt.set_title("Equalized histogram with colormap {cmap}".format(cmap=cmap))
C:\Users\myuser\AppData\Local\Continuum\Anaconda3\lib\site-packages\skimage\exposure\exposure.py in equalize_hist(image, nbins, mask)
165 cdf, bin_centers = cumulative_distribution(image[mask], nbins)
166 else:
--> 167 cdf, bin_centers = cumulative_distribution(image, nbins)
168 out = np.interp(image.flat, bin_centers, cdf)
169 return out.reshape(image.shape)
C:\Users\myuser\AppData\Local\Continuum\Anaconda3\lib\site-packages\skimage\exposure\exposure.py in cumulative_distribution(image, nbins)
125 True
126 """
--> 127 hist, bin_centers = histogram(image, nbins)
128 img_cdf = hist.cumsum()
129 img_cdf = img_cdf / float(img_cdf[-1])
C:\Users\myuser\AppData\Local\Continuum\Anaconda3\lib\site-packages\skimage\exposure\exposure.py in histogram(image, nbins)
86 return hist[idx:], bin_centers[idx:]
87 else:
---> 88 hist, bin_edges = np.histogram(image.flat, bins=nbins)
89 bin_centers = (bin_edges[:-1] + bin_edges[1:]) / 2.
90 return hist, bin_centers
C:\Users\myuser\AppData\Local\Continuum\Anaconda3\lib\site-packages\numpy\lib\function_base.py in histogram(a, bins, range, normed, weights, density)
495 mn, mx = 0.0, 1.0
496 else:
--> 497 mn, mx = a.min() + 0.0, a.max() + 0.0
498 else:
499 mn, mx = [mi + 0.0 for mi in range]
TypeError: unsupported operand type(s) for +: 'MaskedIterator' and 'float'
有人知道为什么会这样吗?我很茫然。
正如@hpaulij 建议的那样,当您计划传递数据时,请尽可能远离屏蔽数组。鉴于您在此处显示的用法,没有特别的理由不只维护一个单独的掩码:
import numpy as np
import skimage.exposure as ske
import matplotlib.pyplot as plt
# doesn't really exist
from proprietary import openImage, findForeground
imagePath = "...." # path to the image file
# image format is proprietary, so we have a custom function open it for us
# it returns a regular numpy uint16 2d array
# print(type(img), img.dtype, img.shape) shows
# `
# <class 'numpy.ndarray'> float64 (2688, 1151)
# `
img = openImage(imagePath)
foreground = findForeground(img) # this function sets all background pixels to white
# 65535 == white for a uint16 array
mask = (foreground != 65536)
# plotting this `masked_img` using plt.imshow works perfectly, the background is completely white
# and the foreground is shown as it is supposed to
# foreground should work as well as the original img here
equalized = ske.equalize_hist(img, mask=mask)
还要记住,掩码数组的掩码与 equalize_hist
is expecting. numpy.ma.MaskedArray
sets invalid elements 和 True
的意义相反,而 equalize_hist 期望 valid 元素为 True
.
proprietary.findForeground
只是 return 一个蒙版可能对您有益,而不是弄乱原始图像。这样做的好处是不会将掩码值绑定到图像的 dtype
,而不是将 运行 绑定到饱和前景像素的问题上。如果您有能力做到这一点,您的代码将类似于:
mask = findForeground(img) # Now returns a boolean array of the correct size
...
equalized = ske.equalize_hist(img, mask=mask)
如您所见,这将从您的流程中删除步骤。