基于python-tensorflow的机器视觉学习手札 (1.4)图像处理篇-图像的空域、频域增强

接着上一篇没总结完的继续。
由于回学校了,会把一部分时间投入到科研以及找工作中去(其实找工作也是写博客的初衷之一),尽量保持更新速度,怎么也要一周两三更吧。。
系统的提一嘴,1.n将是图像处理部分,用matlab和python的opencv(有时可能用到numpy和matplotlib等包)接口实现各种基础的功能,最后可能会总结到一些简单的非cnn实现一些人脸区域识别、模式识别的领域里;(大体按照matlab图像处理实例详解的顺序来)2.n可能是python的使用部分,由于我是跟着廖雪峰老师的教程来的,所以顺序可能是和廖老师的一样,然后带一些numpy等常用包的使用方法作为番外;3.n是tensorflow部分,我学的也不是很好,前面先跟着极客学院的中文手册来,后面可能会结合外文文献做一些翻译和复现。
由于我是半路出家,所以对这些东西的理解不够专业和详尽,可能还会有很多错误,请各位指出并海涵,也可以和我交流讨论!qq:1157274846,欢迎大家找我交流!
废话说完了,开始总结:

1.图像的空域增强

其实前面很多东西都是空域增强,比如直方图均衡化啊、用numpy增强对比度啊,等等。不过最重要的部分还是以卷积为原理的,前面稍微提到过一点的(在邻域操作部分)。
不同的邻域操作,也就是空间域的卷积操作,可以在空域实现不同的图像增强效果,而每一种方法的不同之处只是卷积核的不同(算子 或者卷积矩阵,怎么叫都没关系)。
比如,卷积核为np.array[0,1,0],[1,1,1],[0,1,0],叫做线性平均滤波。(实际上是求目标点的4邻域和本身的平均值作为新图像中该点的值)这是一种最常用的线性空域滤波,主要作用是模糊图像,实质上是一种低通滤波器,会挡掉图像高频的部分,而高频的部分主要是图像的边缘,所以会产生模糊。为什么说模糊图像也是图像增强呢?因为这种方法是去噪声的方法之一,且对数量较少的随机椒盐噪声效果较好。
同样的,也可以把卷积核大小设定为5*5、7*7、或是卷积核变为ones(全为1的矩阵)、高斯分布等,都是平均(低通)滤波,也叫平滑滤波。
python中常用的平滑滤波分别有:

blur—图像均值平滑滤波
blur(src, ksize, dst=None, anchor=None, borderType=None)
  src:图像矩阵
  ksize:滤波窗口尺寸
GaussianBlur—图像高斯平滑滤波
GaussianBlur(src, ksize, sigmaX, dst=None, sigmaY=None, borderType=None)
  src:图像矩阵
  ksize:滤波窗口尺寸
  sigmaX:标准差
medianBlur—图像中值滤波
medianBlur(src, ksize, dst=None)
  src:图像矩阵
  ksize:滤波窗口尺寸
bilateralFilter—图像双边滤波
bilateralFilter(src, d, sigmaColor, sigmaSpace, dst=None, borderType=None)
  src:图像矩阵
  d:邻域直径
  sigmaColor:颜色标准差
  sigmaSpace:空间标准差

这几种是初级的平滑滤波函数,其实平滑滤波在matlab中还有一些其他的方式,比如维纳滤波(自适应滤波)wiener2,在python的opencv库里可能没有直接的语句用。(不过可以抄)
除了平滑滤波,图像增强也少不了锐化,锐化时我们通常用的是拉普拉斯算子:
np.array([[0,-1,0],[-1,4,-1],[0,-1,0]])
不过这种算子由于是0和的(4-1-1-1=0),所以锐化时是用卷积得到的结果乘一个系数加在原图像上。高通滤波在图像增强上用的不多,几乎就锐化一个作用,高通滤波主要的作用是在边缘检测上(不过边缘检测在python中有其他的方法)。

2.图像的频域增强

这里主要是说各种频域上的变换,也就是我们所说的高通/低通/带阻/带通滤波器。
在进行频域增强之前,我们首先要先对图像进行傅里叶变换,这里采用numpy的函数:

f = np.fft.fft2(img)#傅里叶变换
f_shift = np.fft.fftshift(f)#第一部得到的低频部分在左下角,为了使用滤波器更方便,
#我们把低频部分移到中心

其实还是很简单的!
然后就是自己做掩膜和f_shift相乘,也就是把自己想要滤除的部分(掩膜上为0)滤掉!被设为0的部分为就是截止。
这种方法成为理想滤波器,这种方法得到的图像容易有振铃现象(图像上有像是音叉振动的波动)。为了去除这种振铃现象,我们又提出了新的滤波器,即巴特沃斯滤波器和高斯滤波器。这些opencv里好像没有,我们可以用numpy做(代码来源:https://blog.csdn.net/skyecs/article/details/79105514):

def lpfilter(flag, rows, cols, d0, n):
    '''低通滤波器
    @param flag: 滤波器类型
    0 - 理想低通滤波
    1 - 巴特沃兹低通滤波
    2 - 高斯低通滤波
    @param rows: 被滤波的矩阵高度
    @param cols: 被滤波的矩阵宽度
    @param d0: 滤波器大小 D0
    @param n: 巴特沃兹低通滤波的阶数 
    @return 滤波器矩阵 
    '''
    assert d0 > 0, 'd0 should be more than 0.'
    filter_mat = None
    # 理想低通滤波
    if flag == 0:
        filter_mat = np.zeros((rows, cols, 2), np.float32)
        cv2.circle(filter_mat, (rows // 2, cols // 2),
                   d0, (1, 1, 1), thickness=-1)
    # 巴特沃兹低通滤波
    elif flag == 1:
        duv = fft_distances(*fft_mat.shape[:2])
        filter_mat = 1 // (1 + np.power(duv // d0, 2 * n))
        # fft_mat有2个通道,实部和虚部
        # fliter_mat 也需要2个通道
        filter_mat = cv2.merge((filter_mat, filter_mat))
    # 高斯低通滤波
    else:
        duv = fft_distances(*fft_mat.shape[:2])
        filter_mat = np.exp(-(duv * duv) // (2 * d0 * d0))
        # fft_mat有2个通道,实部和虚部
        # fliter_mat 也需要2个通道
        filter_mat = cv2.merge((filter_mat, filter_mat))
    return filter_mat


def hpfilter(flag, rows, cols, d0, n):
    '''高通滤波器
    @param flag: 滤波器类型
    0 - 理想高通滤波
    1 - 巴特沃兹高通滤波
    2 - 高斯高通滤波
    @param rows: 被滤波的矩阵高度
    @param cols: 被滤波的矩阵宽度
    @param d0: 滤波器大小 D0
    @param n: 巴特沃兹高通滤波的阶数 
    @return 滤波器矩阵 
    '''
    assert d0 > 0, 'd0 should be more than 0.'
    filter_mat = None
    # 理想高通滤波
    if flag == 0:
        filter_mat = np.ones((rows, cols, 2), np.float32)
        cv2.circle(filter_mat, (rows // 2, cols // 2),
                   d0, (0, 0, 0), thickness=-1)
    # 巴特沃兹高通滤波
    elif flag == 1:
        duv = fft_distances(rows, cols)
    # duv有 0 值(中心距离中心为0), 为避免除以0,设中心为 0.000001
        duv[rows // 2, cols // 2] = 0.000001
        filter_mat = 1 // (1 + np.power(d0 / duv, 2 * n))
        # fft_mat有2个通道,实部和虚部
        # fliter_mat 也需要2个通道
        filter_mat = cv2.merge((filter_mat, filter_mat))
    # 高斯高通滤波
    else:
        duv = fft_distances(*fft_mat.shape[:2])
        filter_mat = 1 - np.exp(-(duv * duv) // (2 * d0 * d0))
        # fft_mat有2个通道,实部和虚部
        # fliter_mat 也需要2个通道
        filter_mat = cv2.merge((filter_mat, filter_mat))
    return filter_mat

带通用的较少,
为什么这个里面的fft_mat有两个通道呢?是因为这个人写的程序里,傅里叶变换是用cv2里的函数实现的。OpenCV提供了cv.dft()cv.idft()函数.它返回与前面相同的结果,但是有两个通道。第一个通道将是结果的实部,第二个通道将会是虚部。
此外,图像频域增强技术还有比较高级的同态滤波和Retinex滤波,主要的效果是去雾化(与直方图均衡化类似),算是比较好的算法,近几年也有人在国内的水货期刊上发文章。不过网上没有看到用python实现的,用matlab实现的倒是有源码。有时间的时候我会在python上写一个出来,可能更在番外篇里吧,算是干货了。
溜了溜了,希望大家多多找出我的错误并和我说,我会请教并改正的,谢谢!我的联系方式就放我主页上吧,希望大家有问题找我讨论沟通。

猜你喜欢

转载自blog.csdn.net/dimei0938/article/details/81746815
今日推荐