OpenCV图像处理之自定义滤波

 更新时间:2021年08月25日 09:46:46   作者:飞鸢逐浪  
滤波处理分为两大类:线性滤波和非线性滤波,OpenCV里有这些滤波的函数,使用起来非常方便,这篇文章主要给大家介绍了关于OpenCV图像处理之自定义滤波的相关资料,文中通过示例代码介绍的非常详细,需要的朋友可以参考下

图像处理中,"空间域" 指的是图像平面,因此,空间滤波可定义为:在图像平面内对像素灰度值进行的滤波

1 空间滤波

1.1 滤波过程

如图,Filter 是一个 3x3 滤波核,当它从图像的左上角开始,逐个像素沿水平方向扫描,最后到右下角时,便会产生滤波后的图像

假设输入图像 $f(x, y)$,滤波后的图像为$g(x, y)$,则其中$g(2,2)$ 和 $g(4,4)$ 的计算过程如下:

上图中,以像素 (4,4) 为中心的 3x3 邻域,和滤波核的向量点乘之积,即为 g(4,4)

g(4,4) = 240*0.1111 + 183*0.1111 + 0*0.1111 + 250*0.1111 + 12*0.1111 + 87*0.1111 + 255*0.1111 + 1*0.1111 + 94*0.1111

= 26.6666 + 20.3333 + 0 + 27.7777 + 1.3333 + 9.6666 + 28.3333 + 0 + 10.4444

= 124.55

1.2 相关和卷积

空间滤波中,相关和卷积,是容易混淆的概念,定义如下:

-相关 (Correlation),和上述的滤波过程一样,即 滤波核 逐行扫描图像,并计算每个位置像素点积的过程

-卷积 (Convolution),和 "相关" 过程类似,但 滤波核 要先旋转 180°,然后再执行和 “相关” 一样的操作

(二维中的旋转 180°,等于滤波核沿一个坐标轴翻转,然后再沿另一个坐标轴翻转)

注意:如果滤波核是对称的,则对图像进行相关和卷积的结果是一致的

2 OpenCV 函数

2.1 filter2D 函数

在 OpenCV 中,可自定义滤波核,然后通过 filter2D() 来完成图像滤波

void filter2D(
     InputArray     src,              // 输入图像 
     OutputArray    dst,              // 输出图像(大小和通道数,同 src)
     int            ddepth,           // 输出图像的 depth
     InputArray     kernel,           // 滤波核,准确地说,是相关核
     Point  anchor = Point(-1,-1),    // 锚点位置,滤波核尺寸为奇数时,不用指定,一般取默认值 Point(-1,-1);滤波核尺寸为偶数时,需指定锚点位置
     double             delta = 0,    // optional value added to the filtered pixels before storing them in dst      
     int borderType = BORDER_DEFAULT  // 边界处理方法
 );

filter2D() 求的是相关,并非卷积,只有当滤波核对称时,filte2D() 才可视为卷积运算,其公式如下:

假定滤波核 kernel 大小为 3x3,以一个像素点 src(4,4) 为例,则有:

dst(4,4) = kernel(0,0)*src(4+0-1, 4+0-1) + kernel(0,1)*src(4+0-1, 4+1-1) + kernel(0,2)*src(4+0-1, 4+2-1)

+ kernel(1,0)*src(4+1-1, 4+0-1) + kernel(1,1)*src(4+1-1, 4+1-1) + kernel(1,2)*src(4+1-1, 4+2-1)

+ kernel(2,0)*src(4+2-1, 4+0-1) + kernel(2,1)*src(4+2-1, 4+1-1) + kernel(2,2)*src(4+2-1, 4+2-1)

滤波核与输入图像的卷积点乘,对应关系如下:

2.2 flip 函数

当滤波核不对称时,要得到真正的卷积运算,还需 flip() 函数来完成 kernel 的二维翻转

如果滤波核的大小为奇数,则 filter2D() 中的锚点位置可设为 Point(-1,-1),此时,默认滤波核的中心为锚点;如果滤波核的大小为偶数,则需要自定义锚点位置

OpenCV 中锚点位置的实现函数normalizeAnchor() 如下:

  void flip(
      InputArray  src,  // input array
      OutputArray dst,  // output array
      int    flipCode   // 0, flip around x-axis; positive value, flip around y-axis; negative value, flip around both axes.
  );

3 代码示例

3.1 偏导数

自定义滤波核,利用 filter2D() 函数,实现图像的一阶和二阶偏导运算

1) 一阶偏导

图像在 x 和 y 方向的一阶偏导如下:

对应滤波核为

2) 二阶偏导

同样,在 x 和 y 方向的二阶偏导如下:

对应滤波核为

3.2 代码示例

#include "opencv2/imgproc.hpp"
#include "opencv2/highgui.hpp"

using namespace cv;

int main()
{
    // 读取图像
    Mat src = imread("fangtze.jpg", IMREAD_GRAYSCALE);
    if (src.empty()) {
        return -1;
    }

    Mat kx = (Mat_<float>(1, 2) << -1, 1);  // 1行2列的 dx 滤波核
    Mat ky = (Mat_<float>(2, 1) << -1, 1);  // 2行1列的 dy 滤波核

    Mat kxx = (Mat_<float>(1, 3) << 1, -2, 1);     // 1行3列的 dxx 滤波核
    Mat kyy = (Mat_<float>(3, 1) << 1, -2, 1);     // 3行1列的 dyy 滤波核
    Mat kxy = (Mat_<float>(2, 2) << 1, -1, -1, 1); // 2行2列的 dxy 滤波核

    // 一阶偏导
    Mat dx, dy;
    filter2D(src, dx, CV_32FC1, kx);
    filter2D(src, dy, CV_32FC1, ky);

    // 二阶偏导
    Mat dxx, dyy, dxy;
    filter2D(src, dxx, CV_32FC1, kxx);
    filter2D(src, dyy, CV_32FC1, kyy);
    filter2D(src, dxy, CV_32FC1, kxy);

    // 显示图像
    imshow("dx", dx);

    waitKey();
}

输出的偏导图像如下,第一行从左到右:原图 - dx - dy;第二行从左至右:dxy - dxx -dyy

参考资料

OpenCV Tutorials / imgproc module /Making your own linear filters

Gonzalez,《Digital Image Processing》4th ch3 Intesity Transformations and Spatial Filtering

CS425 Lab: Intensity Transformations and Spatial Filtering

总结

到此这篇关于OpenCV图像处理之自定义滤波的文章就介绍到这了,更多相关OpenCV自定义滤波内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • flask框架url与重定向操作实例详解

    flask框架url与重定向操作实例详解

    这篇文章主要介绍了flask框架url与重定向操作,结合实例形式详细分析了flask框架URL映射、传参、重定向等相关概念、原理与操作注意事项,需要的朋友可以参考下
    2020-01-01
  • Python with语句上下文管理器两种实现方法分析

    Python with语句上下文管理器两种实现方法分析

    这篇文章主要介绍了Python with语句上下文管理器两种实现方法,结合实例形式较为详细的分析了Python上下文管理器的相关概念、功能、使用方法及相关操作注意事项,需要的朋友可以参考下
    2018-02-02
  • 详解Python网络框架Django和Scrapy安装指南

    详解Python网络框架Django和Scrapy安装指南

    这篇文章主要介绍了详解Python网络框架Django和Scrapy安装指南,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2019-04-04
  • Ubuntu下升级 python3.7.1流程备忘(推荐)

    Ubuntu下升级 python3.7.1流程备忘(推荐)

    这篇文章主要介绍了Ubuntu下升级 python3.7.1流程备忘,本文通过实例代码给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下
    2018-12-12
  • jupyter notebook指定启动目录的方法

    jupyter notebook指定启动目录的方法

    这篇文章主要介绍了jupyter notebook指定启动目录的方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-03-03
  • Python中常用的十个函数介绍

    Python中常用的十个函数介绍

    这篇文章主要介绍了Python中常用的十个函数,shutil 是 Python 中的高级文件操作模块,与os模块形成互补的关系,需要的朋友可以参考下
    2023-04-04
  • pandas 使用insert插入一列

    pandas 使用insert插入一列

    这篇文章主要介绍了pandas 使用insert插入一列的操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-03-03
  • Python with用法:自动关闭文件进程

    Python with用法:自动关闭文件进程

    这篇文章主要介绍了Python with用法:自动关闭文件进程,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-07-07
  • Python代码生成视频的缩略图的实例讲解

    Python代码生成视频的缩略图的实例讲解

    在本篇文章里小编给大家正里的是一篇关于Python代码生成视频的缩略图的实例讲解,对此有需要的朋友们可以跟着学习下。
    2019-12-12
  • Python爬虫UA伪装爬取的实例讲解

    Python爬虫UA伪装爬取的实例讲解

    在本篇文章里小编给大家整理的是一篇关于Python爬虫UA伪装爬取的实例讲解内容,有需要的朋友们可以学习参考下。
    2021-02-02

最新评论