简体   繁体   中英

histogram equalization in image processing python- Gonzalez e Woods

The goal as the title indicates is the equalization of a given image, only that in my case it is over-saturating, by the way, any image that I upload "pops". I am trying to reproduce the Gonzalez and Woods algorithm. In addition to this there must be some way to make the code "lighter" to be compiled, the only rule is that everything has to be done with the numpy library. Link to algorithm: https://pt.wikipedia.org/wiki/Equaliza%C3%A7%C3%A3o_de_histograma

The code has plots in the middle because it was made in jupyter and I used several cells in an attempt to optimize the code, that is, to run it faster.

Here is the code:

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)

There are a couple of things at play here. Judging by your input filename, you're probably working with 16bit TIFF files. If you're dealing with 16bit values, your maximum value is 65535, not 255. This will cause the histogram to be incorrect. There are a couple of huge speed improvements to be made as well.

This block of code you have will be very slow:

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

Use the array as a lookup table instead:

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

Likewise for this block:

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]

Which becomes:

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

Lastly, to make sure everything plays well with the implot function call, convert everything to 8bit RGB to be displayed:

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

And here is the final result:

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()

Input image:

输入

Output image:

输出

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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