简体   繁体   English

使用 Z3B7F949B2343F9E5390​​E29F6EF5E1778Z 对灰度图像进行直方图均衡

[英]Histogram equalization of grayscale images with NumPy

How to do histogram equalization for multiple grayscaled images stored in a NumPy array easily?如何轻松对存储在 Z3B7F949B2343F9E5390​​E29F6EF5E1778Z 数组中的多个灰度图像进行直方图均衡?

I have the 96x96 pixel NumPy data in this 4D format:我有这种 4D 格式的 96x96 像素 Z3B7F949B2343F9E5390​​E29F6EF5E1778Z 数据:

(1800, 1, 96,96)

Moose's comment which points to this blog entry does the job quite nicely. Moose对这篇博客文章评论非常好。

For completeness I give an axample here using nicer variable names and a looped execution on 1000 96x96 images which are in a 4D array as in the question. 为了完整性,我在这里使用更好的变量名称和1000个96x96图像上的循环执行给出了一个例子,这些图像在问题中是4D阵列。 It is fast (1-2 seconds on my computer) and only needs NumPy. 它很快(在我的电脑上1-2秒)并且只需要NumPy。

import numpy as np

def image_histogram_equalization(image, number_bins=256):
    # from http://www.janeriksolem.net/2009/06/histogram-equalization-with-python-and.html

    # get image histogram
    image_histogram, bins = np.histogram(image.flatten(), number_bins, density=True)
    cdf = image_histogram.cumsum() # cumulative distribution function
    cdf = 255 * cdf / cdf[-1] # normalize

    # use linear interpolation of cdf to find new pixel values
    image_equalized = np.interp(image.flatten(), bins[:-1], cdf)

    return image_equalized.reshape(image.shape), cdf

if __name__ == '__main__':

    # generate some test data with shape 1000, 1, 96, 96
    data = np.random.rand(1000, 1, 96, 96)

    # loop over them
    data_equalized = np.zeros(data.shape)
    for i in range(data.shape[0]):
        image = data[i, 0, :, :]
        data_equalized[i, 0, :, :] = image_histogram_equalization(image)[0]

Very fast and easy way is to use the cumulative distribution function provided by the skimage module. 非常快速简便的方法是使用由skimage模块提供的累积分布函数。 Basically what you do mathematically to proof it. 基本上你用数学方法来证明它。

from skimage import exposure
import numpy as np
def histogram_equalize(img):
    img = rgb2gray(img)
    img_cdf, bin_centers = exposure.cumulative_distribution(img)
    return np.interp(img, bin_centers, img_cdf)

As of today janeriksolem 's url is broken. 截至今天, janeriksolem的网址已被破坏。

I found however this gist that links the same page and claims to perform histogram equalization without computing the histogram. 然而,我发现这个要点链接同一页并声称在不计算直方图的情况下执行直方图均衡。

The code is: 代码是:

img_eq = np.sort(img.ravel()).searchsorted(img)

Here's an alternate implementation for a single channel image that is fast.这是一个快速的单通道图像的替代实现。 See skimage.exposure.histogram for reference.请参阅skimage.exposure.histogram以供参考。 Using timeit, 'image_histogram_equalization' has a mean execution time was 0.3696 seconds, while this function has a mean execution time of 0.0534 seconds.使用 timeit,'image_histogram_equalization' 的平均执行时间为 0.3696 秒,而此 function 的平均执行时间为 0.0534 秒。 However this implementation also relies on skimage.然而,这个实现也依赖于 skimage。

import numpy as np
from skimage import exposure

def hist_eq(image):
    hist, bins = exposure.histogram(gray, nbins=256, normalize=False)
    # append any remaining 0 values to the histogram
    hist = np.hstack((hist, np.zeros((255 - bins[-1])))) 
    cdf = 255*(hist/hist.sum()).cumsum()
    equalized = cdf[image].astype(np.uint8)

    return equalized

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM