• Python-OpenCV中的filter2D()函数


    原文转自:https://www.cnblogs.com/lfri/p/10599420.html

    Python-OpenCV中的filter2D()函数

     

    使用自定义内核对图像进行卷积。该功能将任意线性滤波器应用于图像。支持就地操作。当光圈部分位于图像外部时,该功能会根据指定的边框模式插入异常像素值。

     

    语法

    函数原型:

    dst=cv.filter2D(src, ddepth, kernel[, dst[, anchor[, delta[, borderType]]]])

    参数:

    参数 描述
    src 原图像
    dst 目标图像,与原图像尺寸和通过数相同
    ddepth 目标图像的所需深度
    kernel 卷积核(或相当于相关核),单通道浮点矩阵;如果要将不同的内核应用于不同的通道,请使用拆分将图像拆分为单独的颜色平面,然后单独处理它们。
    anchor 内核的锚点,指示内核中过滤点的相对位置;锚应位于内核中;默认值(-1,-1)表示锚位于内核中心。
    detal 在将它们存储在dst中之前,将可选值添加到已过滤的像素中。类似于偏置。
    borderType 像素外推法,参见BorderTypes

    该函数实际计算的是相关性,而不是卷积

    dst(x,y)=0y<kernel.rows0x<kernel.cols,kernel(x,y)src(x+xanchor.x,y+yanchor.y)dst(x,y)=∑0≤y′<kernel.rows0≤x′<kernel.cols,kernel(x′,y′)∗src(x+x′−anchor.x,y+y′−anchor.y)

    在内核足够大(~11x11或者更大)的时候,该函数使用DFT算法,对于小内核则直接计算。

    也可见,anchor相当于坐标轴平移。

    其中ddepth表示目标图像的所需深度,它包含有关图像中存储的数据类型的信息,可以是unsigned char(CV_8U),signed char(CV_8S),unsigned short(CV_16U)等等...

    Input depth (src.depth())Output depth (ddepth)
    CV_8U -1/CV_16S/CV_32F/CV_64F
    CV_16U/CV_16S -1/CV_32F/CV_64F
    CV_32F -1/CV_32F/CV_64F
    CV_64F -1/CV_64F

     Note:当ddepth=-1时,表示输出图像与原图像有相同的深度。

    例子

    图像内核是一个小矩阵,用于应用您可能在Photoshop或Gimp中找到的效果,例如模糊,锐化,轮廓或浮雕。它们还用于机器学习中的“特征提取”,这是一种用于确定图像最重要部分的技术。在这种情况下,该过程更普遍地称为“卷积”(参见:卷积神经网络)。

    有许多有趣的内核,下面一一介绍:

     1、模糊(blur)

    模糊内核消除了相邻像素值之间的差异。内核如下:

    0.0625 0.125 0.0625
    0.125 0.25 0.125
    0.0625 0.125 0.125

     代码:

    复制代码
    import cv2
    import numpy as np
    
    def solve():
    
        src = cv2.imread("./Pictures/car001.jpg")
        if src is None:
            return -1
    
        kernel = np.array((
            [0.0625, 0.125, 0.0625],
            [0.125, 0.25, 0.125],
            [0.0625, 0.125, 0.0625]), dtype="float32")
    
    
        dst = cv2.filter2D(src, -1, kernel)
        htich = np.hstack((src, dst))
        cv2.imwrite("./Pictures/car.jpg", htich)
        cv2.imshow('merged_img', htich)
        cv2.waitKey(0)
    
        return 0
    
    
    if __name__ == "__main__":
        solve()
    复制代码

    效果:

    2、索贝尔(sobel)

    sobel内核用于仅显示特定方向上相邻像素值的差异,分为left sobel、right sobel(检测梯度的水平变化)、top sobel、buttom sobel(检测梯度的垂直变化)。

    例如,buttom sobel

    -1 -2 -1
    0 0 0
    1 2 1

    代码与上面类似,只需修改krenel的值。

    3、浮雕(emboss)

    通过强调像素的差在给定方向的Givens深度的错觉。在这种情况下,沿着从左上到右下的直线的方向。

    -2 -1 0
    -1 1 1
    0 1 2

    效果:

    4、大纲(outline)

    一个轮廓内核(也称为“边缘”的内核)用于突出显示的像素值大的差异。具有接近相同强度的相邻像素旁边的像素在新图像中将显示为黑色,而与强烈不同的相邻像素相邻的像素将显示为白色。

    -1 -1 -1
    -1 8 -1
    -1 -1 -1

    效果:


    5、锐化(sharpen)

    锐化内核强调在相邻的像素值的差异。这使图像看起来更生动。

    0 -1 0
    -1 5 -1
    0 -1 0

    效果:

    6、拉普拉斯算子(laplacian operator)

    拉普拉斯算子可以用于边缘检测,对于检测图像中的模糊也非常有用。

    0 1 0
    1 -4 1
    0 1 0

    效果:

    7、分身(identity)

    这个非常简单,就是原图(不考虑边界时),How boring!

    0 0 0
    0 1 0
    0 0 0

    拓展部分

    正如您在本博文中所收集的那样,我们必须  手动定义每个内核以应用各种操作,例如平滑,锐化和边缘检测。

    如何定义内核达到你想要的效果,这并不是一件简单的事情。

    现在有一种神经网络——CNN,通过应用卷积滤波器,非线性激活函数,汇集和反向传播,CNN能够学习过滤器(的权重),可以检测网络较低层中的边缘和类似blob的结构 - 然后使用边缘和结构作为构建块,最终在网络的更深层中检测更高级别的对象(即,面部,猫,狗,杯等)。这样就不必手动定义过滤器了。

  • 相关阅读:
    DNS域名解析抓包分析
    Redis实现分布式锁
    Redis内存回收淘汰策略
    Redis缓存雪崩、击穿、穿透
    Redis内存碎片
    C++ 友元
    C++ const
    C++构造函数与析构函数调用虚函数
    C++类成员变量的初始化顺序
    C++ 类对象和类指针
  • 原文地址:https://www.cnblogs.com/whw1314/p/12007928.html
Copyright © 2020-2023  润新知