Stefano Pozzi
Stefano Pozzi

Reputation: 619

Image de-blurring

This post is divided in two


Part One

I have a little issue converting an image from grayscale back to RGB.

Image in question:

enter image description here

I use this code to convert it:

equ = cv2.cvtColor(equ, cv2.COLOR_GRAY2RGB)

without any success though...


Part Two

Moreover I need to de-blur such image. Here I found some code that uses a wiener filter to do so, but when I implement it it doesn't seem to work effectively. Here is the code:

psf = np.ones((5, 5)) / 25
img = convolve2d(equ, psf, 'same')
img += 0.1 * img.std() * np.random.standard_normal(img.shape)
#deconvolved_img = restoration.wiener(img, psf, 1100)
deconvolved = restoration.wiener(img, psf, 1, clip=False)
plt.imshow(deconvolved, cmap='gray')

and this is the output:

enter image description here

Any help for the two problems is greatly appreciated!

Upvotes: 0

Views: 2274

Answers (1)

bfris
bfris

Reputation: 5835

To equalize a color image, it seems a common thing to do is

  • convert the image to HSV or YUV
  • split the image into separate components (e.g. H, S, V)
  • equalize on Value channel (or all three if you want)
  • merge the channels back together

    hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
    split = cv2.split(hsv)  # split is a 3D array containing H S V info
    split[2] = cv2.equalizeHist(split[2])
    hsv = cv2.merge(split)
    img = cv2.cvtColor(hsv, cv2.COLOR_HSV2BGR)
    

For "deblurring", I sometimes use an unsharp mask. From the Wikipedia page on unsharp masking, the formula for this operation is

sharpened = original + (original − blurred) × amount

which can be rearranged to

sharpened = original×(1 + amount) + blurred×(-amount)

Wikipedia says a good starting point for amount is 0.5 to 1.5. In my app I have a spinbox that let's it vary between 0 and 10. For blurring I use a Gaussian blur with kernel size varying from 1 to 31 (must be odd and integer). To do the matrix math, I prefer to use OpenCV functions because they are often faster than NumPy and they will usually autoscale output to values between 0 and 255 (e.g. for 8 bit and 8 bit/3 channel images). Here we use addWeighted which does

dst = src1*alpha + src2*beta + gamma;

amount = 1.5
ksize = 3
blur = cv2.GaussianBlur(img, ksize, 0, 0)
unsharp = cv.addWeighted(img, 1 + amount, blur, -amount, 0)

Upvotes: 3

Related Questions