【问题标题】:histogram equalization in image processing python- Gonzalez e Woods图像处理中的直方图均衡 python-Gonzalez e Woods
【发布时间】:2021-06-24 11:11:33
【问题描述】:

标题所示的目标是均衡给定图像,只是在我的情况下它是过度饱和的,顺便说一下,我上传的任何图像“弹出”。我正在尝试重现 Gonzalez 和 Woods 算法。除此之外,必须有一些方法可以使代码“更轻”地被编译,唯一的规则是一切都必须使用 numpy 库来完成。 算法链接:https://pt.wikipedia.org/wiki/Equaliza%C3%A7%C3%A3o_de_histograma

代码中间有绘图,因为它是在 jupyter 中制作的,我使用了几个单元格来尝试优化代码,即更快地运行它。

代码如下:

import numpy as np
import matplotlib.pyplot as plt

olho=plt.imread('training/images/29_training.tif')
olho_verde=olho[:,:,1]

teste=np.copy(olho_verde)

incidencia=np.zeros((teste.size)) 
ocorrencia=np.zeros(256)
k=0
for i in range(584):
    for j in range(565):
        incidencia[k]=teste[i,j] #all image intensities
        k=k+1
count=0
for i in range(256): # how many times each intensity occurs for a total number of pixels of 255
    for j in range(len(incidencia)):
        if incidencia[j]==i:
            count=count+1
    ocorrencia[i]=count
    count=0

acumulado=np.zeros(256) #down here I have the algorithm so with histogram and image plot
count=0
for i in range(256):
    count=count+ocorrencia[i]
    acumulado[i]=count
        
constante=255/(584*565)

for i in range(256):
    acumulado[i]=round(acumulado[i]*constante,0)
    
plt.figure(figsize=(20,8))    
plt.hist(acumulado,256,[0,256])
plt.show

equaliza=np.copy(olho_verde)
i1,j1=np.nonzero(equaliza)

for i in range(256):
    for j in range(len(i1)):
        if(equaliza[i1[j],j1[j]]==i):
            equaliza[i1[j],j1[j]]=acumulado[i]
            
plt.imshow(equaliza)

【问题讨论】:

    标签: image numpy image-processing


    【解决方案1】:

    这里有几件事在起作用。从您的输入文件名来看,您可能正在使用 16 位 TIFF 文件。如果您正在处理 16 位值,则最大值是 65535,而不是 255。这将导致直方图不正确。还有一些巨大的速度改进。

    你的这段代码会很慢:

    for i in range(256):
        for j in range(len(incidencia)):
            if incidencia[j]==i:
                count=count+1
        ocorrencia[i]=count
        count=0
    

    将数组用作查找表:

    for j in range(len(incidencia)):
        ocorrencia[int(incidencia[j])] += 1
    

    对于这个块也是如此:

    for i in range(256):
        for j in range(len(i1)):
            if(equaliza[i1[j],j1[j]]==i):
                equaliza[i1[j],j1[j]]=acumulado[i]
    

    变成:

    for j in range(len(i1)):
        equaliza[i1[j], j1[j]] = acumulado[int(equaliza[i1[j], j1[j]])]
    

    最后,为确保 implot 函数调用一切正常,将所有内容转换为 8 位 RGB 以显示:

    equaliza = equaliza.astype("uint8")
    equaliza = np.stack((equaliza,) * 3, axis=-1)
    

    这是最终结果:

    import numpy as np
    import matplotlib.pyplot as plt
    
    olho = plt.imread('faded.jpg')
    olho_verde = olho[:, :, 1]
    
    teste = np.copy(olho_verde)
    
    if teste.dtype == np.uint16:
        depth = 65536
    else:
        depth = 256
    
    height, width = teste.shape
    
    incidencia = np.zeros((teste.size))
    ocorrencia = np.zeros(depth)
    k = 0
    for i in range(height):
        for j in range(width):
            incidencia[k] = teste[i, j]
            k = k + 1
    count = 0
    
    for j in range(len(incidencia)):
        ocorrencia[int(incidencia[j])] += 1
    
    acumulado = np.zeros(depth)
    count = 0
    for i in range(depth):
        count += ocorrencia[i]
        acumulado[i] = count
    
    constante = (depth-1) / (height * width)
    
    for i in range(depth):
        acumulado[i] = round(acumulado[i] * constante, 0)
    
    equaliza = np.copy(olho_verde)
    i1, j1 = np.nonzero(equaliza)
    
    for j in range(len(i1)):
        equaliza[i1[j], j1[j]] = acumulado[int(equaliza[i1[j], j1[j]])]
    
    equaliza = equaliza.astype("uint8")
    equaliza = np.stack((equaliza,) * 3, axis=-1)
    
    plt.imshow(equaliza)
    plt.show()
    

    输入图片:

    输出图像:

    【讨论】:

    • Ij 上有一个双循环,用于复制 incidencia[k] = teste[i, j]。这是一个毫无意义的副本。为什么要把它留在里面?
    • @Jon 非常感谢您的回答,时间级别的代码测试和优化是超现实的!正如你所看到的,我是从这个 python 世界开始的,有些事情我仍然不明白,比如替换 for 循环。我会研究这个文档。再次感谢!
    • “@CrisLuengo 专家先生,你去哪儿了?发生了什么?”这是什么意思?你希望我在哪里?我有义务在半夜上网吗?你期待我的回复吗?另外,如果你已经 90% 在那里,我为什么要写一个答案?这就是 cmets 的用途,以帮助改进答案。不要被建设性的批评冒犯。如果你这样做了,世界确实是一个非常艰难的地方。
    猜你喜欢
    • 2012-04-25
    • 2010-12-23
    • 1970-01-01
    • 1970-01-01
    • 2013-11-20
    • 2013-01-25
    • 1970-01-01
    • 1970-01-01
    • 2019-07-21
    相关资源
    最近更新 更多