python3-scikit-image对比拉伸和直方图均衡化

发布时间:2021-09-21 23:48:24编辑:run阅读(5963)

    直方图处理技术为改变图像中像素值的动态范围提供了一种更好的解决方法,使其强度直方图具有理想的形状。对比度拉伸操作的图像增强是有限的,因为它只能应用线性缩放函数。


    直方图处理技术可以通过使用非线性(和非单调)传递函数将输入像素的强度映射到输出像素的强度,从而使其功能变得更加强大。


    直方图均衡化采用单调的非线性映射,该映射重新分配输入图像的像素强度值,使输出图像的强度分布均匀(直方图平坦),从而增强图像的对比度。直方图均衡化的实现有两种不同的方式:第一种是对整个图像的全局操作;第二种是局部的(自适应)操作,将图像分割成块,并在每个块上直方图均衡化.

    from skimage.io import imread
    from skimage import data, img_as_float,img_as_ubyte, exposure, io, color
    from skimage.color import rgb2gray
    import matplotlib.pylab as pylab
    import numpy as np
    
    pylab.rcParams['font.sans-serif'] = ['KaiTi']
    pylab.rcParams['axes.unicode_minus'] = False
    def plot_image(image, title=''):
        pylab.title(title, size=20)
        pylab.imshow(image)
        pylab.axis('off')
    def plot_hist(r, g, b, title=''):
        r, g, b = img_as_ubyte(r), img_as_ubyte(g), img_as_ubyte(b)
        pylab.hist(np.array(r).ravel(), bins=256, range=(0, 256), color='r', alpha=0.5)
        pylab.hist(np.array(g).ravel(), bins=256, range=(0, 256), color='g', alpha=0.5)
        pylab.hist(np.array(b).ravel(), bins=256, range=(0, 256), color='b', alpha=0.5)
        pylab.xlabel('像素值', size=20)
        pylab.ylabel('频率', size=20)
        pylab.title(title, size=20)
    img = rgb2gray(imread(r"D:\image_processing\image4\b.jpg"))
    img_eq = exposure.equalize_hist(img)
    img_adapteq = exposure.equalize_adapthist(img, clip_limit=0.03)
    pylab.gray()
    images = [img, img_eq, img_adapteq]
    titles = ["原始图像", "直方图均衡化图像", "自适应直方图均衡化图像"]
    for i in range(3):
        pylab.figure(figsize=(20, 10))
        plot_image(images[i], titles[i])
    pylab.figure(figsize=(20, 10))
    for i in range(3):
        pylab.subplot(1, 3, i+1)
        pylab.hist(images[i].ravel(), color='g')
        pylab.title(titles[i])
    pylab.show()

    image.png

    image.png

    image.png

    可以看到,经过直方图均衡化后,输出图像的直方图变得几乎一样,但与全局直方图均衡化后的图像相比,自适应直方图均衡化的图像更清晰地显示了细节。


    局部直方图均衡化和自适应(拉伸和分段均匀)直方图均衡化像素分布的情况

    image.png



    实现使用两种不同的直方图处理技术,即基于scikit-image的对比度拉伸和直方图均衡化得到的图像增强进行比较。

    from skimage import data, img_as_float,img_as_ubyte, exposure, io
    import matplotlib.pylab as pylab
    import numpy as np
    
    pylab.rcParams['font.sans-serif'] = ['KaiTi']
    pylab.rcParams['axes.unicode_minus'] = False
    pylab.rcParams['font.size'] = 8
    
    def plot_image_and_list(image, axes, bins=256):
        image = img_as_float(image)
        _image, axes_hist = axes
        axes_cdf = axes_hist.twinx()
        _image.imshow(image, cmap=pylab.cm.gray)
        _image.set_axis_off()
        axes_hist.hist(image.ravel(), bins=bins, histtype='step', color='black')
        axes_hist.set_xlim(0, 1)
        axes_hist.set_xlabel('像素强度', size=20)
        axes_hist.ticklabel_format(axis='y', style='scientific', scilimits=(0, 0))
        axes_hist.set_yticks([])
        image_cdf, bins = exposure.cumulative_distribution(image, bins)
        axes_cdf.plot(bins, image_cdf, 'r')
        axes_cdf.set_yticks([])
        return _image, axes_hist, axes_cdf
    im = io.imread(r'D:\image_processing\image4\4.jpg')
    im_rescale = exposure.rescale_intensity(im, in_range=(0, 180))
    im_eq = exposure.equalize_hist(im)
    im_adapteq = exposure.equalize_adapthist(im, clip_limit=0.03)
    fig = pylab.figure(figsize=(20, 15))
    axes = np.zeros((2, 4), dtype=np.object)
    axes[0, 0] = fig.add_subplot(2, 4, 1)
    for i in range(1, 4):
        axes[0, i] = fig.add_subplot(2, 4, 1+i, sharex=axes[0, 0], sharey=axes[0, 0])
    for i in range(0, 4):
        axes[1, i] = fig.add_subplot(2, 4, 5+i)
    axes_image, axes_hist, axes_cdf = plot_image_and_list(im, axes[:, 0])
    axes_image.set_title('低对比度原始图像', size=20)
    y_min, y_max = axes_hist.get_ylim()
    axes_hist.set_ylabel('像素总数量', size=20)
    axes_hist.set_yticks(np.linspace(0, y_max, 5))
    axes_image, axes_hist, axes_cdf = plot_image_and_list(im_rescale, axes[:, 1])
    axes_image.set_title('对比度拉伸', size=20)
    axes_image, axes_hist, axes_cdf = plot_image_and_list(im_eq, axes[:, 2])
    axes_image.set_title('直方图均衡化', size=20)
    axes_image, axes_hist, axes_cdf = plot_image_and_list(im_adapteq, axes[:, 3])
    axes_image.set_title('自适应均衡化', size=20)
    axes_cdf.set_ylabel('总强度分数', size=20)
    axes_cdf.set_yticks(np.linspace(0, 1, 5))
    fig.tight_layout()
    pylab.show()

    image.png


    输出结果,低对比原始图像,对比度拉伸,直方图均衡化和自适应均衡化及各自的像素分布情况,可以看到,自适应直方图均衡化后的图像比直方图均衡化的图像效果更好,细节更加清晰。

关键字