2017-05-11 8 views
0

Ich habe ein Bild als ein numpy maskiertes Array dargestellt. Das Bild besteht aus einem Vordergrund und einem Hintergrund, ich bin nicht an dem Hintergrund interessiert, also habe ich ihn maskiert. Es ist ein Bild mit schlechtem Kontrast, und ich möchte den Kontrast im Vordergrund mit skimage.exposure.equalize_histFehler beim Versuch, skimage.equalize_hist über ein maskiertes Array auszuführen

erhöhen Ich bemerkte, dass die equalize_hist-Funktion einen benannten Parameter mask nimmt, um die unmasked Daten zu ignorieren.

Mein Code sieht wie folgt aus

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) 

Der ske.equalize_hist Aufruf erzeugt diesen Fehler, und ich bin nicht sicher, warum.

--------------------------------------------------------------------------- 
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' 

Hat jemand eine Idee, warum das passiert? Ich bin ratlos.

+1

Als allgemeine Regel gilt, dass 'numpy' und Third-Party-Code keine maskierten Arrays in irgendeiner speziellen Weise behandeln. Sie verwenden nur das vollständige Attribut "data". Sie müssen 'np.ma ...' Funktionen oder Funktionen verwenden, die an 'ma' Methoden delegieren. Aber hast du 'equalize_hist (masked_img.data, mask = mask) 'versucht? – hpaulj

+1

Außerdem sollte 'Vordergrund = 65535' wahrscheinlich' Vordergrund == 65535' sein. –

+0

@MadPhysicist Wahr, ich hatte einen doppelten Wert in meinem ursprünglichen Code, aber nicht hier. Behoben. – Azeirah

Antwort

2

Wie @hpaulij vorschlägt, halten Sie sich von maskierten Arrays so weit wie möglich fern, wenn Sie die Daten weitergeben möchten. Gegeben hier die Verwendung Sie zeigen, gibt es keinen besonderen Grund, nicht nur eine separate Maske zu halten:

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) 

Beachten Sie auch, dass die Maske für maskierten Arrays hat die entgegengesetzte Richtung von, was equalize_hist erwartet. numpy.ma.MaskedArray setzt invalid elements auf True, während equalize_hist erwartet, dass die gültigen Elemente True sind.

Es kann von Vorteil sein, proprietary.findForeground einfach eine Maske für Sie zurückgeben, anstatt mit dem Originalbild zu verwirren. Dies hätte den Vorteil, dass der maskierte Wert nicht an das dtype des Bildes gebunden wird und keine Probleme mit gesättigten Vordergrundpixeln auftreten. Wenn Sie die Möglichkeit, dies zu tun haben, würde der Code in etwa so aussehen:

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

Wie Sie sehen können, wird dieser Schritt von Ihrem Prozess beseitigen.

Verwandte Themen