def calc_magnitude_spectrum(self): """Plots the magnitude spectrum This method calculates the magnitude spectrum of the image passed to the class constructor. :returns: magnitude spectrum """ # convert the frame to grayscale if necessary if len(self.frame_orig.shape) > 2: frame = cv2.cvtColor(self.frame_orig, cv2.COLOR_BGR2GRAY) else: frame = self.frame_orig # expand the image to an optimal size for FFT rows, cols = self.frame_orig.shape[:2] nrows = cv2.getOptimalDFTSize(rows) ncols = cv2.getOptimalDFTSize(cols) frame = cv2.copyMakeBorder(frame, 0, ncols - cols, 0, nrows - rows, cv2.BORDER_CONSTANT, value=0) # do FFT and get log-spectrum img_dft = np.fft.fft2(frame) spectrum = np.log10(np.abs(np.fft.fftshift(img_dft))) # return for plotting return 255 * spectrum / np.max(spectrum)
def calc_magnitude_spectrum(img: np.ndarray): """Plot the magnitude spectrum This method calculates the magnitude spectrum of the image passed to the class constructor. :returns: magnitude spectrum """ # convert the frame to grayscale if necessary if len(img.shape) > 2: img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # expand the image to an optimal size for FFT rows, cols = img.shape nrows = cv2.getOptimalDFTSize(rows) ncols = cv2.getOptimalDFTSize(cols) frame = cv2.copyMakeBorder(img, 0, ncols - cols, 0, nrows - rows, cv2.BORDER_CONSTANT, value=0) # do FFT and get log-spectrum img_dft = np.fft.fft2(img) spectrum = np.log10(np.abs(np.fft.fftshift(img_dft))) # return normalized return spectrum / np.max(spectrum)
def dft_optsize_same(im0, im1): """Resize 2 image same size for optimal DFT and computes it Parameters ---------- im0: 2d array First image im1: 2d array Second image Returns ------- dft0: 2d array The dft of the first image dft1: 2d array The dft of the second image Notes ----- dft0 and dft1 will have the same size """ im0 = np.asarray(im0) im1 = np.asarray(im1) #save shape shape0 = im0.shape shape1 = im1.shape #get optimal size ys = max(cv2.getOptimalDFTSize(shape0[0]), cv2.getOptimalDFTSize(shape1[0])) xs = max(cv2.getOptimalDFTSize(shape0[1]), cv2.getOptimalDFTSize(shape1[1])) shape = [ys, xs] f0 = dft_optsize(im0, shape=shape) f1 = dft_optsize(im1, shape=shape) return f0, f1
def cv2_deconvolution(image, b): dft_m = cv2.getOptimalDFTSize(image.shape[0] + b.shape[0] - 1) dft_n = cv2.getOptimalDFTSize(image.shape[1] + b.shape[1] - 1) c = np.zeros((image.shape[0] + d - 1, image.shape[1] + d - 1), dtype='uint8') # getting gaussian dft dft_b = np.zeros((dft_m, dft_n), dtype='float64') dft_b[:b.shape[0], :b.shape[1]] = b psf = cv2.dft(dft_b, flags=cv2.DFT_COMPLEX_OUTPUT) psf2 = (psf**2).sum(-1) ipsf = psf / (psf2 + 0.7)[..., np.newaxis] # getting layers dft dfts = [] new_channels = [] channels = cv2.split(image) for i, channel in enumerate(channels): #cv2.imshow('channel %d'%i, channel) a = np.array(channel, dtype='float64') dft_a = np.zeros((dft_m, dft_n), dtype='float64') dft_a[:a.shape[0], :a.shape[1]] = a print 'deconv' dft_a = cv2.dft(dft_a, flags=cv2.DFT_COMPLEX_OUTPUT) dft_a = cv2.mulSpectrums(dft_a, ipsf, 0) print dft_a dft_a = cv2.idft(dft_a, flags=cv2.DFT_SCALE | cv2.DFT_REAL_OUTPUT) print dft_a tmp = dft_a[d / 2:a.shape[0] + d / 2, d / 2:a.shape[1] + d / 2] channel = np.array(tmp, dtype='uint8') cv2.imshow('new channel %d' % i, channel) new_channels.append(channel) result = cv2.merge(new_channels) return result
def cv2_deconvolution(image, b): dft_m = cv2.getOptimalDFTSize(image.shape[0] + b.shape[0] - 1) dft_n = cv2.getOptimalDFTSize(image.shape[1] + b.shape[1] - 1) c = np.zeros((image.shape[0] + d - 1, image.shape[1] + d - 1), dtype='uint8') # getting gaussian dft dft_b = np.zeros((dft_m, dft_n), dtype='float64') dft_b[:b.shape[0], :b.shape[1]] = b psf = cv2.dft(dft_b, flags=cv2.DFT_COMPLEX_OUTPUT) psf2 = (psf**2).sum(-1) ipsf = psf / (psf2 + 0.7)[..., np.newaxis] # getting layers dft dfts = [] new_channels = [] channels = cv2.split(image) for i, channel in enumerate(channels): #cv2.imshow('channel %d'%i, channel) a = np.array(channel, dtype='float64') dft_a = np.zeros((dft_m, dft_n), dtype='float64') dft_a[:a.shape[0], :a.shape[1]] = a print 'deconv' dft_a = cv2.dft(dft_a, flags=cv2.DFT_COMPLEX_OUTPUT) dft_a = cv2.mulSpectrums(dft_a, ipsf, 0) print dft_a dft_a = cv2.idft(dft_a, flags=cv2.DFT_SCALE | cv2.DFT_REAL_OUTPUT) print dft_a tmp = dft_a[d/2:a.shape[0] + d/2, d/2:a.shape[1] + d/2] channel = np.array(tmp, dtype='uint8') cv2.imshow('new channel %d'%i, channel) new_channels.append(channel) result = cv2.merge(new_channels) return result
def getReflectance(img): img = np.log1p(np.array(img, dtype="float") / 255) h, w = img.shape optHeight = cv2.getOptimalDFTSize(h) optWidth = cv2.getOptimalDFTSize(w) padded = cv2.copyMakeBorder(img, 0, optHeight - h, 0, optWidth - w, cv2.BORDER_CONSTANT, value=0) dft = cv2.dft(np.float32(padded), flags=cv2.DFT_COMPLEX_OUTPUT) dft = np.fft.fftshift(dft) highPass = createGaussianFilter(dft.shape, 20) highPassed = cv2.mulSpectrums(dft, highPass, flags=0) highPassed = np.fft.fftshift(highPassed) highFiltered = cv2.dft(highPassed, flags=cv2.DFT_INVERSE) min, max = np.amin(highFiltered), np.amax(highFiltered) highFiltered = (highFiltered - min) / (max - min) recovered = np.expm1(highFiltered) final = recovered[:h, :w, 0] low, high, _, _ = cv2.minMaxLoc(final) final = final * (1.0 / (high - low)) + ((-low) / (high - low)) final = np.uint8(final * 255) return final
def measure_blurriness_DFT(img): """ More complex blurriness measure averaging top 90% of frequencies in image """ img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) blur_img = cv2.GaussianBlur(img, (3, 3), 0) dftHeight = cv2.getOptimalDFTSize(blur_img.shape[0]) dftWidth = cv2.getOptimalDFTSize(blur_img.shape[1]) complexImg = np.zeros([dftHeight, dftWidth, 2], dtype=float) complexImg[0:img.shape[0], 0:img.shape[1], 0] = img / 255.0 dft_img = cv2.dft(complexImg) dft_img = cv2.magnitude(dft_img[:, :, 0], dft_img[:, :, 1]) dft_img = cv2.log(dft_img + 1) cv2.normalize(dft_img, dft_img, 0, 1, cv2.NORM_MINMAX) dft_img_h, dft_img_w = dft_img.shape[:2] win_size = dft_img_w * 0.55 window = dft_img[dft_img_h / 2 - win_size:dft_img_h / 2 + win_size, dft_img_w / 2 - win_size:dft_img_w / 2 + win_size] return np.mean(np.abs(window))
def fftImage(img_gray, rows, cols): rPadded = cv2.getOptimalDFTSize(rows) cPadded = cv2.getOptimalDFTSize(cols) imgPadded = np.zeros((rPadded, cPadded), dtype=np.float32) imgPadded[:rows, :cols] = img_gray img_fft = cv2.dft(imgPadded, flags=cv2.DFT_COMPLEX_OUTPUT) return img_fft
def PlotMagnitudeSpectrum(self): # convert the frame to grayscale if necessary if len(self.frameOrig.shape) > 2: frame = cv3.cvtColor(self.frameOrig, cv3.COLOR_BGR2GRAY) else: frame = self.frameOrig # expand the image to an optimal size for FFT rows, cols = self.frameOrig.shape[:2] nrows = cv3.getOptimalDFTSize(rows) ncols = cv3.getOptimalDFTSize(cols) frame = cv3.copyMakeBorder(frame, 0, ncols - cols, 0, nrows - rows, cv3.BORDER_CONSTANT, value=0) # do FFT and get log-spectrum imgDFT = np.fft.fft2(frame) spectrum = np.log10(np.abs(np.fft.fftshift(imgDFT))) # return for plotting return 255 * spectrum / np.max(spectrum)
def fft2Conv(I, kernel, borderType=cv2.BORDER_DEFAULT): #图像矩阵的高、宽 R, C = I.shape[:2] #卷积核的高、宽 r, c = kernel.shape[:2] #卷积核的半径 tb = (r - 1) / 2 lr = (c - 1) / 2 #第一步:扩充边界 I_padded = cv2.copyMakeBorder(I, tb, tb, lr, lr, borderType) #第二步:对 I_padded 和 kernel 右侧和下侧补零 #满足二维快速傅里叶变换的行数、列数 rows = cv2.getOptimalDFTSize(I_padded.shape[0] + r - 1) cols = cv2.getOptimalDFTSize(I_padded.shape[1] + c - 1) #补零 I_padded_zeros = np.zeros((rows, cols), np.float64) I_padded_zeros[:I_padded.shape[0], :I_padded.shape[1]] = I_padded kernel_zeros = np.zeros((rows, cols), np.float64) kernel_zeros[:kernel.shape[0], :kernel.shape[1]] = kernel #第三步:快速傅里叶变换 fft2_Ipz = np.zeros((rows, cols, 2), np.float64) cv2.dft(I_padded_zeros, fft2_Ipz, cv2.DFT_COMPLEX_OUTPUT) fft2_kz = np.zeros((rows, cols, 2), np.float64) cv2.dft(kernel_zeros, fft2_kz, cv2.DFT_COMPLEX_OUTPUT) #第四步:两个快速傅里叶变换点乘 Ipz_rz = cv2.mulSpectrums(fft2_Ipz, fft2_kz, cv2.DFT_ROWS) #第五步:傅里叶逆变换,并只取实部 ifft2FullConv = np.zeros((rows, cols), np.float64) cv2.dft(Ipz_rz, ifft2FullConv, cv2.DFT_REAL_OUTPUT + cv2.DFT_INVERSE + cv2.DFT_SCALE) print np.max(ifft2FullConv) #第六步:裁剪,同输入的图像矩阵尺寸一样 sameConv = np.copy(ifft2FullConv[r - 1:R + r - 1, c - 1:C + c - 1]) return sameConv
def image_fft(img, method='cv'): irows, icols = img.shape m = cv2.getOptimalDFTSize(irows) n = cv2.getOptimalDFTSize(icols) right, bottom = n - icols, m - irows nimg = cv2.copyMakeBorder(img, 0, bottom, 0, right, cv2.BORDER_CONSTANT, value=0) # planes = [ nimg.astype('float32'), np.zeros(nimg.shape).astype('float32') ] # complexImg = cv2.merge(planes) # complexImg = cv2.dft(complexImg) complexImg = cv2.dft(nimg.astype('float32'), flags=cv2.DFT_COMPLEX_OUTPUT) if method == 'cv': magImg = cv_fft_shift(complexImg) else: magImg = np_fft_shift(complexImg) # magImg = cv2.normalize(magImg, alpha=0, beta=1, norm_type=cv2.NORM_MINMAX) return magImg
def fourier_bandpass(self): """Function used to calcualte FFT of the image and apply a bandpass filter""" rows, cols = self.array.shape nrows = cv2.getOptimalDFTSize(rows) ncols = cv2.getOptimalDFTSize(cols) nimg = np.zeros((nrows, ncols)) nimg[:rows, :cols] = self.array data_fft = np.fft.rfft2(nimg) fft_abs = np.abs(data_fft) h, w = fft_abs.shape l = int(min(h / 2, w)) # rfft2 returns half the width of fft2 min_l = 0.2 * l max_l = 0.6 * l def filter_indices(x, y, max_x, max_y): x2, y2 = x * x, y * y return (x > 0.05 * max_x) \ & (y > 0.05 * max_y) \ & (min_l * min_l < x2 + y2) \ & (x2 + y2 < max_l * max_l) # count values in a band around the "origin" # positive offsets start at [0, 0], negative at [h, 0] and go backwards indices = np.fromfunction(lambda y, x: filter_indices(y, x, h / 2., w), (h, w)) indices |= np.fromfunction( lambda y, x: filter_indices(h - y, x, h / 2., w), (h, w)) return np.sum(fft_abs[indices])
def dftcv(): h = cv2.getOptimalDFTSize(self.grayimage.shape[0]) w = cv2.getOptimalDFTSize(self.grayimage.shape[1]) padding = cv2.copyMakeBorder(self.grayimage, 0, h - len(self.image), 0, w - len(self.image[0]), cv2.BORDER_CONSTANT, value=[0, 0, 0]) planes = [np.float32(padding), np.zeros(padding.shape, np.float32)] complexI = cv2.merge(planes) cv2.dft(complexI, complexI) cv2.split(complexI, planes) cv2.magnitude(planes[0], planes[1], planes[0]) magI = planes[0] matOfOnes = np.ones(magI.shape, dtype=magI.dtype) cv2.add(matOfOnes, magI, magI) cv2.log(magI, magI) magI_rows, magI_cols = magI.shape magI = magI[0:(magI_rows & -2), 0:(magI_cols & -2)] cx = int(magI_rows / 2) cy = int(magI_cols / 2) q0 = magI[0:cx, 0:cy] q1 = magI[cx:cx + cx, 0:cy] q2 = magI[0:cx, cy:cy + cy] q3 = magI[cx:cx + cx, cy:cy + cy] tmp = np.copy(q0) magI[0:cx, 0:cy] = q3 magI[cx:cx + cx, cy:cy + cy] = tmp tmp = np.copy(q1) magI[cx:cx + cx, 0:cy] = q2 magI[0:cx, cy:cy + cy] = tmp cv2.normalize(magI, magI, 0, 1, cv2.NORM_MINMAX) return magI
def __init__(self, image, low, high): self.image_name = image self.low = low self.high = high self.filter = None self.output = None self.filter_type = None self.padRows = None self.padCols = None original_input = cv2.imread(image,0) rows, cols = original_input.shape if(rows < cols): original_input = cv2.transpose(original_input) self.transposed = True else: self.transposed = False rows, cols = original_input.shape optimalRows = cv2.getOptimalDFTSize(rows) optimalCols = cv2.getOptimalDFTSize(cols) self.padRows = optimalRows - rows self.padCols = optimalCols - cols self.input = np.zeros((optimalRows,optimalCols)) self.input[:rows,:cols] = original_input self.dftshift = get_dft_shift(self.input) plt.subplots_adjust(left=0, bottom=0.05, right=1, top=1, wspace=0, hspace=0) plt.subplot(131) plt.axis('off') plt.title('original image') plt.imshow(self.input, cmap = 'gray',interpolation='nearest') self.axslow = plt.axes([0.05, 0.01, 0.5, 0.02]) self.slow = Slider(self.axslow, 'low', 0.01, 1, valinit=self.low) self.slow.on_changed(self.updateLow) self.axhigh = plt.axes([0.05, 0.03, 0.5, 0.02]) self.shigh = Slider(self.axhigh, 'high', 0.01, 1, valinit=self.high) self.shigh.on_changed(self.updateHigh) self.slow.slidermax=self.shigh self.shigh.slidermin=self.slow self.axfilter = plt.axes([0.62, 0.01, 0.15, 0.04]) self.rfilter = RadioButtons(self.axfilter, ('Gaussian Filter', 'Ideal Filter')) self.rfilter.on_clicked(self.updateFilterType) self.filter_type = self.rfilter.value_selected self.axprocess = plt.axes([0.8, 0.01, 0.08, 0.04]) self.bprocess = Button(self.axprocess, 'Process') self.bprocess.on_clicked(self.process) self.axsave = plt.axes([0.88, 0.01, 0.08, 0.04]) self.bsave = Button(self.axsave, 'Save') self.bsave.on_clicked(self.save)
def cv2_convolution(image, b): dft_m = cv2.getOptimalDFTSize(image.shape[0] + b.shape[0] - 1) dft_n = cv2.getOptimalDFTSize(image.shape[1] + b.shape[1] - 1) d = b.shape[0] c = np.zeros((image.shape[0] + d - 1, image.shape[1] + d - 1), dtype='uint8') # getting gaussian dft dft_b = np.zeros((dft_m, dft_n), dtype='float64') dft_b[:b.shape[0], :b.shape[1]] = b dft_b = cv2.dft(dft_b, flags=cv2.DFT_REAL_OUTPUT) # getting layers dft dfts = [] new_channels = [] channels = cv2.split(image) for i, channel in enumerate(channels): #cv2.imshow('channel %d'%i, channel) a = np.array(channel, dtype='float64') dft_a = np.zeros((dft_m, dft_n), dtype='float64') dft_a[:a.shape[0], :a.shape[1]] = a dft_a = cv2.dft(dft_a, flags=cv2.DFT_REAL_OUTPUT) dft_a = cv2.mulSpectrums(dft_a, dft_b, 0) dft_a = cv2.idft(dft_a, flags=cv2.DFT_SCALE | cv2.DFT_REAL_OUTPUT) tmp = dft_a[d / 2:a.shape[0] + d / 2, d / 2:a.shape[1] + d / 2] channel = np.array(tmp, dtype='uint8') #cv2.imshow('new channel %d'%i, channel) new_channels.append(channel) result = cv2.merge(new_channels) return result
def filtre_passe_bas(image, filtre): o_rows, o_cols = image.shape m = cv.getOptimalDFTSize(o_rows) n = cv.getOptimalDFTSize(o_cols) new_image = cv.copyMakeBorder(image, 0, m - o_rows, 0, n - o_cols, cv.BORDER_CONSTANT, value=[0, 0, 0]) dft = cv.dft(np.float32(new_image), flags=cv.DFT_COMPLEX_OUTPUT) dft_shift = np.fft.fftshift(dft) rows, cols = new_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) crow_n = crow * filtre / 100 ccol_n = ccol * filtre / 100 mask[int(crow - crow_n):int(crow + crow_n), int(ccol - ccol_n):int(ccol + ccol_n)] = 1 # apply mask and inverse DFT fshift = dft_shift * mask f_ishift = np.fft.ifftshift(fshift) img_back = cv.idft(f_ishift) img_back = cv.magnitude(img_back[:, :, 0], img_back[:, :, 1]) return img_back[:o_rows, :o_cols]
def calc_magnitude_spectrum(self): """Plots the magnitude spectrum This method calculates the magnitude spectrum of the image passed to the class constructor. :returns: magnitude spectrum """ # convert the frame to grayscale if necessary if len(self.frame_orig.shape) > 2: frame = cv2.cvtColor(self.frame_orig, cv2.COLOR_BGR2GRAY) else: frame = self.frame_orig # expand the image to an optimal size for FFT rows, cols = self.frame_orig.shape[:2] nrows = cv2.getOptimalDFTSize(rows) ncols = cv2.getOptimalDFTSize(cols) frame = cv2.copyMakeBorder(frame, 0, ncols-cols, 0, nrows-rows, cv2.BORDER_CONSTANT, value=0) # do FFT and get log-spectrum img_dft = np.fft.fft2(frame) spectrum = np.log10(np.abs(np.fft.fftshift(img_dft))) # return for plotting return 255*spectrum/np.max(spectrum)
def zeroPadding(imagem): cinza_h2 = cv.getOptimalDFTSize(imagem.shape[0]) cinza_w2 = cv.getOptimalDFTSize(imagem.shape[1]) # print("x = {} -> {}, y = {} -> {}".format(imagem.shape[0], cinza_h2, imagem.shape[1], cinza_w2)) imagem_padded = np.zeros((cinza_h2, cinza_w2), dtype='uint8') imagem_padded[0:cinza_h, 0:cinza_w] = imagem return imagem_padded
def fft_pad(mat: np.ndarray, min: Tuple[int, int] = None): if min is not None: initial_width = max(min[0], mat.shape[0]) initial_height = max(min[1], mat.shape[1]) else: initial_width, initial_height = mat.shape dft_size = (cv.getOptimalDFTSize(initial_width), cv.getOptimalDFTSize(initial_height)) row_pad = dft_size[0] - mat.shape[0] row_pad_top = row_pad // 2 row_pad_bottom = row_pad - row_pad_top col_pad = dft_size[1] - mat.shape[1] col_pad_left = col_pad // 2 col_pad_right = col_pad - col_pad_left res = cv.copyMakeBorder(mat, row_pad_top, row_pad_bottom, col_pad_left, col_pad_right, cv.BORDER_CONSTANT, value=0) return res, [row_pad_top, row_pad_bottom, col_pad_left, col_pad_right]
def cv2_convolution(image, b): dft_m = cv2.getOptimalDFTSize(image.shape[0] + b.shape[0] - 1) dft_n = cv2.getOptimalDFTSize(image.shape[1] + b.shape[1] - 1) d = b.shape[0] c = np.zeros((image.shape[0] + d - 1, image.shape[1] + d - 1), dtype='uint8') # getting gaussian dft dft_b = np.zeros((dft_m, dft_n), dtype='float64') dft_b[:b.shape[0], :b.shape[1]] = b dft_b = cv2.dft(dft_b, flags=cv2.DFT_REAL_OUTPUT) # getting layers dft dfts = [] new_channels = [] channels = cv2.split(image) for i, channel in enumerate(channels): #cv2.imshow('channel %d'%i, channel) a = np.array(channel, dtype='float64') dft_a = np.zeros((dft_m, dft_n), dtype='float64') dft_a[:a.shape[0], :a.shape[1]] = a dft_a = cv2.dft(dft_a, flags=cv2.DFT_REAL_OUTPUT) dft_a = cv2.mulSpectrums(dft_a, dft_b, 0) dft_a = cv2.idft(dft_a, flags= cv2.DFT_SCALE | cv2.DFT_REAL_OUTPUT) tmp = dft_a[d/2:a.shape[0] + d/2, d/2:a.shape[1] + d/2] channel = np.array(tmp, dtype='uint8') #cv2.imshow('new channel %d'%i, channel) new_channels.append(channel) result = cv2.merge(new_channels) return result
def dft_mask( mat, mask): height, width = mat.shape[:2] if height == mask.shape[ 0] and width == mask.shape[ 1]: padded = mat else: padded_height = cv2.getOptimalDFTSize( height) padded_width = cv2.getOptimalDFTSize( width) if padded_height != mask.shape[ 0] or padded_width != mask.shape[ 1]: raise Exception( "mismatched shape of image and mask!") padded = cv2.copyMakeBorder( mat, 0, padded_height - height, 0, padded_width - width, cv2.BORDER_CONSTANT, value = [ mat.mean()]) masks = cv2.split( mask) channels = cv2.split( padded) result_channels = [] for i in range( len( channels)): mask = np.fft.ifftshift( masks[ i % len( masks)]) dft = cv2.dft( channels[ i].astype( np.float32), flags = cv2.DFT_COMPLEX_OUTPUT) dft *= np.stack( [ mask] * 2, axis = 2) rec = cv2.idft( dft, flags = cv2.DFT_SCALE | cv2.DFT_COMPLEX_OUTPUT) rec = cv2.magnitude( rec[:,:,0], rec[:,:,1]) result_channels.append( rec) result = cv2.merge( result_channels)[ 0:height, 0:width] if not np.issubdtype( mat.dtype, np.floating): result = result.round() return result.clip( 0, data_range( mat)).astype( mat.dtype)
def PlotPowerSpectrum(self): # convert the frame to grayscale if necessary if len(self.frameOrig.shape)>2: frame = cv3.cvtColor(self.frameOrig, cv3.COLOR_BGR2GRAY) else: frame = self.frameOrig # expand the image to an optimal size for FFT rows,cols = self.frameOrig.shape[:2] nrows = cv3.getOptimalDFTSize(rows) ncols = cv3.getOptimalDFTSize(cols) frame = cv3.copyMakeBorder(frame, 0, ncols-cols, 0, nrows-rows, cv3.BORDER_CONSTANT, value = 0) # do FFT and get log-spectrum if self.useNumpyFFT: imgDFT = np.fft.fft2(frame) spectrum = np.log10(np.real(np.abs(imgDFT))**2) else: imgDFT = cv3.dft(np.float32(frame), flags=cv3.DFT_COMPLEX_OUTPUT) spectrum = np.log10(imgDFT[:,:,0]**2+imgDFT[:,:,1]**2) # radial average L = max(frame.shape) freqs = np.fft.fftfreq(L)[:L/2] dists = np.sqrt(np.fft.fftfreq(frame.shape[0])[:,None]**2 + np.fft.fftfreq(frame.shape[1])**2) dcount = np.histogram(dists.ravel(), bins=freqs)[0] histo,bins = np.histogram(dists.ravel(), bins=freqs, weights=spectrum.ravel()) centers = (bins[:-1] + bins[1:]) / 2 plt.plot(centers, histo/dcount) plt.xlabel('frequency') plt.ylabel('log-spectrum') plt.show()
def temporal_ideal_filter(self, src): channels = cv2.split(src) for i in range(len(channels)): current = channels[i] width = cv2.getOptimalDFTSize(current.shape[1]) height = cv2.getOptimalDFTSize(current.shape[0]) temp_img = cv2.copyMakeBorder(current, 0, height - current.shape[0], 0, width - current.shape[1], cv2.BORDER_CONSTANT, (0, 0, 0, 0)) # do the DFT cv2.dft(temp_img, temp_img, cv2.DFT_ROWS | cv2.DFT_SCALE, temp_img.shape[0]) # construct the filter filter = np.copy(temp_img) filter = self.create_ideal_bandpass_filter(filter, self.fl, self.fh, self.rate) # apply filter temp_img = cv2.mulSpectrums(temp_img, filter, cv2.DFT_ROWS) # do the inverse DFT on filtered image cv2.idft(temp_img, temp_img, cv2.DFT_ROWS | cv2.DFT_SCALE, temp_img.shape[0]) # copy back to the current channel channels[i] = temp_img[0:current.shape[0], 0:current.shape[1]] # merge channels] dst = cv2.merge(channels) # normalize the filtered image dst = cv2.normalize(dst, None, 0, 1, cv2.NORM_MINMAX) return dst
def getRealImaginary(imagem): I = cv.imread(imagem, cv.IMREAD_GRAYSCALE) if I is None: print('Error opening image') return -1 rows, cols = I.shape m = cv.getOptimalDFTSize(rows) n = cv.getOptimalDFTSize(cols) padded = cv.copyMakeBorder(I, 0, m - rows, 0, n - cols, cv.BORDER_CONSTANT, value=[0, 0, 0]) # padded = cv.copyMakeBorder(I, 0, 4, 0, 4, cv.BORDER_CONSTANT, value=[0, 0, 0]) planes = [np.float32(padded), np.zeros(padded.shape, np.float32)] complexI = cv.merge(planes) # Add to the expanded another plane with zeros cv.dft(complexI, complexI) # this way the result may fit in the source matrix cv.split(complexI, planes) # planes[0] = Re(DFT(I), planes[1] = Im(DFT(I)) return planes
def dft(file_path): img = cv2.imread(file_path, 0) # numpy 傅里叶变换 f = np.fft.fft2(img) # f[w,h] f_shift = np.fft.fftshift(f) magnitude_spectrum = 20 * np.log(np.abs(f_shift)) # 去除低频分量建立高通滤波 row, col = img.shape rows = int(row / 2) cols = int(col / 2) f_shift[rows - 40:rows + 40, cols - 40:cols + 40] = 0 f_ishift = np.fft.ifftshift(f_shift) # 取绝对值 img_back = np.abs(np.fft.ifft2(f_ishift)) plt.subplot(121), plt.imshow(img, cmap='gray'), plt.title("input_image"), plt.xticks([]), plt.yticks([]), plt.subplot(122), plt.imshow(img_back, cmap='gray'), plt.title("Result in JET"), plt.xticks([]), plt.yticks([]) plt.show() # opencv 傅里叶变换 # 输入图像要先转为float32 opencv 得到的是双通道dft[h,w,2] dft = cv2.dft(np.float32(img), flags=cv2.DFT_COMPLEX_OUTPUT) dft_shift = np.fft.fftshift(dft) magnitude_spectrum_cv = 20 * np.log( cv2.magnitude(dft_shift[:, :, 0], dft_shift[:, :, 1])) plt.subplot(121), plt.imshow(img, cmap='gray'), plt.title("image"), plt.xticks([]), plt.yticks([]), plt.subplot(122), plt.imshow(magnitude_spectrum_cv, cmap='gray'), plt.title("Magnitude Spectrum"), plt.xticks([]), plt.yticks([]) plt.show() # 建立低通滤波掩膜 mask = np.zeros((row, col, 2), np.uint8) mask[rows - 40:rows + 40, cols - 40:cols + 40] = 1 f_shift = dft_shift * mask # 逆频移 f_ishift = np.fft.ifftshift(f_shift) # 逆变换 img_back = cv2.idft(f_ishift) img_back = cv2.magnitude(img_back[:, :, 0], img_back[:, :, 1]) plt.subplot(121), plt.imshow(img, cmap='gray'), plt.title("image"), plt.xticks([]), plt.yticks([]), plt.subplot(122), plt.imshow(img_back, cmap='gray'), plt.title("Magnitude Spectrum"), plt.xticks([]), plt.yticks([]) plt.show() # cv2.getOptimalDFTSize 进行DFT的西南性能优化 print(row, col) nrow = cv2.getOptimalDFTSize(row) ncol = cv2.getOptimalDFTSize(col) print(nrow, ncol)
def homofilter(orig_array, x_size, y_size): print orig_array.shape mask = orig_array == 255 orig_array = orig_array.astype(np.float32) / 255.0 opt_x_size = cv2.getOptimalDFTSize(x_size) opt_y_size = cv2.getOptimalDFTSize(y_size) # opt_x_size = x_size # opt_y_size = y_size if opt_x_size % 2 != 0: opt_x_size += 1 if opt_y_size % 2 != 0: opt_y_size += 1 if opt_x_size - x_size > 0: orig_array = np.hstack( (orig_array, np.ones((y_size, opt_x_size - x_size)))) if opt_y_size - y_size > 0: orig_array = np.vstack( (orig_array, np.ones((opt_y_size - y_size, opt_x_size)))) print orig_array.shape print 'log ...' log_array = np.log(orig_array + 0.0001) print log_array orig_array = None print 'dct ...' dct_array = cv2.dct(log_array) print dct_array log_array = None print 'filter ...' gammaH = 2 gammaL = 0.3 C = 1.0 d0 = float((opt_y_size / 2)**2 + (opt_x_size / 2)**2) colvec = (np.arange(opt_y_size).reshape(opt_y_size, 1))**2 rowvec = (np.arange(opt_x_size).reshape(1, opt_x_size))**2 print(colvec + rowvec) / d0 H = (gammaH - gammaL) * (1 - np.exp(-C * (colvec + rowvec) / d0)) + gammaL # H = np.ones(dct_array.shape) # H[colvec+rowvec<d0] = 0.0 print H filtered_dct_array = dct_array * H print filtered_dct_array dct_array = None print 'idct ...' idct_array = cv2.idct(filtered_dct_array) print idct_array filtered_dct_array = None print 'exp ...' exp_array = np.uint8((np.floor(np.exp(idct_array) * 255.0))) print exp_array array = np.copy(exp_array[0:y_size, 0:x_size]) print array.shape array[mask] = 255 return array
def main(argv): filename = argv[0] if len(argv) > 0 else "images/g2-200px.jpg" I = cv.imread(filename, cv.IMREAD_GRAYSCALE) if I is None: print('error opening image') return -1 rows, cols = I.shape m = cv.getOptimalDFTSize(rows) n = cv.getOptimalDFTSize(cols) padded = cv.copyMakeBorder(I, 0, m - rows, 0, n - cols, cv.BORDER_CONSTANT, value=[0, 0, 0]) planes = [np.float32(padded), np.zeros(padded.shape, np.float32)] complexI = cv.merge(planes) cv.dft(complexI, complexI) cv.split(complexI, planes) cv.magnitude(planes[0], planes[1], planes[0]) magI = planes[0] matOfOnes = np.ones(magI.shape, dtype=magI.dtype) cv.add(matOfOnes, magI, magI) cv.log(magI, magI) magI_rows, magI_cols = magI.shape magI = magI[0:(magI_rows & -2), 0:(magI_cols & -2)] cx = int(magI_rows / 2) cy = int(magI_cols / 2) q0 = magI[0:cx, 0:cy] q1 = magI[cx:cx + cx, 0:cy] q2 = magI[0:cx, cy:cy + cy] q3 = magI[cx:cx + cx, cy:cy + cy] tmp = np.copy(q0) magI[0:cx, 0:cy] = q3 magI[cx:cx + cx, cy:cy + cy] = tmp tmp = np.copy(q1) magI[cx:cx + cx, 0:cy] = q2 magI[0:cx, cy:cy + cy] = tmp cv.normalize(magI, magI, 0, 1, cv.NORM_MINMAX) cv.imshow("input image", I) print('nilai pixel gambar Grayscale :') print('') print I print('') cv.imshow("spectrum magnitude", magI) print('Nilai spectrum magnitude :') print('') print magI cv.waitKey()
def optimize_preprocess(img): #optimize picture before processing rows = img.shape[0] cols = img.shape[1] nrows = cv2.getOptimalDFTSize(rows) ncols = cv2.getOptimalDFTSize(cols) nimg = cv2.resize(img, (ncols, nrows)) return nimg
def fft2Image(src): r, c = src.shape[:2] rpadded = cv2.getOptimalDFTSize(r) cpadded = cv2.getOptimalDFTSize(c) fft2 = np.zeros((rpadded, cpadded, 2), np.float32) fft2[:r, :c, 0] = src cv2.dft(fft2, fft2, cv2.DFT_COMPLEX_OUTPUT) return fft2
def FFT(img): m = cv2.getOptimalDFTSize( img.shape[0] ); n = cv2.getOptimalDFTSize( img.shape[1] ); #on the border add zero values padded = cv2.copyMakeBorder(img, 0, m - img.shape[0], 0, n - img.shape[1], cv2.BORDER_REPLICATE); return color_img_fft(padded)
def main(): cap = cv2.VideoCapture(0) if not cap.isOpened(): print("erro ao abrir a câmera") exit(1) rows = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)) cols = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)) dft_rows = cv2.getOptimalDFTSize(rows) dft_cols = cv2.getOptimalDFTSize(cols) padded_rows = dft_rows - rows padded_cols = dft_cols - cols low_pass_filter = define_low_pass_filter(dft_rows, dft_cols, 20) key = "não" freq = 10 gain = 0 noise = False while "\x1b" != key: # esc ret, frame = cap.read() if not ret: break gray_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) padded = cv2.copyMakeBorder(gray_frame, 0, padded_rows, 0, padded_cols, cv2.BORDER_CONSTANT, value=[0, 0, 0]) planes = cv2.merge([np.float64(padded), np.zeros(padded.shape, np.float64)]) dft_image: np.ndarray = cv2.dft(planes) shifted_image = shift_dft(dft_image) filtered_image: np.ndarray = cv2.mulSpectrums(shifted_image, low_pass_filter, 0) if noise: apply_noise(filtered_image, gain, freq) dft_image = shift_dft(filtered_image) cv2.idft(dft_image, dft_image) real, imaginary = cv2.split(dft_image) cv2.normalize(real, real, alpha=0, beta=1, norm_type=cv2.NORM_MINMAX, dtype=cv2.CV_64F) key = show_images(["gray_Frame", "dft"], [gray_frame, real], 1) freq, gain, noise = options(key, freq, gain, noise, dft_rows)
def PF_2d(r, lowp, flag, d0, d1=None, n=None): """ 功能: 频率域上滤波器 输入: r: 图像 lowp: 1: 低通滤波器 0: 高通滤波器 flag: 0:理想滤波 1: 巴特沃斯滤波 2: 梯形滤波 3: 高斯滤波 d0: 低通直径 d1: 低通直径 n: 如果是巴特沃斯/指数滤波, 则是阶数【2】 输出: 滤波后的图像[uint8] """ nrows = cv.getOptimalDFTSize(r.shape[0]) ncols = cv.getOptimalDFTSize(r.shape[1]) r_bst = np.zeros((nrows, ncols)) r_bst[:rows, :cols] = r r_fs = np.fft.fftshift(np.fft.fft2(r_bst)) center = [nrows // 2, ncols // 2] H = np.zeros(r_fs.shape) for u in range(nrows): for v in range(ncols): duv = np.hypot(u - center[0], v - center[1]) if flag == 0: # 理想滤波器 H[u][v] = duv < d0 if lowp else duv > d0 elif flag == 1: # 巴特沃斯滤波器 H[u][v] = 1 / ((1 + (duv / d0)) ** (2*n)) if lowp \ else 1 / ((1 + (d0 / duv)) ** (2*n)) elif flag == 2: # 梯形滤波器 if lowp: if duv > d0: H[u][v] = 1 elif duv > d1: H[u][v] = 0 elif d0 <= duv and duv <= d1: H[u][v] = (duv - d1) / (d0 - d1) else: if duv < d0: H[u][v] = 0 elif duv > d0: H[u][v] = 1 elif d1 <= duv and duv <= d0: H[u][v] = (d0 - d1) / (duv - d1) elif flag == 3: # 高斯(指数)滤波器 if n is None: n = 2 H[u][v] = (np.e ** (-(duv**n)/(d0**n))) if lowp \ else (1-np.e ** (-(duv**n)/(d0**n))) s_ext = got_ifft_img(r_fs * H) s = s_ext[0:r.shape[0], 0:r.shape[1]] return s.astype(np.uint8)
def optimal_shape_gray(img): rows = img.shape[0] cols = img.shape[1] nrows = cv2.getOptimalDFTSize(rows) ncols = cv2.getOptimalDFTSize(cols) nimg = resize(img, (ncols, nrows)) # nimg = np.zeros([nrows, ncols]) # nimg[:rows, :cols] = img return nimg
def pad_img(img): rows, cols = img.shape nrows = cv2.getOptimalDFTSize(rows) ncols = cv2.getOptimalDFTSize(cols) right = ncols - cols bottom = nrows - rows bordertype = cv2.BORDER_CONSTANT nimg = cv2.copyMakeBorder(img, 0, bottom, 0, right, bordertype, value=0) return nimg
def extractBoundingBox(self, bounding_box): p1, p2 = bounding_box w_bb = p2[0] - p1[0] h_bb = p2[1] - p1[1] h = cv.getOptimalDFTSize(h_bb) w = cv.getOptimalDFTSize(w_bb) return p1, w, h
def blur_with_opencv(image, size=30): assert len(image.shape) == 2 # -----------------Expand the image to an optimal size with padding------------------- rows, cols = image.shape m = cv.getOptimalDFTSize(rows) n = cv.getOptimalDFTSize(cols) padded = cv.copyMakeBorder(image, 0, m - rows, 0, n - cols, cv.BORDER_CONSTANT, value=[0, 0, 0]) # -------------------------Make place for both the complex and the real values------------------ planes = [np.float32(padded), np.zeros(padded.shape, np.float32)] complex_img = cv.merge( planes) # Add to the expanded another plane with zeros # ---------------------construct mask---------------------------- center_y, center_x = int(complex_img.shape[0] / 2), int( complex_img.shape[1] / 2) mask = np.zeros_like(complex_img, dtype=np.uint8) mask[center_y - size:center_y + size, center_x - size:center_x + size, :] = 1 # -------------------------Make the Discrete Fourier Transform----------------------------------- dft_img = cv.dft( complex_img) # this way the result may fit in the source matrix # -------------------------transform the real and complex values to magnitude-------------------- # compute the magnitude and switch to logarithmic scale # = > M = sqrt(Re(DFT(I)) ^ 2 + Im(DFT(I)) ^ 2) # cv.split(complexI, planes) # planes[0] = Re(DFT(I), planes[1] = Im(DFT(I)) # cv.magnitude(planes[0], planes[1], planes[0]) # planes[0] = magnitude # image_ = planes[0] shift_img = np.fft.fftshift(dft_img) # shift_img *= mask # shift_img = cv.bitwise_and(shift_img, mask) # invert centralize ishift_img = np.fft.ifftshift(shift_img) ifft_img = cv.idft(ishift_img) blur_img, img_1 = cv.split(ifft_img) # convert scale to (0, 1) cv.normalize(blur_img, blur_img, 0, 1, cv.NORM_MINMAX) # recover origin shape blur_img = blur_img[0:rows, 0:cols] return blur_img
def preprocessForPhaseCorrelate(G_a): N1 = cv2.getOptimalDFTSize(G_a.shape[0]) N2 = cv2.getOptimalDFTSize(G_a.shape[1]) G_a_padded = cv2.copyMakeBorder( G_a, (N1 - G_a.shape[0]) / 2, (N1 - G_a.shape[0]) / 2, (N2 - G_a.shape[1]) / 2, (N2 - G_a.shape[1]) / 2, cv2.BORDER_CONSTANT, value=0, ) result = np.fft.fft2(G_a_padded) return result
def get_optimal_arraysize(img): """ Performance of DFT calculation is better for some array sizes. Fastest when array size is power of two. You can modify the size of the array to any optimal size (by padding zeros) before finding DFT. """ rows, cols = img.shape print rows, cols optimal_rows = cv2.getOptimalDFTSize(rows) optimal_cols = cv2.getOptimalDFTSize(cols) print optimal_rows, optimal_cols return optimal_rows, optimal_cols
def plot_power_spectrum(self): """Plots the power spectrum This method plots the power spectrum of the image passed to the class constructor. :returns: power spectrum """ # convert the frame to grayscale if necessary if len(self.frame_orig.shape) > 2: frame = cv2.cvtColor(self.frame_orig, cv2.COLOR_BGR2GRAY) else: frame = self.frame_orig # expand the image to an optimal size for FFT rows, cols = self.frame_orig.shape[:2] nrows = cv2.getOptimalDFTSize(rows) ncols = cv2.getOptimalDFTSize(cols) frame = cv2.copyMakeBorder(frame, 0, ncols - cols, 0, nrows - rows, cv2.BORDER_CONSTANT, value=0) # do FFT and get log-spectrum if self.use_numpy_fft: img_dft = np.fft.fft2(frame) spectrum = np.log10(np.real(np.abs(img_dft))**2) else: img_dft = cv2.dft(np.float32(frame), flags=cv2.DFT_COMPLEX_OUTPUT) spectrum = np.log10(img_dft[:, :, 0]**2+img_dft[:, :, 1]**2) # radial average L = max(frame.shape) freqs = np.fft.fftfreq(L)[:L/2] dists = np.sqrt(np.fft.fftfreq(frame.shape[0])[:, np.newaxis]**2 + np.fft.fftfreq(frame.shape[1])**2) dcount = np.histogram(dists.ravel(), bins=freqs)[0] histo, bins = np.histogram(dists.ravel(), bins=freqs, weights=spectrum.ravel()) centers = (bins[:-1] + bins[1:]) / 2 plt.plot(centers, histo/dcount) plt.xlabel('frequency') plt.ylabel('log-spectrum') plt.show()
def PlotMagnitudeSpectrum(self): # convert the frame to grayscale if necessary if len(self.frameOrig.shape)>2: frame = cv3.cvtColor(self.frameOrig, cv3.COLOR_BGR2GRAY) else: frame = self.frameOrig # expand the image to an optimal size for FFT rows,cols = self.frameOrig.shape[:2] nrows = cv3.getOptimalDFTSize(rows) ncols = cv3.getOptimalDFTSize(cols) frame = cv3.copyMakeBorder(frame, 0, ncols-cols, 0, nrows-rows, cv3.BORDER_CONSTANT, value = 0) # do FFT and get log-spectrum imgDFT = np.fft.fft2(frame) spectrum = np.log10(np.abs(np.fft.fftshift(imgDFT))) # return for plotting return 255*spectrum/np.max(spectrum)
def image_fft(img, method='cv'): irows,icols = img.shape m = cv2.getOptimalDFTSize(irows) n = cv2.getOptimalDFTSize(icols) right, bottom = n-icols, m-irows nimg = cv2.copyMakeBorder(img, 0, bottom, 0, right, cv2.BORDER_CONSTANT, value=0) # planes = [ nimg.astype('float32'), np.zeros(nimg.shape).astype('float32') ] # complexImg = cv2.merge(planes) # complexImg = cv2.dft(complexImg) complexImg = cv2.dft(nimg.astype('float32'), flags=cv2.DFT_COMPLEX_OUTPUT) if method=='cv': magImg = cv_fft_shift(complexImg) else: magImg = np_fft_shift(complexImg) # magImg = cv2.normalize(magImg, alpha=0, beta=1, norm_type=cv2.NORM_MINMAX) return magImg
def calcFourierDescr(self): opt_size = cv2.getOptimalDFTSize(len(self.contour)) #Como los arrays de numpy se almacenan en bloques contiguos de memoria # se inicializa uno con el tamanho optimo conocido donde se almacenara la dft self.dft_contour = np.zeros(shape=(opt_size, 1, 2)) for i in range(opt_size): self.dft_contour.itemset(i, self.contour.item(i%len(self.contour))) self.dft_contour = cv2.dft(self.dft_contour) self.descriptors = np.zeros(shape=(self.dft_contour.shape[0]/2, 1, 2)) for i in range(0,self.dft_contour.shape[0],2): self.descriptors.itemset(i, np.sqrt(np.power(self.dft_contour.item(i),2)+np.power(self.dft_contour.item(i+1),2))) self.descriptors /= np.amax(self.descriptors) #Se pasa de numpy.array a lista para que sea mas facil imprimir los valores self.descriptors = [x.tolist()[0][0] for x in self.descriptors] self.descriptors = self.descriptors[1:]
def calcRotAngle(srcImgOrg,srcImgGray): angleD = 0 opWidth = cv.getOptimalDFTSize(srcImgGray.shape[1]) opHeight = cv.getOptimalDFTSize(srcImgGray.shape[0]) padded = cv.copyMakeBorder(srcImgGray, 0, opWidth - srcImgGray.shape[1] , 0, opHeight - srcImgGray.shape[0], cv.BORDER_CONSTANT); plane = np.zeros(padded.shape,dtype=np.float32) planes = [padded,plane] #Merge into a double-channel image comImg = cv.merge(planes) cv.dft(comImg,comImg) cv.split(comImg, planes) planes[0] = cv.magnitude(planes[0], planes[1]); magMat = planes[0] magMat += np.ones(magMat.shape) cv.log(magMat,magMat); cx = magMat.shape[1] / 2; cy = magMat.shape[0] / 2 q0 = magMat[0:cx,0: cy ] q1 = magMat[cx:,0: cy] q2 = magMat[0:cx, cy:] q3 = magMat[cx:,cy:] c1 = np.vstack((q3,q2)) c2 = np.vstack((q1,q0)) magMat2 = np.hstack((c1,c2)) cv.normalize(magMat2, magMat, 0, 1,cv.NORM_MINMAX); magMat = cv.resize(magMat,(magMat.shape[0] / 2,magMat.shape[1]/2)) magMat = magMat * 255 magMat = cv.threshold(magMat,GRAY_THRESH,255,cv.THRESH_BINARY)[1].astype(np.uint8) lines = cv.HoughLines(magMat,1,np.pi/180, HOUGH_VOTE); #cv.imshow("mag_binary", magMat); #lineImg = np.ones(magMat.shape,dtype=np.uint8) angle = 0 if lines != None and len(lines) != 0: for line in lines[0]: #print line rho = line[0] theta = line[1] if (theta < (np.pi/4. )) or (theta > (3.*np.pi/4.0)): print 'Vertical line , rho : %f , theta : %f'%(rho,theta) pt1 = (int(rho/np.cos(theta)),0) pt2 = (int((rho-magMat.shape[0]*np.sin(theta))/np.cos(theta)),magMat.shape[0]) #cv.line( lineImg, pt1, pt2, (255)) angle = theta else: print 'Horiz line , rho : %f , theta : %f'%(rho,theta) pt1 = (0,int(rho/np.sin(theta))) pt2 = (magMat.shape[1], int((rho-magMat.shape[1]*np.cos(theta))/np.sin(theta))) #cv.line(lineImg, pt1, pt2, (255), 1) angle = theta + np.pi / 2 #cv.imshow('lineImg',lineImg) #Find the proper angel if angle > (np.pi / 2): angle = angle - np.pi #Calculate the rotation angel #The image has to be square, #so that the rotation angel can be calculate right print 'angle : %f' % angle #print srcImgOrg.shape alpha = float(srcImgOrg.shape[1]) / float(srcImgOrg.shape[0]) print 'alpha : %f' % alpha if alpha > 1: angleT = srcImgOrg.shape[1] * np.tan(angle) / srcImgOrg.shape[0]; angleD = np.arctan(angleT) * 180 / np.pi; else: angleD = angle * 180 / np.pi print 'angleD : %f' % angleD return angleD
def convolveWithDFT(a, b, verbose=False): ''' Returns a convolved with b. Uses DFT and Convolution Theorem. :type a: numpy.ndarray :type b: numpy.ndarray :rtype: numpy.ndarray ''' if verbose: pbar = progressbar.ProgressBar(widgets=[progressbar.Percentage(), progressbar.Bar()], maxval=4).start() # Based on: docs.opencv.org/modules/core/doc/operations_on_arrays.html#dft # Create result and work out correct size. a_rows, a_cols = a.shape b_rows, b_cols = b.shape result = np.empty((abs(a_rows-b_rows)+1, abs(a_cols-b_cols)+1)) # Calculate size for DFT dft_width = cv2.getOptimalDFTSize((a_cols-b_cols)+1) dft_height = cv2.getOptimalDFTSize((a_rows-b_rows)+1) # Tranform a and b to fourier domain. # Complexity: O(n**2 * log2(n) # Create temporary buffers. temp_a = np.zeros((dft_height, dft_width)) temp_b = np.zeros((dft_height, dft_width)) # Copy a and b to top left conerns of temporary buffers. temp_a[0:a_cols, 0:a_rows] = a temp_b[0:b_cols, 0:b_rows] = b # Transform padded a&b in place. # Use nonzeroRows hint for faster processing. cv2.dft(temp_a, temp_a, 0, a_rows) if verbose: pbar.update(1) cv2.dft(temp_b, temp_b, 0, b_rows) if verbose: pbar.update(2) # By convolution theorem multiplication in fourier domain is equivalent to convolution # in original domain. # Perform per element multiplication. # Complexity: O(n**2) temp_a = cv2.mulSpectrums(temp_a, temp_b, False) if verbose: pbar.update(3) # Transform result from fourier domain to original domain. # Only need first abs(image_rows-kernel_rows)+1 rows of result. # Complexity: O(n**2 * log2(n) cv2.dft(temp_a, temp_a, cv2.DFT_INVERSE + cv2.DFT_SCALE, result.shape[1]) result = temp_a[0:result.shape[0], 0:result.shape[1]] if verbose: pbar.finish() return result
return -1; Mat padded; //expand input image to optimal size int m = getOptimalDFTSize( I.rows ); int n = getOptimalDFTSize( I.cols ); // on the border add zero values copyMakeBorder(I, padded, 0, m - I.rows, 0, n - I.cols, BORDER_CONSTANT, Scalar::all(0)); ''' import cv2 import numpy as np import matplotlib.pyplot as plt # img = cv2.imread("imageTextR.png", cv2.IMREAD_GRAYSCALE) img = cv2.imread("imageTextN.png", cv2.IMREAD_GRAYSCALE) irows,icols = img.shape m = cv2.getOptimalDFTSize(irows) n = cv2.getOptimalDFTSize(icols) right, bottom = n-icols, m-irows nimg = cv2.copyMakeBorder(img, 0, bottom, 0, right, cv2.BORDER_CONSTANT, value=0) ''' Mat planes[] = {Mat_<float>(padded), Mat::zeros(padded.size(), CV_32F)}; Mat complexI; merge(planes, 2, complexI); // Add to the expanded another plane with zeros dft(complexI, complexI); // this way the result may fit in the source matrix ''' # planes = [ nimg.astype('float32'), np.zeros(nimg.shape).astype('float32') ] # complexImg = cv2.merge(planes)
def main(argv): print_help() filename = argv[0] if len(argv) > 0 else 'lena.jpg' I = cv.imread(cv.samples.findFile(filename), cv.IMREAD_GRAYSCALE) if I is None: print('Error opening image') return -1 ## [expand] rows, cols = I.shape m = cv.getOptimalDFTSize( rows ) n = cv.getOptimalDFTSize( cols ) padded = cv.copyMakeBorder(I, 0, m - rows, 0, n - cols, cv.BORDER_CONSTANT, value=[0, 0, 0]) ## [expand] ## [complex_and_real] planes = [np.float32(padded), np.zeros(padded.shape, np.float32)] complexI = cv.merge(planes) # Add to the expanded another plane with zeros ## [complex_and_real] ## [dft] cv.dft(complexI, complexI) # this way the result may fit in the source matrix ## [dft] # compute the magnitude and switch to logarithmic scale # = > log(1 + sqrt(Re(DFT(I)) ^ 2 + Im(DFT(I)) ^ 2)) ## [magnitude] cv.split(complexI, planes) # planes[0] = Re(DFT(I), planes[1] = Im(DFT(I)) cv.magnitude(planes[0], planes[1], planes[0])# planes[0] = magnitude magI = planes[0] ## [magnitude] ## [log] matOfOnes = np.ones(magI.shape, dtype=magI.dtype) cv.add(matOfOnes, magI, magI) # switch to logarithmic scale cv.log(magI, magI) ## [log] ## [crop_rearrange] magI_rows, magI_cols = magI.shape # crop the spectrum, if it has an odd number of rows or columns magI = magI[0:(magI_rows & -2), 0:(magI_cols & -2)] cx = int(magI_rows/2) cy = int(magI_cols/2) q0 = magI[0:cx, 0:cy] # Top-Left - Create a ROI per quadrant q1 = magI[cx:cx+cx, 0:cy] # Top-Right q2 = magI[0:cx, cy:cy+cy] # Bottom-Left q3 = magI[cx:cx+cx, cy:cy+cy] # Bottom-Right tmp = np.copy(q0) # swap quadrants (Top-Left with Bottom-Right) magI[0:cx, 0:cy] = q3 magI[cx:cx + cx, cy:cy + cy] = tmp tmp = np.copy(q1) # swap quadrant (Top-Right with Bottom-Left) magI[cx:cx + cx, 0:cy] = q2 magI[0:cx, cy:cy + cy] = tmp ## [crop_rearrange] ## [normalize] cv.normalize(magI, magI, 0, 1, cv.NORM_MINMAX) # Transform the matrix with float values into a ## viewable image form(float between values 0 and 1). ## [normalize] cv.imshow("Input Image" , I ) # Show the result cv.imshow("spectrum magnitude", magI) cv.waitKey()
''' Based on the following tutorial: http://docs.opencv.org/3.0-beta/doc/py_tutorials/py_imgproc/py_transforms/py_fourier_transform/py_fourier_transform.html ''' import numpy as np import cv2 from matplotlib import pyplot as plt # Load the image in gray scale img = cv2.imread('../data/messi5.jpg', 0) rows, cols = img.shape # Transform the image to improve the speed in the fourier transform calculation optimalRows = cv2.getOptimalDFTSize(rows) optimalCols = cv2.getOptimalDFTSize(cols) optimalImg = np.zeros((optimalRows, optimalCols)) optimalImg[:rows, :cols] = img crow, ccol = optimalRows / 2 , optimalCols / 2 # Calculate the discrete Fourier transform dft = cv2.dft(np.float32(optimalImg), flags=cv2.DFT_COMPLEX_OUTPUT) dftShift = np.fft.fftshift(dft) # Mask everything except the center mask = np.zeros((optimalRows, optimalCols, 2), np.uint8) mask[crow - 30:crow + 30, ccol - 30:ccol + 30] = 1 dftShift = dftShift * mask # Rescale the values for visualization purposes magnitudeSpectrum = 20 * np.log(cv2.magnitude(dftShift[:, :, 0], dftShift[:, :, 1]))
def dftSkew(im): # convert to grayscale # im = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY) h, w = im.shape[:2] realInput = im.astype(np.float64) # perform an optimally sized dft dft_M = cv2.getOptimalDFTSize(w) dft_N = cv2.getOptimalDFTSize(h) # copy A to dft_A and pad dft_A with zeros dft_A = np.zeros((dft_N, dft_M, 2), dtype=np.float64) dft_A[:h, :w, 0] = realInput # no need to pad bottom part of dft_A with zeros because of # use of nonzeroRows parameter in cv2.dft() cv2.dft(dft_A, dst=dft_A, nonzeroRows=h) cv2.imshow("win", im) # Split fourier into real and imaginary parts image_Re, image_Im = cv2.split(dft_A) # Compute the magnitude of the spectrum Mag = sqrt(Re^2 + Im^2) magnitude = cv2.sqrt(image_Re ** 2.0 + image_Im ** 2.0) # Compute log(1 + Mag) log_spectrum = cv2.log(1.0 + magnitude) # Rearrange the quadrants of Fourier image so that the origin is at # the image center shift_dft(log_spectrum, log_spectrum) # normalize and display the results as rgb cv2.normalize(log_spectrum, log_spectrum, 0.0, 1.0, cv2.NORM_MINMAX) magMat = log_spectrum * 255 magMat = np.uint8(np.around(magMat)) cv2.imwrite("dft.png", magMat) rows = h cols = w # //imwrite("imageText_mag.jpg",magImg); # //Turn into binary image (_, magImg) = cv2.threshold(magMat, 160, 255, cv2.THRESH_BINARY) cv2.imwrite("dft1.png", magImg) # //imwrite("imageText_bin.jpg",magImg); # //Find lines with Hough Transformation pi180 = np.pi / 180 linImg = np.zeros(magImg.shape) lines = cv2.HoughLines(magImg, 1, pi180, 100, 0, 0) print lines for line in lines[0]: rho = line[0] theta = line[1] a = np.cos(theta) b = np.sin(theta) x0 = a * rho y0 = b * rho pt1 = (int(x0 + 1000 * (-b)), int(y0 + 1000 * (a))) pt2 = (int(x0 - 1000 * (-b)), int(y0 - 1000 * (a))) cv2.line(linImg, pt1, pt2, (255), 1) cv2.imwrite("dlines.png", linImg) # //imwrite("imageText_line.jpg",linImg); # if(lines.size() == 3){ # cout << "found three angels:" << endl; # cout << lines[0][1]*180/CV_PI << endl << lines[1][1]*180/CV_PI << endl << lines[2][1]*180/CV_PI << endl << endl; # } # //Find the proper angel from the three found angels angel = 0 piThresh = np.pi / 90 pi2 = np.pi / 2 for line in lines[0]: theta = line[1] if abs(theta) < piThresh or abs(theta - pi2) < piThresh: continue else: angel = theta break # //Calculate the rotation angel # //The image has to be square, # //so that the rotation angel can be calculate right if angel < pi2: angel = angel else: angel = angel - np.pi if angel != pi2: angelT = rows * tan(angel) / cols angel = np.arctan(angelT) angelD = angel * 180 / np.pi # Rotate the image to recover rotMat = cv2.getRotationMatrix2D((cols / 2, rows / 2), angelD, 1.0) dstImg = cv2.warpAffine(im, rotMat, (cols, rows)) cv2.imwrite("dresult.png", dstImg)
def shc_opencv(d0,d1): ''' Read DocString for SHC ''' d0 = np.float32(d0 - d0.mean()) d1 = np.float32(d1 - d1.mean()) if d0.shape != d1.shape: raise ValueError("Input shapes do not match") if d0.ndim > 2: raise ValueError("Only 1-d or 2-d data supported") ## one dimensional case if d0.ndim == 1: ## Manually Pad Arrays for DFT Optimization rows = (d0.shape)[0] nrows = cv2.getOptimalDFTSize(rows) d0n = np.zeros((nrows)) d1n = np.zeros((nrows)) d0n[:rows] = d0 d1n[:rows] = d1 ## Fourier Phase Correlation d0_dft = cv2.dft(d0, flags = cv2.DFT_COMPLEX_OUTPUT) d1_dft = cv2.dft(d1, flags = cv2.DFT_COMPLEX_OUTPUT) d01 = cv2.mulSpectrums(d0_dft,d1_dft,flags = 0, conjB = True) id01 = cv2.idft(d01, flags = cv2.DFT_SCALE | cv2.DFT_REAL_OUTPUT) cc = np.fft.fftshift(np.abs(id01)) xmax = cc.argmax() ## Polyfit of degree 2 for three points, extremum c1 = (cc[xmax+1]-cc[xmax-1])/2. c2 = cc[xmax+1]-c1-cc[xmax] xmax = xmax - c1/c2/2. return xmax - d0.shape[0]/2 ## two dimensional case if d0.ndim == 2: ## Manually Pad Arrays for DFT Optimization rows, cols = d0.shape nrows = cv2.getOptimalDFTSize(rows) ncols = cv2.getOptimalDFTSize(cols) d0n = np.zeros((nrows,ncols)) d1n = np.zeros((nrows,ncols)) d0n[:rows,:cols] = d0 d1n[:rows,:cols] = d1 ## Fourier Phase Correlation d0_dft = cv2.dft(np.float32(d0n), flags = cv2.DFT_COMPLEX_OUTPUT) d1_dft = cv2.dft(np.float32(d1n), flags = cv2.DFT_COMPLEX_OUTPUT) d01 = cv2.mulSpectrums(d0_dft,d1_dft,flags = 0, conjB = True) id01 = cv2.idft(d01, flags = cv2.DFT_SCALE | cv2.DFT_REAL_OUTPUT) cc = np.fft.fftshift(np.abs(id01)) indices = np.where(cc == cc.max()) rmax = (indices[0])[0] cmax = (indices[1])[0] ## Interpolate to sub-pixel accuracy if (rmax*cmax >= 0) and (rmax < d0n.shape[0]) and (cmax < d0n.shape[1]): ## interpolate to sub-pixel accuracy ## we use a quadratic estimator as in Tian and Huhns (1986) pg 222 denom = 2.*(2.*cc.max() - cc[rmax+1,cmax] - cc[rmax-1, cmax]) rfra = (rmax) + (cc[rmax+1,cmax] -cc[rmax-1,cmax])/denom denom = 2.*(2.*cc.max() - cc[rmax,cmax+1] - cc[rmax, cmax-1]) cfra = (cmax) + (cc[rmax,cmax+1] -cc[rmax,cmax-1])/denom rmax = rfra cmax = cfra return np.array([rmax - d0n.shape[0]/2. , cmax - d0n.shape[1]/2.])
width, height = frame.shape[1], frame.shape[0] grid = flowUtil.getGrid(0,0, width-5, height-5, 10,10) flowComputer.setGrid(grid) #initialize flowComputer with first frame(at this point, we have only one image and no flow is computer) flowComputer.apply(frame) #initialize flow diff computer diffComputer = FlowDiffComputer(flowComputer) allBlack = np.zeros((height, width), dtype=np.uint8) #find optimal size for fourrier transform rows,cols,k = frame.shape nrows = cv2.getOptimalDFTSize(rows) ncols = cv2.getOptimalDFTSize(cols) modeDemoSpectrum = False displayResults = True writeMode = True writeDFT = True writeFlowDiff=True flowDiffWriter = object() DFTWriter = object() if writeFlowDiff: #get video writer to write flow diff output flowDiff_h, flowDiff_w = allBlack.shape
def optimalDFTImg(img): """Zero-padding sobre img para alcanzar un tamaño óptimo para FFT""" h=cv.getOptimalDFTSize(img.shape[0]) w=cv.getOptimalDFTSize(img.shape[1]) return cv.copyMakeBorder(img,0,h-img.shape[0],0,w-img.shape[1],cv.BORDER_CONSTANT)
def describe(self, image): #Convert to graysacale im = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) features = [] h, w = im.shape[:2] realInput = im.astype(np.float64) # perform an optimally sized dft dft_M = cv2.getOptimalDFTSize(w) dft_N = cv2.getOptimalDFTSize(h) # copy A to dft_A and pad dft_A with zeros dft_A = np.zeros((dft_N, dft_M, 2), dtype=np.float64) dft_A[:h, :w, 0] = realInput # no need to pad bottom part of dft_A with zeros because of # use of nonzeroRows parameter in cv2.dft() cv2.dft(dft_A, dst=dft_A, nonzeroRows=h) # Split fourier into real and imaginary parts image_Re, image_Im = cv2.split(dft_A) # Compute the magnitude of the spectrum Mag = sqrt(Re^2 + Im^2) magnitude = cv2.sqrt(image_Re**2.0 + image_Im**2.0) # Compute log(1 + Mag) log_spectrum = cv2.log(1.0 + magnitude) # Rearrange the quadrants of Fourier image so that the origin is at # the image center self.shift_dft(log_spectrum, log_spectrum) # normalize and display the results as rgb cv2.normalize(log_spectrum, log_spectrum, 0.0, 1.0, cv2.NORM_MINMAX) h, w = log_spectrum.shape[:2] #Calcula media com uma mascara de 3x3 if(self.maskSize == 3): i_h = 1 while i_h < h: i_w = 1 while i_w < w: s = log_spectrum[i_h-1, i_w-1] + log_spectrum[i_h-1, i_w] + log_spectrum[i_h-1, i_w+1] + log_spectrum[i_h, i_w-1] + log_spectrum[i_h, i_w] + log_spectrum[i_h, i_w+1] + log_spectrum[i_h+1, i_w-1] + log_spectrum[i_h+1, i_w] + log_spectrum[i_h+1, i_w+1] p = s / 9 features.append(p) i_w += 3 i_h += 3 #Calcula media com uma mascara de 5x5 elif(self.maskSize == 5): i_h = 2 while i_h < h: i_w = 2 while i_w < w: s = log_spectrum[i_h-2, i_w-2] + log_spectrum[i_h-2, i_w-1] + log_spectrum[i_h-2, i_w+1] + log_spectrum[i_h-2, i_w] + log_spectrum[i_h-2, i_w+1] + log_spectrum[i_h-2, i_w+2] s += log_spectrum[i_h-1, i_w-2] + log_spectrum[i_h-1, i_w-1] + log_spectrum[i_h-1, i_w+1] + log_spectrum[i_h-1, i_w] + log_spectrum[i_h-1, i_w+1] + log_spectrum[i_h-1, i_w+2] s += log_spectrum[i_h, i_w-2] + log_spectrum[i_h, i_w-1] + log_spectrum[i_h, i_w+1] + log_spectrum[i_h, i_w] + log_spectrum[i_h, i_w+1] + log_spectrum[i_h, i_w+2] s += log_spectrum[i_h+1, i_w-2] + log_spectrum[i_h+1, i_w-1] + log_spectrum[i_h+1, i_w+1] + log_spectrum[i_h+1, i_w] + log_spectrum[i_h+1, i_w+1] + log_spectrum[i_h+1, i_w+2] s += log_spectrum[i_h+2, i_w-2] + log_spectrum[i_h+2, i_w-1] + log_spectrum[i_h+2, i_w+1] + log_spectrum[i_h+2, i_w] + log_spectrum[i_h+2, i_w+1] + log_spectrum[i_h+2, i_w+2] p = s / 25 features.append(p) i_w += 5 i_h += 5 #Calcula media com uma mascara de 7x7 elif(self.maskSize == 7): i_h = 3 while i_h < h - 7: i_w = 3 while i_w < w - 7: s = log_spectrum[i_h-3, i_w-3] + log_spectrum[i_h-3, i_w-2] + log_spectrum[i_h-3, i_w-1] + log_spectrum[i_h-3, i_w] + log_spectrum[i_h-3, i_w+1] + log_spectrum[i_h-3, i_w+2] + log_spectrum[i_h-3, i_w+3] s += log_spectrum[i_h-2, i_w-3] + log_spectrum[i_h-2, i_w-2] + log_spectrum[i_h-2, i_w-1] + log_spectrum[i_h-2, i_w] + log_spectrum[i_h-2, i_w+1] + log_spectrum[i_h-2, i_w+2] + log_spectrum[i_h-2, i_w+3] s += log_spectrum[i_h-1, i_w-3] + log_spectrum[i_h-1, i_w-2] + log_spectrum[i_h-1, i_w-1] + log_spectrum[i_h-1, i_w] + log_spectrum[i_h-1, i_w+1] + log_spectrum[i_h-1, i_w+2] + log_spectrum[i_h-1, i_w+3] s += log_spectrum[i_h, i_w-3] + log_spectrum[i_h, i_w-2] + log_spectrum[i_h, i_w-1] + log_spectrum[i_h, i_w] + log_spectrum[i_h, i_w+1] + log_spectrum[i_h, i_w+2] + log_spectrum[i_h, i_w+3] s += log_spectrum[i_h+1, i_w-3] + log_spectrum[i_h+1, i_w-2] + log_spectrum[i_h+1, i_w-1] + log_spectrum[i_h+1, i_w] + log_spectrum[i_h+1, i_w+1] + log_spectrum[i_h+1, i_w+2] + log_spectrum[i_h+1, i_w+3] s += log_spectrum[i_h+2, i_w-3] + log_spectrum[i_h+2, i_w-2] + log_spectrum[i_h+2, i_w-1] + log_spectrum[i_h+2, i_w] + log_spectrum[i_h+2, i_w+1] + log_spectrum[i_h+2, i_w+2] + log_spectrum[i_h+2, i_w+3] s += log_spectrum[i_h+3, i_w-3] + log_spectrum[i_h+3, i_w-2] + log_spectrum[i_h+3, i_w-1] + log_spectrum[i_h+3, i_w] + log_spectrum[i_h+3, i_w+1] + log_spectrum[i_h+3, i_w+2] + log_spectrum[i_h+3, i_w+3] p = s / 49 features.append(p) i_w += 7 i_h += 7 return features
if __name__ == "__main__": if len(sys.argv)>1: im = cv2.imread(sys.argv[1]) else : im = cv2.imread('../data/baboon.jpg') print "usage : python dft.py <image_file>" # convert to grayscale im = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY) h, w = im.shape[:2] realInput = im.astype(np.float64) # perform an optimally sized dft dft_M = cv2.getOptimalDFTSize(w) dft_N = cv2.getOptimalDFTSize(h) # copy A to dft_A and pad dft_A with zeros dft_A = np.zeros((dft_N, dft_M, 2), dtype=np.float64) dft_A[:h, :w, 0] = realInput # no need to pad bottom part of dft_A with zeros because of # use of nonzeroRows parameter in cv2.dft() cv2.dft(dft_A, dst=dft_A, nonzeroRows=h) cv2.imshow("win", im) # Split fourier into real and imaginary parts image_Re, image_Im = cv2.split(dft_A)
def _optimize_shape(self, img): rows, cols = img.shape nrows = cv2.getOptimalDFTSize(rows) ncols = cv2.getOptimalDFTSize(cols) img = cv2.copyMakeBorder(img, 0, nrows-rows, 0, ncols-cols, cv2.BORDER_CONSTANT, value = 0) return img