Reputation: 129
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.
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
Upvotes: 12
Views: 17266
Reputation: 107
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)
Upvotes: 3
Reputation: 11
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)
Upvotes: 1
Reputation: 2018
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.
Upvotes: 3