Reputation: 13
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)
Upvotes: 1
Views: 574
Reputation: 1005
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:
Upvotes: 2