def do_stuff(): image = get_image() dft = cv2.dft(np.float32(image), flags=cv2.DFT_COMPLEX_OUTPUT) # shift the zero-frequncy component to the center of the spectrum dft_shift = np.fft.fftshift(dft) # save image of the image in the fourier domain. magnitude_spectrum = 20 * np.log( cv2.magnitude(dft_shift[:, :, 0], dft_shift[:, :, 1])) # magnitude_spectrum = 20 * np.log(np.sqrt(dft_shift[:, :, 0] + dft_shift[:, :, 1])) cv2.imwrite("magnitude_spectrum.png", magnitude_spectrum) rows, cols = image.shape crow, ccol = rows // 2, cols // 2 # create a mask first, center square is 1, remaining all zeros mask = np.zeros((rows, cols, 2), np.uint8) mask[crow - 30:crow + 30, ccol - 30:ccol + 30] = 1 # mask -= 1 # mask = np.abs(mask) # apply mask and inverse DFT fshift = dft_shift * mask f_ishift = np.fft.ifftshift(fshift) img_back = cv2.idft(f_ishift) img_back = cv2.magnitude(img_back[:, :, 0], img_back[:, :, 1]) img_back = img_back / img_back.max() * 255 cv2.imwrite("filtered_image_low.png", img_back)
def DFT_IDFT_OpenCv(image): dft = cv2.dft(np.float32(image), flags=cv2.DFT_COMPLEX_OUTPUT) dftShift = np.fft.fftshift(dft) fourier = 20 * np.log(cv2.magnitude(dftShift[:, :, 0], dftShift[:, :, 1])) ishift = np.fft.ifftshift(dftShift) iimage = cv2.idft(ishift) iimage = cv2.magnitude(iimage[:, :, 0], iimage[:, :, 1]) Plt_Contrast(image, fourier, iimage)
def LPK_OpenCv(mask, r, c, D0, dftShift): mask[r - D0:r + D0, c - D0:c + D0] = 1 fshift = dftShift * mask ishift = np.fft.ifftshift(fshift) iimage = cv2.idft(ishift) iimage = cv2.magnitude(iimage[:, :, 0], iimage[:, :, 1]) return iimage
def edgeDetectionSobel(img: np.ndarray, thresh: float = 0.2) -> (np.ndarray, np.ndarray): """ Detects edges using the Sobel method :param img: Input image :param thresh: The minimum threshold for the edge response :return: opencv solution, my implementation """ s = np.array([[1, 0, -1], [2, 0, -2], [1, 0, -1]]) thresh *= 255 # my_res = np.sqrt((conv2D(img, s) ** 2 + conv2D(img, s.transpose()) ** 2)) my_res = np.sqrt((cv.filter2D(img, -1, s, borderType=cv.BORDER_REPLICATE) ** 2 + cv.filter2D(img, -1, s.transpose(), borderType=cv.BORDER_REPLICATE) ** 2)) my = np.ndarray(my_res.shape) my[my_res > thresh] = 1 my[my_res < thresh] = 0 cv_res = cv.magnitude(cv.Sobel(img, -1, 1, 0), cv.Sobel(img, -1, 0, 1)) v = np.ndarray(cv_res.shape) v[cv_res > thresh] = 1 v[cv_res < thresh] = 0 return cv_res, my_res
def edgeDetectionSobel(img: np.ndarray, thresh: float = 0.2) -> (np.ndarray, np.ndarray): """ Detects edges using the Sobel method :param img: Input image :param thresh: The minimum threshold for the edge response :return: opencv solution, my implementation """ s = np.array([[1, 0, -1], [2, 0, -2], [1, 0, -1]]) thresh *= 255 my_res = np.sqrt((conv2D(img, s)**2 + conv2D(img, s.transpose())**2)) my = np.ndarray(my_res.shape) my[my_res > thresh] = 1 my[my_res < thresh] = 0 plt.imshow(my, cmap='gray') plt.show() cv_res = cv.magnitude(cv.Sobel(img, -1, 1, 0), cv.Sobel(img, -1, 0, 1)) v = np.ndarray(cv_res.shape) v[cv_res > thresh] = 1 v[cv_res < thresh] = 0 plt.imshow(v, cmap='gray') plt.show() return cv_res, my_res
def apply_mask(img, mask): dft_shift = apply_fourier_transform(img) fshift = dft_shift * mask f_ishift = np.fft.ifftshift(fshift) img_back = cv2.idft(f_ishift) img_back = cv2.magnitude(img_back[:, :, 0], img_back[:, :, 1]) return img_back
def PQFT(prev_img, next_img, map_size = 64): """ Computing saliency using phase spectrum of quaternion fourier transform. Images are 3 channel. """ new_shape = (int(next_img.shape[1]/(next_img.shape[0]/map_size)), map_size) next_img = cv2.resize(next_img, new_shape, cv2.INTER_LINEAR) (b, g, r) = cv2.split(next_img) # color channels R = r-(g+b)/2 G = g-(r+b)/2 B = b-(r+g)/2 Y = (r+g)/2-abs(r-g)/2-b red_green = R-G blue_yellow = B-Y # intensity intensity = np.sum(next_img, axis=-1) # motion prev_img = cv2.resize(prev_img, new_shape, cv2.INTER_LINEAR) prev_intensity = np.sum(prev_img, axis=-1) movement = abs(intensity-prev_intensity) planes = [ movement.astype(np.float64), red_green.astype(np.float64), ] f1 = cv2.merge(planes) f1 = cv2.dft(f1) planes = cv2.split(f1) magnitude1 = cv2.magnitude(planes[0], planes[1]) magnitude1 = cv2.multiply(magnitude1, magnitude1) planes = [ blue_yellow.astype(np.float64), intensity.astype(np.float64), ] f2 = cv2.merge(planes) f2 = cv2.dft(f2) planes = cv2.split(f2) magnitude2 = cv2.magnitude(planes[0], planes[1]) magnitude2 = cv2.multiply(magnitude2, magnitude2) magnitude = magnitude1+magnitude2 magnitude = cv2.sqrt(magnitude) planes[0] = planes[0]/magnitude planes[1] = planes[1]/magnitude f2 = cv2.merge(planes) planes = cv2.split(f1) planes[0] = planes[0]/magnitude planes[1] = planes[1]/magnitude f1 = cv2.merge(planes) cv2.dft(f1, f1, cv2.DFT_INVERSE) cv2.dft(f2, f2, cv2.DFT_INVERSE) planes = cv2.split(f1) magnitude1 = cv2.magnitude(planes[0], planes[1]) magnitude1 = cv2.multiply(magnitude1, magnitude1) planes = cv2.split(f2) magnitude2 = cv2.magnitude(planes[0], planes[1]) magnitude2 = cv2.multiply(magnitude2, magnitude2) magnitude = magnitude1 + magnitude2 magnitude = cv2.GaussianBlur(magnitude, (5, 5), 8, None, 8) saliency = np.zeros((new_shape[0], new_shape[1], 1), np.uint8) saliency = cv2.normalize(magnitude, saliency, 0, 255, cv2.NORM_MINMAX, dtype=cv2.CV_8U) return saliency
def get_spectrum(img): dft_shift = apply_fourier_transform(img) magnitude_spectrum = 20 * np.log( cv2.magnitude(dft_shift[:, :, 0], dft_shift[:, :, 1])) return magnitude_spectrum
def HPK_OpenCv(r, c, D0, dftShift): dftShift[r - D0:r + D0, c - D0:c + D0] = 0 ishift = np.fft.ifftshift(dftShift) iimage = cv2.idft(ishift) iimage = cv2.magnitude(iimage[:, :, 0], iimage[:, :, 1]) return iimage
from cv2 import cv2 as cv from matplotlib import pyplot as plt import numpy as np img = cv.imread('tree.jpg', 0) dft = cv.dft(np.float32(img), flags=cv.DFT_COMPLEX_OUTPUT) dft_shift = np.fft.fftshift(dft) magnitude_spectrum = 20 * \ np.log(cv.magnitude(dft_shift[:,:, 0], dft_shift[:,:, 1])) plt.subplot(121), plt.imshow(img, cmap='gray') plt.title('Source'), plt.xticks([]), plt.yticks([]) plt.subplot(122), plt.imshow(magnitude_spectrum, cmap='gray') plt.title('Magnitude Spectrum'), plt.xticks([]), plt.yticks([]) plt.show() rows, cols = img.shape crow, ccol = int(rows / 2), int(cols / 2) mask = np.zeros((rows, cols, 2), np.uint8) mask[crow - 30:crow + 30, ccol - 30:ccol + 30] = 1 fshift = dft_shift * mask f_ishift = np.fft.ifftshift(fshift) img_back = cv.idft(f_ishift) plt.subplot(121), plt.imshow(img, cmap='gray') plt.title('Source'), plt.xticks([]), plt.yticks([]) plt.subplot(122), plt.imshow(img_back, cmap='gray') plt.title('Magnitude Spectrum'), plt.xticks([]), plt.yticks([])
plt.show() # The result shows High Pass Filtering is an edge detection operation. This is what we have seen in Image Gradients chapter. This also shows that most of the image data is present in the Low frequency region of the spectrum. Anyway we have seen how to find DFT, IDFT etc in Numpy. Now let’s see how to do it in OpenCV. # If you closely watch the result, especially the last image in JET color, you can see some artifacts (One instance I have marked in red arrow). It shows some ripple like structures there, and it is called ringing effects. It is caused by the rectangular window we used for masking. This mask is converted to sinc shape which causes this problem. So rectangular windows is not used for filtering. Better option is Gaussian Windows. # Fourier Transform in OpenCV # OpenCV provides the functions cv2.dft() and cv2.idft() for this. It returns the same result as previous, but with two channels. First channel will have the real part of the result and second channel will have the imaginary part of the result. The input image should be converted to np.float32 first. We will see how to do it. dft = cv2.dft(np.float32(img), flags=cv2.DFT_COMPLEX_OUTPUT) dft_shift = np.fft.fftshift(dft) magnitude_spectrum = 20 * np.log( cv2.magnitude(dft_shift[:, :, 0], dft_shift[:, :, 1])) plt.subplot(121), plt.imshow(img, cmap='gray') plt.title('Input Image'), plt.xticks([]), plt.yticks([]) plt.subplot(122), plt.imshow(magnitude_spectrum, cmap='gray') plt.title('Magnitude Spectrum'), plt.xticks([]), plt.yticks([]) plt.show() # You can also use cv2.cartToPolar() which returns both magnitude and phase in a single shot # So, now we have to do inverse DFT. In previous session, we created a HPF, this time we will see how to remove high frequency contents in the image, ie we apply LPF to image. It actually blurs the image. For this, we create a mask first with high value (1) at low frequencies, ie we pass the LF content, and 0 at HF region. rows, cols = img.shape crow, ccol = rows / 2, cols / 2 # create a mask first, center square is 1, remaining all zeros mask = np.zeros((rows, cols, 2), np.uint8)