Laplacian sharpening - grey image as result
<p>As many people before me, I am trying to implement an example of image sharpening from Gonzalez and Woods "Digital image processing" book.</p>

<p>I create a negative Laplacian kernel (-1, -1, -1; -1, 8, -1; -1, -1,-1) and convolve it with the image, then subtract the result from the original image. (I also tried taking positive Laplacian (1, 1, 1; 1, -8, 1; 1, 1, 1) and adding it to the image). On each stage I perform fitting the results into the (0, 255) range, the normalized Laplacian looks nice and grey as it is supposed.</p>

<pre><code>import matplotlib.cm as cm
import scipy.misc
import scipy.ndimage.filters

#Function for plotting abs:
pic_n = 1
def show_abs(I, plot_title):
    plt.title(plot_title)
    plt.tight_layout()
    plt.axis('off')
    plt.imshow(abs(I), cm.gray)

#Reading the image into numpy array:
A = scipy.misc.imread('moon1.jpg', flatten=True)

plt.figure(pic_n)
pic_n += 1
show_abs(A, 'Original image')

A          -= np.amin(A) #map values to the (0, 255) range
A          *= 255.0/np.amax(A)

#Kernel for negative Laplacian
kernel      = np.ones((3,3))*(-1)
kernel[1,1] = 8

#Convolution of the image with the kernel:
Lap         = scipy.ndimage.filters.convolve(A, kernel)

#Laplacian now has negative values in range (-255, 255):
print('L', np.amax(Lap), np.amin(Lap))

plt.figure(pic_n)
pic_n += 1
show_abs(Lap, 'Laplacian')

#Map Laplacian to the (0, 255) range:
Lap        -= np.amin(Lap)
Lap        *= 255.0/np.amax(Lap)
print('L', np.amax(Lap), np.amin(Lap))

plt.figure(pic_n)
pic_n += 1
show_abs(Lap, 'Normalized Laplacian')

A         += Lap #Add negative Laplacian to the original image

print('A', np.amax(A), np.amin(A))
A          -= np.amin(A)
A          *= 255.0/np.amax(A)
print('A', np.amax(A), np.amin(A))

plt.figure(pic_n)
pic_n += 1
show_abs(A, 'Laplacian filtered img')

plt.show()
</code></pre>

<h2>Original image:</h2>

<p><img src="http://i.stack.imgur.com/tM3V5.jpg" alt="Original image"></p>

<h2>Results:</h2>

<p><img src="http://i.stack.imgur.com/o6Dmy.png" alt="Results"></p>

<p>The problem is that the final sharpened image looks faded and grey. I tried doing histogram equalization to make it more contrasting, but the result was weird. I thought about applying gamma-correction, but I don't like the voluntary choice of the gamma coefficient.</p>

<p>It seems there must be an easy and convenient way of bringing the image back to the original dynamic range. I would appreciate ideas and comments on the code. Thank you!</p>

<p>After correcting the code as <strong>ali_m</strong> advised, I apply local histogram equalization - it slows down the code and also adds dependency on the OpenCV library, but the resulting image looks fine.</p>

<pre><code>import numpy as np
import matplotlib.pyplot as plt
import matplotlib.cm as cm
import scipy.misc
import scipy.ndimage.filters
import cv2

#Function for plotting abs:
pic_n       = 1
def show_abs(I, plot_title):
    plt.title(plot_title)
    plt.tight_layout()
    plt.axis('off')
    plt.imshow(abs(I), cm.gray)

#Reading of the image into numpy array:
A0           = scipy.misc.imread('moon1.jpg', flatten=True)
A0          -= np.amin(A0)#map values to the (0, 255) range
A0          *= 255.0/np.amax(A0)
print('Img         ', np.amax(A0), np.amin(A0))
#&gt;&gt;&gt; Img          255.0 0.0

#Kernel for negative Laplacian
kernel      = np.ones((3,3))*(-1)
kernel[1,1] = 8

#Convolution of the image with the kernel:
Lap        = scipy.ndimage.filters.convolve(A0, kernel)

#Laplacian now has negative values
print('Original Lap', np.amax(Lap), np.amin(Lap))
#&gt;&gt;&gt; Original Lap 1151.0 -1166.0

#Map Laplacian to some new range:
Laps        = Lap*100.0/np.amax(Lap) #Sharpening factor!
print('Scaled Lap  ', np.amax(Laps), np.amin(Laps))
#&gt;&gt;&gt; Scaled Lap   100.0 -101.303

plt.figure(pic_n)
pic_n += 1
plt.subplot(1,2,1)
show_abs(Lap, 'Laplacian')
plt.subplot(1,2,2)
show_abs(Laps, 'Scaled Laplacian')

A           = A0 + Laps #Add negative Laplacian to the original image

print('SharpImg    ', np.amax(A), np.amin(A))
#&gt;&gt;&gt; SharpImg     350.917 -81.06

A = abs(A) #Get rid of negative values
print('SharpImg abs', np.amax(A), np.amin(A))

A           *= 255.0/np.amax(A)
print('SharpImg after scaling', np.amax(A), np.amin(A))
#&gt;&gt;&gt; SharpImg abs 350.917 0.0

# Local Histogram Equalization with OpenCV:
A_cv2       = A
A_cv2       = A_cv2.astype(np.uint8)

tile_s0     = 4
tile_s1     = 4

clahe       = cv2.createCLAHE(clipLimit=1, tileGridSize=(tile_s0,tile_s1))
A_cv2       = clahe.apply(A_cv2)

plt.figure(pic_n)
pic_n += 1
plt.subplot(2,1,1)
plt.hist(A_cv2)
plt.title('Original Histogram')
plt.subplot(2,1,2)
plt.hist(A_cv2)
plt.title('Locally Equalized Histogram')

plt.figure(pic_n)
pic_n += 1
plt.subplot(1,3,1)
show_abs(A0, 'Original image')
plt.subplot(1,3,2)
show_abs(A, 'Laplacian filtered img')
plt.subplot(1,3,3)
show_abs(A_cv2, 'Local Hist equalized img')
plt.show()
</code></pre>

<p><a href="http://i.stack.imgur.com/pbZN9.png" rel="nofollow"><img src="http://i.stack.imgur.com/pbZN9.png" alt="Results:"></a></p>

python image-processing scipy