如图二所示(图像也可以自主选择),(1)把该图像按行像素依次贯序转换为一维波形(灰度为波形的幅度,像素先后为时间序列),分析其频谱;(2)把该图像按列像素依次贯序转换为一维波形(灰度为波形的幅度,像素先后为时间序列),分析其频谱;(3)按奈奎斯特采样定理,讨论其采样频率;(4)按该采样频率进行采样,并通过线性插值滤波进行验证(图像相似度)其正确性。
薛定谔的照片
图像预处理
处理三个通道的数据比较复杂,先将图像进行灰度化处理,灰度化的过程就是将每个像素点的RGB值统一成同一个值。灰度化后的图像将由三通道变为单通道,单通道的数据处理起来就会简单许多。
import matplotlib.pyplot as plt
import numpy as np
import cv2
if __name__ == '__main__':
bb=[]
aa=[]
hang=[]
lie=[]
img = plt.imread('D:\\11.jpg')
# 显示图片
plt.imshow(img) # 准备显示图片
width = img.shape[1]
height = img.shape[0]
print('大小:{}'.format(img.shape))
plt.show()
# 从彩色图像中去除噪声
#dst = cv2.fastNlMeansDenoisingColored(img, 10, 10, 7, 21)
# 灰度化图像
img1 = img.mean(axis=-1) # axis=-1表示最后一个轴,在最后一个轴取均值即灰度化
plt.imshow(img1, cmap='gray')
plt.axis('on')
plt.show()
img2 = (np.array(img1))#.round()
图像大小为(431, 592, 3),即宽593,高431,通道大小3,处理后的结果图如下所示:
薛定谔的照片
行/列像素值分析
计算每一行和每一列的像素与幅值关系,用方差找出变化最剧烈的一行/列的索引值,代码如下,经运行可知,行索引为175,列索引为7。
#找出变化最剧烈的某一行或者某一列
hang.append(np.std(img2,axis=1))#求出矩阵每一行的方差
hang=np.array(hang)
print(f"最大方差值:{np.max(hang)},行索引:{hang.argmax()}")
lie.append(np.std(img2,axis=0))#求出矩阵每一列的方差
lie = np.array(lie)
print(f"最大方差值:{np.max(lie)}, 列索引:{lie.argmax()}")
for i in range(width):
aa.append(i)
plt.plot( aa, img2[175], color='red', linewidth=1 ) # 利用得到的行像素值画图
plt.show()
for j in range(height):
bb.append(j)
plt.plot( bb, img2[:,7], color='red', linewidth=1 ) # 利用得到的列像素值画图
plt.show()
运行结果:
(1)行像素频谱分析
把该图像变化最剧烈的一行像素,以灰度为波形的幅度,像素先后为时间序列的方式转换为一维波形。由波形图可知,此行像素的灰度值变化范围较大,在像素值(0,150)之间灰度值变化明显,来回抖动;在像素(150,350),(400,550)之间灰度值较为平稳,但是像素在(550,592),(350,400)之间灰度值变化剧烈,范围从25到255之间。
薛定谔的照片
(2)列像素频谱分析
把该图像变化最剧烈的一列像素,以灰度为波形的幅度,像素先后为时间序列的方式转换为一维波形。由波形图可知,此列像素的灰度值变化范围较大,在像素(0,150)之间灰度值较为平稳,但是从(150,200)之间变化剧烈,出现了剧烈的抖动,像素值在(200,400)之间变化较为平缓,像素值在(400,431)之间有出现了剧烈的变化。
薛定谔的照片
对图像向下取样,它将对图像进⾏⾼斯核卷积,并删除原图中所有的偶数⾏和列,最终缩⼩图像。其中,⾼斯核卷积运算就是对整幅图像进⾏加权平均的过程,每⼀个像素点的值,都由其本⾝和邻域内的其他像素值经过加权平均后得到。
import cv2
import matplotlib.pyplot as plt
#重新读取原始图像
img = cv2.imread('D:\\4321.jpg')
src = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
#图像向下取样
r = cv2.pyrDown(src)
#显示图像
titles = ['src', 'pyrDown']
images = [src, r]
plt.figure(figsize=(10, 4))
for i in range(2):
plt.subplot(1, 2, i+1)
plt.imshow(images[i], 'gray')
plt.title(titles[i])
# plt.xticks([]), plt.yticks([])
plt.show()
(3)奈奎斯特采样定理
图像采样处理指的是从连续的模拟图像中提取离散像素点的过程。将一幅连续图像在空间上分割成M×N的网格,每个网格用一个亮度值或灰度值来表示,将空间中连续的图像变换成离散点的操作成为采样。若横向的像素数(列数)为M ,纵向的像素数(行数)为N,则图像总像素数为M*N个像素。图像采样就是对原始图像信号的一种数字化逼近。
奈奎斯特采样定律:采样频率fs必须大于原始信号中最高频率的2倍时(fs>2fmax),采样之后的数字信号完整地保留了原始信号中的信息,才能完整地还原原始信号,不发生混叠现象。
以上图中不规则的复杂波形图为例,任何复合狄利克雷条件的周期函数都能够被分解为无穷多个简单的正弦函数。因此可将其转换为多个简单波形的组合,可以理解为上述单行像素的波形图可以被转换为多个基础波形的组合,然后再由离散余弦变换公式计算出各个基础波形的系数,也就是函数在频域的取值。最后找到原始信号中频率最高的信号。
图像采样的间隔越大,所得图像像素数越少,空间分辨率越低,图像质量越差,甚至出现马赛克效应;相反,图像采样的间隔越小,所得图像像素数越多,空间分辨率越高,图像质量越好,但数据量会相应的增大。根据奈奎斯特采样定理,只要采样频率⼤于被采样信号最⾼频率的2倍,就可以由采样信号对原始信号进⾏完整恢复。
在采样的过程中,使用的采样率过低会导致图片丢失大量的细节。其大小和原图一致时将会看到大量如马赛克效果一样的色斑,如下图(采样比率20)。
薛定谔的照片
向下取样使用的函数为pyrDown(),它将原始图像压缩成原图的四分之一。可多次向下取样,每次向下取样均为上次的四分之一,并且图像的清晰度会降低。薛定谔的照片
(4)线性插值
线性插值方法的基本原理是根据导频位置将基系数向量分隔成各个小段,在每个小段内利用导频位置的数据通过一次函数拟合进行插值,从而得到导频位置之间的数值。线性插值可以用来为利用过点的直线来近似原函数,也可以用来计算得到查表过程中表中没有的数值。对于数据(x0, y0)与(x1, y1),要计算[x0, x1]区间内某一位置x在直线上的y值。公式为:
线性插值方法复杂度较低,在算法性能方面的表现一般,由于其低通滤波的特性,插值得到的数值的高频成分被滤除,降低了插值得到的基系数的数值精度。
import cv2
def resize_demo(src, new_size):
dst_h, dst_w = new_size # 目标图像宽高
# 遍历目标图像
dst = np.zeros((dst_h, dst_w, 3), dtype=np.uint8)
for dst_y in range(dst_h):# 对width 循环
for dst_x in range(dst_w): # 目标在源上的坐标
src_x = dst_x
src_y = dst_y
# 计算在源图上 4 个近邻点的位置
i = int(np.floor(src_x))
j = int(np.floor(src_y))
u = src_x-i
v = src_y-j
if j == dst_h-1:
j = dst_h-2
if i == dst_w -1:
i = dst_w -2
dst[dst_y, dst_x] = (1-u)*(1-v)*src[j, i]+u*(1-v) * \
src[j+1, i] + (1-u)*v*src[j, i+1]+u*v*src[j+1, i+1]
return dst
if __name__ == '__main__':
src = cv2.imread('D:\\4321.jpg')
dst = resize_demo(src, (431, 592))
cv2.imshow("orignal image", src)
cv2.imshow("interpolated image", dst)
cv2.waitKey()
线性插值可以扩展到有两个变量的函数的双线性插值,核心思想是在两个方向分别进行一次线性插值,并且选择x方向和y方向进行插值的先后顺序没有唯一标准。如下图所示:左边是原始图像,右边是经过线性插值后的图像。
薛定谔的照片