赞
踩
图像中的低频信号和高频信号,也叫做低频分量和高频分量。
低频分量对应图像中物体的亮度均匀或变化缓慢的区域;
高频分量对应图像中物体的边缘、细节、噪声。
图像的频率:该图像灰度值变化剧烈程度的指标,是灰度在平面空间上的梯度。
图像信号中的低频分量,指的是图像强度(亮度、灰度)变换平缓的地方。也就是大片色块,变化不那么明显的地方。
低频就是颜色缓慢地变化,也就是灰度缓慢地变化,就代表着那是连续渐变的一块区域,这部分就是低频。对于一幅图像来说,除去高频的就是低频了,也就是边缘以内的内容为低频,而边缘内的内容就是图像的大部分信息,即图像的大致概貌和轮廓,是图像的近似信息。
图像信号中的高频分量,指的就是图像信号强度(亮度/灰度)变化剧烈的地方,也就是我们常说的边缘(轮廓)。
高频就是频率变化快。图像中什么时候灰度变化快?就是相邻区域之间灰度相差很大,这就是变化得快。图像中,一个影像与背景的边缘部位,通常会有明显的差别,也就是说变化那条边线那里,灰度变化很快,也即是变化频率高的部位。因此,图像边缘的灰度值变化快,就对应着频率高,即高频显示图像边缘。图像的细节处也是属于灰度值急剧变化的区域,正是因为灰度值的急剧变化,才会出现细节。
另外噪声(即噪点)也是这样,在一个像素所在的位置,之所以是噪点,就是因为它与正常的点颜色不一样了,也就是说该像素点灰度值明显不一样了,也就是灰度有快速地变化了,所以是高频部分,因此有噪声在高频这么一说。
1、在一张白纸上有一行字,那么我们肯定直接聚焦在文字上,而不会太在意白纸本身,这里文字就是高频信号,而白纸就是低频信号。
2、为什么图像的频率是表征图像中灰度变化剧烈程度的指标。大面积的沙漠在图像中是一片灰度变化缓慢的区域,对应的频率值很低,属于低频;而对于地表属性变换剧烈的边缘区域在图像中是一片灰度变化剧烈的区域,对应的频率值较高,属于高频。
3、低频保留了光影与颜色,高频保留了纹理与质感。
4、穿条纹衬衫的人
在上图中,围巾和条纹衬衫为该图像高频的区域,这部分从一种亮度到另一种亮度变化非常迅速。在同一张图像的较高位置,我们看到天空和背景的部分变化非常缓慢,是图像的低频部分。
空域是指图像平面本身,空域滤波这类方法直接对图像的像素进行处理。频域滤波是变换域滤波的一种,它是指将图像进行变换后(频域是指经过傅里叶变换之后),在变换域中对图像的变换系数进行处理(滤波),处理完毕后再进行逆变换,获得滤波后的图像。
如何将图像从空域切换到频域?使用傅里叶变换。
图像的空间域,就是二维平面坐标系,它有两个正交的轴即x,y轴。 某点在空间域上的幅值就是该点处的灰度。 图像上某点处的灰度是该点在x,y方向上灰度的叠加。 这样,分别以x,y为横坐标,灰度值为纵坐标,得到两个函数。表示图像在x,y方向上的灰度值变化情况。
傅里叶级数。根据傅里叶级数的知识,函数可以写成多个不同振幅及频率的正弦函数的和。因此,通过傅里叶变换,灰度-x函数就变换为振幅-u函数,灰度-y函数就换为振幅-v函数。建立以u,v为正交轴的平面坐标系,这样就得到了频率图。
由于二维DFT通常为复函数,因此可以用极坐标形式表示:
Answer1:
Answer2:如何理解图像的频率域处理? - 知乎 (zhihu.com)
经过低通滤波器处理。保留低频信息,去除高频信息。图像细节部分丢失,图像变模糊。
经过高通滤波器处理,也就是去除频率域中的低频信息,只保存高频信息后的结果。图像只保留了细节部分。
图像傅里叶变换原理 python实现 - 我坚信阳光灿烂 - 博客园
推荐 数字图像处理 - 标签 - 我坚信阳光灿烂 - 博客园 (cnblogs.com)
在数字图像处理中,有两个经典的变换被广泛使用——傅里叶变换和霍夫变换。傅里叶变换是将时间域上的信号转变为频率域上的信号,进而进行图像去噪、图像增强等处理。
傅里叶变换(Fourier Transform,FT)后,对同一事物的观看角度随之改变,可以从频域里发现一些从时域里不易察觉的特征。某些在时域内不好处理的地方,在频域内可以容易地处理。
傅里叶定理:“ 任何连续周期信号都可以表示成(或者无限逼近)一系列正弦信号的叠加。”
python里有两种常见方法:numpy 和 OpenCV。
Python Numpy np.fft2()方法|极客教程 (geek-docs.com)
numpy.fft.fft(a, n=None, axis=-1, norm=None)
numpy.fft.fft - 计算一维离散傅里叶变换。 (runebook.dev)
功能:计算一维傅里叶变换。使用高效的快速傅立叶变换(FFT)算法[CT] 计算一维n点离散傅立叶变换(DFT)。
numpy.fft.fft2(a, n=None, axis=-1, norm=None)
numpy.fft.fft2 - 计算二维离散傅立叶变换。 (runebook.dev)
功能:计算二维的傅里叶变换。此函数通过快速傅立叶变换(FFT)计算M维数组中任何轴上的n维离散傅立叶变换。默认情况下,转换是在输入数组的最后两个轴上进行的,即二维FFT。
numpy.fft.fftn()
numpy.fft.fftn - 计算N维离散傅立叶变换。 (runebook.dev)
功能:计算n维的傅里叶变换。通过快速傅立叶变换(FFT)计算M维数组中任意数量轴上的N维离散傅立叶变换。
numpy.fft.fftfreq()
numpy.fft.rfftfreq - 返回离散傅里叶变换的采样频率(与rfft、irfft一起使用)。 (runebook.dev)
功能:返回离散傅里叶变换的采样频率(与rfft、irfft一起使用)。返回的浮点数组 f
包含频率单元中心,该频率单元中心以每单位采样间隔的周期为周期(开始时为零)。例如,如果样本间隔为秒,则频率单位为循环/秒。
numpy.fft.shift()
numpy.fft.fftshift - 将零频分量移到光谱中心。 (runebook.dev)
功能:将FFT输出中的直流分量移动到频谱中央。列出的所有轴交换半角空格(默认为全部)。
20*np.log(np.abs(fshift))
功能:傅里叶变换得到的结果是一个复数数组,不能直接用于显示图像,要想得到频谱灰度图像,我们需要一个映射,把复数映射[0, 255]之间。
np.abs(i_img)
功能:设置值范围,实现傅里叶逆变换
cv2.dft()
功能:实现傅里叶变换
cv2.magnitude(参数1,参数2)
这个函数的作用与numpy数组:np.abs(fshift)是一回事,np.abs(fshift)是求复数数组fshift中每个复数的大小(注:fshift是一个一维的复数数组),而cv2.dft()返回的是一个二维数组(一维是复数的实部,一个是复数的虚部).
cv2.idft(ishift)
功能:实现傅里叶逆变换。
图像的低频部分可以理解为“轮廓”,比如人脸的脸型。
图像的高频部分可以理解为“细节”,比如人脸的皱纹、斑点等。
因此,对图像做模糊处理后得到了图像的低频部分,对图像做锐化处理会让图像的高频信息更多。
当我们放大混合图像时,可以清楚地看到高频信息,于是人眼更倾向于识别这部分的信息。相反地,当我们缩小图片时,高频信息就不那么容易被观察到了,这时候我们我们就更倾向于识别低频的部分。
这里有一张哈利波特和伏地魔的混叠图像。可以看到,当图像放大时我们看到的是哈利波特,而当图片缩小时,我们会认为这张图片是描述伏地魔的。
实现的总体思路很简单——将只有低频信息的图片和只有高频信息的图像叠加在一起。具体步骤如下:
实现代码:GitHub - MinisculeDust/Hybrid-Image
- import numpy as np
- from MyConvolution import convolve
- # version 3.3 2019.11.7-18:57
- # https://github.com/MinisculeDust/Hybrid-Image/blob/master/MyHybridImages.py
-
-
- def makeGaussianKernel(sigma):
-
- # set the sacle of templet
- size = (int)(8 * sigma + 1) # (this implies the window is + / - 4 sigmas from the centre of the Gaussian)
- if (size % 2 == 0):
- size += 1 # size must be odd
-
- # templet's centre position
- center = (size - 1) / 2
-
- # state kernel
- kernel = np.zeros((size, size))
-
- kernel_sum = 0
- # gaussian calculating
- for i in range(size):
- x2 = pow(i - center, 2)
- for j in range(size):
- y2 = pow(j - center, 2)
- g = np.exp(-(x2 + y2)/(2 * sigma * sigma)) / (2 * np.pi * sigma * sigma)
- kernel[i][j] = g
- kernel_sum += kernel[i][j]
-
- # normalisation
- # kernel_sum2 = 0
- # for i in range(size):
- # for j in range(size):
- # kernel[i][j] = kernel[i][j] / kernel_sum
- # kernel_sum2 += kernel[i][j]
-
- return kernel
-
- def myHybridImages(lowImage: np.ndarray, lowSigma, highImage: np.ndarray, highSigma):
-
- # make kernel
- low_kernel = makeGaussianKernel(lowSigma)
- high_kernel = makeGaussianKernel(highSigma)
-
- # convolve low-pass pictures
- low_image = convolve(lowImage, low_kernel)
-
- # make high-pass picture
- high_image = (highImage - convolve(highImage, high_kernel))
-
- # final picture
- # the weights between and final lighting can be changed flexibly
- weight = 1
- weight2 = 1
- adjustment = 0
- hybrid_image = high_image * weight2 + low_image * weight + adjustment
- # hybrid_image = high_image + low_image
-
- # randomly double check the output
- # print(hybrid_image[11][22][1])
- # print(hybrid_image[44][55][0])
- # print(hybrid_image[357][159][2])
-
- return hybrid_image
- import numpy as np
- # version 3.4 2019.11.8-9:37
- # https://github.com/MinisculeDust/Hybrid-Image/blob/master/MyConvolution.py
-
- def calculate_convolution(image, kernel):
-
- # rotating kernel with 180 degrees
- kernel = np.rot90(kernel, 2)
-
- kernel_heigh = int(np.array(kernel).shape[0])
- kernel_width = int(np.array(kernel).shape[1])
-
- # set kernel matrix to random int matrix
- if ((kernel_heigh % 2 != 0) & (kernel_width % 2 != 0)): # make sure that the scale of kernel is odd
- # the scale of result
- conv_heigh = image.shape[0] - kernel.shape[0] + 1
- conv_width = image.shape[1] - kernel.shape[1] + 1
- conv = np.zeros((conv_heigh, conv_width))
-
- # convolve
- for i in range(int(conv_heigh)):
- for j in range(int(conv_width )):
- result = (image[i:i + kernel_heigh, j:j + kernel_width] * kernel).sum()
- # if(result<0):
- # resutl = 0
- # elif(result>255):
- # result = 255
- conv[i][j] = result
- return conv
-
- def convolve(image: np.ndarray, kernel: np.ndarray) -> np.ndarray:
-
- # zero padding
- kernel_half_row = int((kernel.shape[0]-1)/2)
- kernel_half_col = int((kernel.shape[1]-1)/2)
-
- # judge how many channels
- if len(image.shape) == 3:
- image = np.pad(image, ((kernel_half_row, kernel_half_row), (kernel_half_col, kernel_half_col),(0, 0)), 'constant', constant_values=0)
-
- # if image.shape[2] == 3 or image.shape[2] == 4:
- # if style is png, there will be four channels, but we just need to use the first three
- # if the style is bmp or jpg, there will be three channels
- image_r = image[:, :, 0]
- image_g = image[:, :, 1]
- image_b = image[:, :, 2]
- result_r = calculate_convolution(image_r, kernel)
- result_g = calculate_convolution(image_g, kernel)
- result_b = calculate_convolution(image_b, kernel)
- result_picture = np.dstack([result_r, result_g, result_b])
- # if the picture is black and white
- elif len(image.shape) == 2:
- image = np.pad(image, ((kernel_half_row, kernel_half_row), (kernel_half_col, kernel_half_col)), 'constant', constant_values=0)
- result_picture = calculate_convolution(image, kernel)
-
- # returns the convolved image (of the same shape as the input image)
- return result_picture
-
-
- def fourier_trans(image: np.ndarray, kernel: np.ndarray):
- # make the scale of the kernel as the same as pictures
- # make sure it can work for different sance of pictures
- if (image.shape[0] - kernel.shape[0]) % 2 == 0:
- pad_heigh = np.int(((image.shape[0] - kernel.shape[0])) / 2)
- else:
- pad_heigh = np.int(((image.shape[0] - kernel.shape[0])) / 2) + 1
-
- if (image.shape[1] - kernel.shape[1]) % 2 == 0:
- pad_width = np.int(((image.shape[1] - kernel.shape[1])) / 2)
- else:
- pad_width = np.int(((image.shape[1] - kernel.shape[1])) / 2) + 1
- pad_heigh_light = np.int(((image.shape[0] - kernel.shape[0])) / 2)
- pad_width_light = np.int(((image.shape[1] - kernel.shape[1])) / 2)
- kernel = np.pad(kernel, ((pad_heigh_light, pad_heigh), (pad_width_light, pad_width)), 'constant', constant_values=0)
- print("kernel.shape", kernel.shape)
- copy_fft2_image = np.zeros(image.shape)
-
- # fourier transform for kernel
- # shift the centre of kernel to axis origin and then do fourier transform
- fft2_kenel_after = np.fft.fft2(np.fft.fftshift(kernel))
-
- if len(image.shape) == 3:
- # fourier transform
- for i in range(image.shape[2]):
- image_fft = np.fft.fft2(image[:, :, i])
- # print("fft2_kenel_after * image_fft.shape ==== ", (fft2_kenel_after * image_fft).shape)
- # image_fft = np.fft.fftshift(np.fft.fft2(image[:, :, i]))
- # copy_fft2_image[:, :, i] = np.fft.ifftshift(np.fft.ifft2(fft2_kenel_after * image_fft))
- frequcy_result = fft2_kenel_after * image_fft
- # copy_fft2_image[:, :, i] = np.fft.fftshift(np.fft.ifft2(frequcy_result))
- copy_fft2_image[:, :, i] = np.fft.ifft2(frequcy_result)
- elif len(image.shape) == 2:
- image_fft = np.fft.fft2(image)
- frequcy_result = fft2_kenel_after * image_fft
- copy_fft2_image[:, :] = np.fft.ifft2(frequcy_result)
-
- return copy_fft2_image
一文读懂图像信号中的高频和低频_流年若逝的博客-CSDN博客_信号的高频分量与低频分量
图像高频和低频_cys119的博客-CSDN博客_图像中的低频信号和高频信号
图像的高频信息和低频信息的含义_马鹏森的博客-CSDN博客_图像高频和低频对应图像的什么信息
图像中的高低频信息简单理解 - 知乎 (zhihu.com)
计算机视觉之混合图像(Hybrid) - 知乎 (zhihu.com)
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。