Why performing an histogram equalization by scikit

2019-08-30 20:11发布

问题:

I used histogram equalization and adaptation for erase illumination from the grayscale images, but after the histogram equalization (i used scikit image python library) was good, during image conversion in mahotas something goes wrong. I got a picture total black. How can i fix it?

  • Source image:

  • Histogram equalization and adaptation;

  • Result after mahotas conversion.

conversion code from scikit to mahotas:

binimg = np.array(img_adapteq, dtype=np.bool)

Source code:

import scipy
import numpy as np
import pymorph as pm
import mahotas as mh
from skimage import morphology
from skimage import io
from matplotlib import pyplot as plt
from skimage import data, img_as_float
from skimage import exposure
def plot_img_and_hist(img, axes, bins=256):
    """Plot an image along with its histogram and cumulative histogram.

    """
    img = img_as_float(img)
    ax_img, ax_hist = axes
    ax_cdf = ax_hist.twinx()

    # Display image
    ax_img.imshow(img, cmap=plt.cm.gray)
    ax_img.set_axis_off()

    # Display histogram
    ax_hist.hist(img.ravel(), bins=bins, histtype='step', color='black')
    ax_hist.ticklabel_format(axis='y', style='scientific', scilimits=(0, 0))
    ax_hist.set_xlabel('Pixel intensity')
    ax_hist.set_xlim(0, 1)
    ax_hist.set_yticks([])

    # Display cumulative distribution
    img_cdf, bins = exposure.cumulative_distribution(img, bins)
    ax_cdf.plot(bins, img_cdf, 'r')
    ax_cdf.set_yticks([])

    return ax_img, ax_hist, ax_cdf


mhgray = mh.imread(path,0)
binimg = mhgray[:,:,0]
print(type(binimg[0][0]))
thresh = mh.otsu(binimg)
gray =( binimg< thresh)

shape = list(gray.shape)
w = 0
if (shape[0] > shape[1]):
    shape = shape[0]
else:
    shape = shape[1]

if (shape < 100):
    w =  int((shape/100 )*1.5)
elif(shape > 100 and shape <420):
    w =  int((shape/100 )*2.5)
else:
    w = int((shape/100)*4)
disk7 = pm.sedisk(w)

img = binimg

# Contrast stretching
p2 = np.percentile(img, 2)
p98 = np.percentile(img, 98)
img_rescale = exposure.rescale_intensity(img, in_range=(p2, p98))

# Equalization
img_eq = exposure.equalize_hist(img)

# Adaptive Equalization
img_adapteq = exposure.equalize_adapthist(img, clip_limit=0.03)

# Display results
f, axes = plt.subplots(2, 4, figsize=(8, 4))

ax_img, ax_hist, ax_cdf = plot_img_and_hist(img, axes[:, 0])
ax_img.set_title('Low contrast image')

y_min, y_max = ax_hist.get_ylim()
ax_hist.set_ylabel('Number of pixels')
ax_hist.set_yticks(np.linspace(0, y_max, 5))

ax_img, ax_hist, ax_cdf = plot_img_and_hist(img_rescale, axes[:, 1])
ax_img.set_title('Contrast stretching')

ax_img, ax_hist, ax_cdf = plot_img_and_hist(img_eq, axes[:, 2])
ax_img.set_title('Histogram equalization')

ax_img, ax_hist, ax_cdf = plot_img_and_hist(img_adapteq, axes[:, 3])
ax_img.set_title('Adaptive equalization')

ax_cdf.set_ylabel('Fraction of total intensity')
ax_cdf.set_yticks(np.linspace(0, 1, 5))

# prevent overlap of y-axis labels
plt.subplots_adjust(wspace=0.4)
plt.show()


plt.gray()
plt.subplot(121)
plt.title("after histo")
plt.imshow(img_adapteq)
plt.show()

binimg = np.array(img_adapteq, dtype=np.bool)#uint16

plt.gray()
plt.subplot(121)
plt.title("after otsu")
plt.imshow(binimg)
plt.show()

imgbnbin = mh.morph.dilate(binimg, disk7)

#2     
plt.gray()
plt.subplot(121)
plt.title("after dilate before close")
plt.imshow(imgbnbin)
plt.show()

imgbnbin = mh.morph.close(imgbnbin, disk7)
#2     
plt.gray()
plt.subplot(121)
plt.title("before skeletonize")
plt.imshow(imgbnbin)
plt.show()

imgbnbin = mh.morph.close(imgbnbin, disk7)
out = morphology.skeletonize(imgbnbin>0)

回答1:

The scikit-image algorithm probably returns a floating point image with values between 0 and 1. If you cast that to bool, you'll get all ones. You probably want

binimg = img_adapteq > 0.5

In general, also take note of the rescale_intensity function, which will take an image with values between 0 and 1 and return an image with values between 0 and 255.

from skimage import exposure image = rescale_intensity(image, out_range=(0, 255))