本文首发于“小白学视觉”微信公众号,欢迎关注公众号 本文作者为小白,版权归人民邮电出版社发行所有,禁止转载,侵权必究!


经过几个月的努力,小白终于完成了市面上第一本OpenCV 4入门书籍《OpenCV 4开发详解》。为了更让小伙伴更早的了解最新版的OpenCV 4,小白与出版社沟通,提前在公众号上连载部分内容,请持续关注小白。

前面介绍的滤波函数使用的滤波器都是固定形式的滤波器,有时我们需要根据实际需求调整滤波模板,例如在滤波计算过程中滤波器中心位置的像素值不参与计算,滤波器中参与计算的像素值不是一个矩形区域等。OpenCV 4无法根据每种需求单独编写滤波函数,因此OpenCV 4提供了根据自定义滤波器实现图像滤波的函数,就是我们本章最开始介绍的卷积函数filter2D(),不过根据函数的名称,这里称呼为滤波函数更为准确一些,输入的卷积模板也应该称为滤波器或者滤波模板。该函数的使用方式我们在一开始已经介绍,只需要根据需求定义一个卷积模板或者滤波器,便可以实现自定义滤波。

无论是图像卷积还是滤波,在原图像上移动滤波器的过程中每一次的计算结果都不会影响到后面过程的计算结果,因此图像滤波是一个并行的算法,在可以提供并行计算的处理器中可以极大的加快图像滤波的处理速度。除此之外,图像滤波还具有可分离行,这个性质我们在高斯滤波中有简单的接触,可分离性指的是先对X(Y)方向滤波,再对Y(X)方向滤波的结果与将两个方向的滤波器联合后整体滤波的结果相同。两个方向的滤波器的联合就是将两个方向的滤波器相乘,得到一个矩形的滤波器,例如X方向的滤波器为x=[x1x2x3]x={\begin{bmatrix}{{x_1}}&{{x_2}}&{{x_3}} \end{bmatrix}}x=[x1​​x2​​x3​​] ,Y方向的滤波器为y=[y1y2y3]Ty = {\begin{bmatrix}{{y_1}} &{{y_2}}&{{y_3}}\end{bmatrix}}^Ty=[y1​​y2​​y3​​]T,两个方向联合滤波器可以用式(5.7)计算,无论先进行X方向滤波还是Y方向滤波,两个方向联合滤波器都是相同的。
xy=[y1y2y3]∗[x1x2x3]=[x1y1x2y1x3y1x1y2x2y2x2y2x1y3x3y2x3y3](5.7)xy = {\begin{bmatrix} {{y_1}}\\ {{y_2}}\\ {{y_3}} \end{bmatrix}}*{\begin{bmatrix} {{x_1}}&{{x_2}}&{{x_3}} \end{bmatrix}} = {\begin{bmatrix} {{x_1}{y_1}}&{{x_2}{y_1}}&{{x_3}{y_1}}\\ {{x_1}{y_2}}&{{x_2}{y_2}}&{{x_2}{y_2}}\\ {{x_1}{y_3}}&{{x_3}{y_2}}&{{x_3}{y_3}} \end{bmatrix}} \tag{5.7}xy=⎣⎡​y1​y2​y3​​⎦⎤​∗[x1​​x2​​x3​​]=⎣⎡​x1​y1​x1​y2​x1​y3​​x2​y1​x2​y2​x3​y2​​x3​y1​x2​y2​x3​y3​​⎦⎤​(5.7)

因此在高斯滤波中,我们利用getGaussianKernel()函数分别得到X方向和Y方向的滤波器,之后通过生成联合滤波器或者分别用两个方向的滤波器进行滤波的计算结果相同。但是两个方向联合滤波需要在使用filter2D()函数滤波之前计算联合滤波器,而两个方向分别滤波需要调用两次filter2D()函数,增加了通过代码实现的复杂性,因此OpenCV 4提供了可以输入两个方向滤波器实现滤波的滤波函数sepFilter2D(),该函数的函数原型在代码清单5-16中给出。

代码清单5-16 sepFilter2D()函数原型
1.  void cv::sepFilter2D(InputArray  src,
2.                           OutputArray  dst,
3.                           int  ddepth,
4.                           InputArray  kernelX,
5.                           InputArray  kernelY,
6.                           Point  anchor = Point(-1,-1),
7.                           double  delta = 0,
8.                           int  borderType = BORDER_DEFAULT
9.                           )
  • src:待滤波图像
  • dst:输出图像,与输入图像src具有相同的尺寸、通道数和数据类型。
  • ddepth:输出图像的数据类型(深度),根据输入图像的数据类型不同拥有不同的取值范围,具体的取值范围在表5-1给出,当赋值为-1时,输出图像的数据类型自动选择。
  • kernelX:X方向的滤波器,
  • kernelY:Y方向的滤波器。
  • anchor:内核的基准点(锚点),其默认值为(-1,-1)代表内核基准点位于kernel的中心位置。基准点即卷积核中与进行处理的像素点重合的点,其位置必须在卷积核的内部。
  • delta:偏值,在计算结果中加上偏值。
  • borderType:像素外推法选择标志,取值范围在表3-5中给出。默认参数为BORDER_DEFAULT,表示不包含边界值倒序填充。

该函数将可分离的线性滤波器分离成X方向和Y方向进行处理,与filter2D()函数不同之处在于,filter2D()函数需要通过滤波器的尺寸区分滤波操作是作用在X方向还是Y方向,例如滤波器尺寸为K×1时是Y方向滤波,1×K尺寸的滤波器是X方向滤波。而sepFilter2D()函数通过不同参数区分滤波器是作用在X方向还是Y方向,无论输入滤波器的尺寸是K×1还是1×K,都不会影响滤波结果。

为了更加了解线性滤波的可分离性,在代码清单5-17中给出了利用filter2D()函数和sepFilter2D()函数实现滤波的示例程序。程序中利用filter2D()函数依次进行Y方向和X方向滤波,将结果与两个方向联合滤波器滤波结果相比较,验证两种方式计算结果的一致性。同时将两个方向的滤波器输入sepFilter2D()函数中,验证该函数计算结果是否与前面的计算结果一致。最后利用自定义的滤波器,对图像依次进行X方向滤波和Y方向滤波,查看滤波结果是否与使用联合滤波器的滤波结果一致。程序的计算结果依次在图5-19、图5-20给出。

代码清单 5-17 myselfFilter.cpp可分离图像滤波
1.  #include <opencv2\opencv.hpp>
2.  #include <iostream>
3.
4.  using namespace cv;
5.  using namespace std;
6.
7.  int main()
8.  {9.      system("color F0");  //更改输出界面颜色
10.     float points[25] = { 1,2,3,4,5,
11.                              6,7,8,9,10,
12.                              11,12,13,14,15,
13.                              16,17,18,19,20,
14.                              21,22,23,24,25 };
15.     Mat data(5, 5, CV_32FC1, points);
16.     //X方向、Y方向和联合滤波器的构建
17.     Mat a = (Mat_<float>(3, 1) << -1, 3, -1);
18.     Mat b = a.reshape(1, 1);
19.     Mat ab = a*b;
20.     //验证高斯滤波的可分离性
21.     Mat gaussX = getGaussianKernel(3, 1);
22.     Mat gaussData, gaussDataXY;
23.     GaussianBlur(data, gaussData, Size(3, 3), 1, 1, BORDER_CONSTANT);
24.     sepFilter2D(data,gaussDataXY,-1, gaussX, gaussX, Point(-1,-1),0,BORDER_CONSTANT);
25.     //输入两种高斯滤波的计算结果
26.     cout << "gaussData=" << endl
27.         << gaussData << endl;
28.     cout << "gaussDataXY=" << endl
29.         << gaussDataXY << endl;
30.     //线性滤波的可分离性
31.     Mat dataYX, dataY, dataXY, dataXY_sep;
32.     filter2D(data, dataY, -1, a, Point(-1, -1), 0, BORDER_CONSTANT);
33.     filter2D(dataY, dataYX, -1, b, Point(-1, -1), 0, BORDER_CONSTANT);
34.     filter2D(data, dataXY, -1, ab, Point(-1, -1), 0, BORDER_CONSTANT);
35.     sepFilter2D(data, dataXY_sep, -1, b, b, Point(-1, -1), 0, BORDER_CONSTANT);
36.     //输出分离滤波和联合滤波的计算结果
37.     cout << "dataY=" << endl
38.         << dataY << endl;
39.     cout << "dataYX=" << endl
40.         << dataYX << endl;
41.     cout << "dataXY=" << endl
42.         << dataXY << endl;
43.     cout << "dataXY_sep=" << endl
44.         << dataXY_sep << endl;
45.     //对图像的分离操作
46.     Mat img = imread("lena.png");
47.     if (img.empty())
48.     {49.         cout << "请确认图像文件名称是否正确" << endl;
50.         return -1;
51.     }
52.     Mat imgYX, imgY, imgXY;
53.     filter2D(img, imgY, -1, a, Point(-1, -1), 0, BORDER_CONSTANT);
54.     filter2D(imgY, imgYX, -1, b, Point(-1, -1), 0, BORDER_CONSTANT);
55.     filter2D(img, imgXY, -1, ab, Point(-1, -1), 0, BORDER_CONSTANT);
56.     imshow("img", img);
57.     imshow("imgY", imgY);
58.     imshow("imgYX", imgYX);
59.     imshow("imgXY", imgXY);
60.     waitKey(0);
61.     return 0;
62. }

图5-19 myselfFilter.cpp程序中数据矩阵滤波结果 图5-20 myselfFilter.cpp程序中图像滤波结果

OpenCV 4开发详解
往期推荐
【OpenCV 4开发详解】视频加载与摄像头调用
【OpenCV 4开发详解】图像与视频的保存
【OpenCV 4开发详解】保存和读取XML和YMAL文件
【OpenCV 4开发详解】颜色模型与转换
【OpenCV 4开发详解】多通道分离与合并
【OpenCV 4开发详解】图像像素统计
【OpenCV 4开发详解】两图像间的像素操作
【OpenCV 4开发详解】图像二值化
【OpenCV 4开发详解】图像LUT查找表
【OpenCV 4开发详解】图像连接
【OpenCV 4开发详解】图像仿射变换
【OpenCV 4开发详解】图像透视变换
【OpenCV 4开发详解】图像极坐标变换
【OpenCV 4开发详解】图像上绘制几何图形
【OpenCV 4开发详解】图像金字塔
【OpenCV 4开发详解】窗口交互操作
【OpenCV 4开发详解】图像直方图绘制
【OpenCV 4开发详解】直方图操作
【OpenCV 4开发详解】直方图应用
【OpenCV 4开发详解】图像模板匹配
【OpenCV 4开发详解】图像卷积
【OpenCV 4开发详解】图像噪声的种类与生成
【OpenCV 4开发详解】均值滤波
【OpenCV 4开发详解】方框滤波
【OpenCV 4开发详解】高斯滤波
经过几个月的努力,市面上第一本OpenCV 4入门书籍《OpenCV 4开发详解》将春节后由人民邮电出版社发行。如果小伙伴觉得内容有帮助,希望到时候多多支持!
关注小白的小伙伴可以提前看到书中的内容,我们创建了学习交流群,欢迎各位小伙伴添加小白微信加入交流群,添加小白时请备注“学习OpenCV 4”。

【OpenCV 4开发详解】可分离滤波相关推荐

  1. 【OpenCV 4开发详解】中值滤波

    本文首发于"小白学视觉"微信公众号,欢迎关注公众号 本文作者为小白,版权归人民邮电出版社发行所有,禁止转载,侵权必究! 经过几个月的努力,小白终于完成了市面上第一本OpenCV 4 ...

  2. 【OpenCV 4开发详解】高斯滤波

    本文首发于"小白学视觉"微信公众号,欢迎关注公众号 本文作者为小白,版权归人民邮电出版社发行所有,禁止转载,侵权必究! 经过几个月的努力,小白终于完成了市面上第一本OpenCV 4 ...

  3. 【OpenCV 4开发详解】方框滤波

    本文首发于"小白学视觉"微信公众号,欢迎关注公众号 本文作者为小白,版权归人民邮电出版社发行所有,禁止转载,侵权必究! 经过几个月的努力,小白终于完成了市面上第一本OpenCV 4 ...

  4. 【OpenCV 4开发详解】均值滤波

    本文首发于"小白学视觉"微信公众号,欢迎关注公众号 本文作者为小白,版权归人民邮电出版社发行所有,禁止转载,侵权必究! 经过几个月的努力,小白终于完成了市面上第一本OpenCV 4 ...

  5. 【OpenCV 4开发详解】分割图像——分水岭法

    本文首发于"小白学视觉"微信公众号,欢迎关注公众号 本文作者为小白,版权归人民邮电出版社发行所有,禁止转载,侵权必究! 经过几个月的努力,小白终于完成了市面上第一本OpenCV 4 ...

  6. 【OpenCV 4开发详解】深度神经网络应用实例

    本文首发于"小白学视觉"微信公众号,欢迎关注公众号 本文作者为小白,版权归人民邮电出版社发行所有,禁止转载,侵权必究! 经过几个月的努力,小白终于完成了市面上第一本OpenCV 4 ...

  7. 【OpenCV 4开发详解】图像修复

    本文首发于"小白学视觉"微信公众号,欢迎关注公众号 本文作者为小白,版权归人民邮电出版社发行所有,禁止转载,侵权必究! 经过几个月的努力,小白终于完成了市面上第一本OpenCV 4 ...

  8. 【OpenCV 4开发详解】分割图像——Mean-Shift分割算法

    本文首发于"小白学视觉"微信公众号,欢迎关注公众号 本文作者为小白,版权归人民邮电出版社发行所有,禁止转载,侵权必究! 经过几个月的努力,小白终于完成了市面上第一本OpenCV 4 ...

  9. 【OpenCV 4开发详解】分割图像——Grabcut图像分割

    本文首发于"小白学视觉"微信公众号,欢迎关注公众号 本文作者为小白,版权归人民邮电出版社发行所有,禁止转载,侵权必究! 经过几个月的努力,小白终于完成了市面上第一本OpenCV 4 ...

最新文章

  1. Winform中设置ZedGraph的颜色填充使用Fill
  2. c++ 输出二进制_C语言 printf 格式化输出的详细示例
  3. 拓端tecdat|使用SAS Enterprise Miner进行数据挖掘:信用评分构建评分卡模型
  4. Java开源内容管理CMS系统J4CMS的几个样式
  5. 能够支持python开发的环境_Windows上使用virtualenv搭建Python+Flask开发环境
  6. 本地创建MYSQL数据库详解
  7. python学强化学习
  8. PS钢笔工具使用方法简介
  9. ubuntu 终端查看图片(eog)
  10. bequeath_conn
  11. python和ruby对比
  12. 高能所客座用户计算机申请,2020年中科院高能所招收联合培养硕士博士生、客座研究生多名...
  13. 搞机器学习需要哪些技能
  14. python 随机森林分类 DecisionTreeClassifier 随机搜索优化参数 GridSearchCV
  15. 专家建议加速2G3G退网、5G取代4G,你感受到网速快了吗?
  16. 21、TWS API和IB中的新闻和公告
  17. 如何模拟微信内置浏览器阅读环境打开文章
  18. MYSQL UDF提权
  19. 牛客网2-给定一系列正整数,请按要求对数字进行分类,并输出以下5个数字
  20. 考虑以下c语言代码int,计算机组成习题答案(清华大学出版社)

热门文章

  1. 高通与苹果宣布“复合”,英特尔黯然退场 | 极客头条
  2. 一款高颜值的 MySQL 管理工具
  3. WebSocket 集群解决方案
  4. 骚操作 !IDEA 防止写代码沉迷插件 !
  5. 总结:一些关于 CPU 的基本知识
  6. 基于深度学习的文本分类应用!
  7. 计算机科学和Python编程导论(二 ) Python简介
  8. 厚积薄发!他读博前三年零文章,后期发力产出11篇一作,现任985高校博导
  9. 导师吐槽大会开始:自己招的学生,哭着也要带完
  10. TensorRT和PyTorch模型的故事