I need to implement a high-pass filter from Photoshop using OpenCV. I've read about high-pass filters in OpenCV and tried some kernels, like
[[ 0, -1, 0],
[-1, 4, -1],
[ 0, -1, 0]].
However, the result isn't what I want to get, since the output image is mostly black-and-white while the output image in Photoshop is gray-ish. Here's examples: OpenCV high pass and Photoshop high pass. Also, I tried that:
blur = cv2.GaussianBlur(img,(ksize,ksize),0)
filtered = cv2.subtract(img,blur)
The result is similar to OpenCV high pass.
After that, I tried to add 127 to every pixel of the output image. Indeed, the image look gray-ish now, but still it's different from the Photoshop image.
So what am I missing? Thanks in advance.
EDIT. To Håken Lid: the code now is simply this:
import cv2
import numpy
img = cv2.imread('input.jpg')
blur = cv2.GaussianBlur(img,(31,31),0)
filtered = cv2.subtract(img, blur)
filtered = cv2.add(filtered, 127*numpy.ones(neg_frame.shape, numpy.uint8))
cv2.imwrite('output.jpg', filtered)
Here's result and original picture.
EDIT2. Yes, Håken Lid was right about truncating. I've edited the code once again:
import cv2
import numpy
img = cv2.imread('input.jpg')
blur = cv2.GaussianBlur(img,(31,31),0)
filtered = img - blur
filtered = filtered + 127*numpy.ones(neg_frame.shape, numpy.uint8)
cv2.imwrite('output.jpg', filtered)
The output result is this. Now it's more like what I wanted yet the difference is still here.
my code: photoshop:
LAST EDIT. After playing with GaussianBlur kernel size, I've finally got what I want with ksize = 51
. Thanks a lot for all the help! Now I'm feeling a bit dumb :P
If you take an image with a single white pixel on a black background and apply a filter in Photoshop, you will get a convolution kernel from Photoshop.
Without unnecessary imports and variables. More Pythonic shorter way.
import cv2
def highpass(img, sigma):
return img - cv2.GaussianBlur(img, (0,0), sigma) + 127
img = cv2.imread('lena.png')
img = highpass(img, 3)
cv2.imshow('lena highpass', img)
cv2.waitKey(0)
When you are subtracting the blurred image you need to use floating points instead of integers before you add the 127, otherwise it truncate the negative pixels. I also added an odd number checker to the kernel bit. Now it behaves like Photoshop.
import cv2
import numpy
img = cv2.imread('images/test.jpg')
size =50
if not size%2:
size +=1
kernel = numpy.ones((size,size),numpy.float32)/(size*size)
filtered= cv2.filter2D(img,-1,kernel)
filtered = img.astype('float32') - filtered.astype('float32')
filtered = filtered + 127*numpy.ones(img.shape, numpy.uint8)
cv2.imwrite('output.jpg', filtered)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With