2017-05-11 33 views
0

我有一张表示为numpy遮罩数组的图像。图像由前景和背景组成,我对背景不感兴趣,因此我将其蒙蔽。这是一个对比度差的图像,我想增加在前景的对比度使用skimage.exposure.equalize_hist尝试在遮罩数组上执行skimage.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' 

任何人都知道为什么会发生这种情况?我很茫然。

+1

作为一般规则'numpy'和第三方代码不以任何特殊方式处理掩码数组。他们只是使用完整的'data'属性。你必须使用委托给'ma'方法的'np.ma ...'函数或函数。但你有没有尝试'equalize_hist(masked_img.data,mask = mask)'? – hpaulj

+1

此外,'前景= 65535'应该可能是'前景== 65535' –

+0

@MadPhysicist真的,我在我的原始代码中有一个等于两倍,但不是在这里。修复。 – Azeirah

回答

2

正如@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期待的方向相反。 numpy.ma.MaskedArrayinvalid elementsTrue,而equalize_hist期望有效元素为True

proprietary.findForeground只为您返回一个掩码,而不是混淆原始图像可能会有好处。这样做的好处是不会将遮罩值绑定到图像的dtype,并且不会遇到饱和前景像素的问题。如果你有能力做到这一点,你的代码看起来是这样的:

mask = findForeground(img) # Now returns a boolean array of the correct size 
... 
equalized = ske.equalize_hist(img, mask=mask) 

正如你所看到的,这将消除您的工艺步骤。