迄今为止,看到的函数中,卷积的操作发生在OpenCV函数的内部。理论上,图像卷积就是将内核与图像覆盖区域对应位置相乘之后求和。从调用函数上来看,它需要一个数组参数来描述内核。在实践层面,有一个重要的微妙因素会对结果产生重大影响。微妙之处在于一些内核是可分离的,而另一些则不是。

图1

图1(A)是可分离的; 它可以表示为两个一维卷积(B和C);D是一个不可分割内核的例子。可分离的内核是可以被认为是两个一维内核的内核,首先与x内核进行卷积然后与y内核进行卷积来应用。这种分解的好处是内核卷积的计算成本大约是图像面积乘以内核区域。这意味着用n×n内核卷积区域A的图像需要时间与An2成正比,同时n×1内核与图像卷积一次,然后与1×n内核卷积占用与An + An = 2An成比例。即使n小于3也有好处,随着n的增长,优势更为突出。

1、 利用filter2D()滤波

鉴于图像卷积所需的操作次数,是图像中像素的数量乘以内核中的像素数,这可能需要很多计算,因此,在这种情况下,最好让OpenCV来帮你完成并利用内部优化。OpenCV完成这些操作的函数是filter2D():

cv::filter2D(

cv::InputArray src,

cv::OutputArray dst,

int ddepth,

cv::InputArray kernel,

cv::Point anchor = cv::Point(-1,-1),

double delta = 0,

int borderType = cv::BORDER_DEFAULT

);

创建一个适当大小的数组,并用滤波器的系数填充它,然后将它与源图像和目标图像一起传递到filter2D()中。可以使用ddepth指定结果图像的深度,使用锚点指定滤波的锚点,使用borderType指定边界类型。如果定义了锚点,则内核可以是偶数大小;否则,它应该是奇数大小。如果要在应用滤波器后将总体偏移应用于结果,则可以使用参数delta。

2、 利用sepFilter2D分离滤波器

在内核可分离的情况下,通过以分离的形式表示并将这些一维内核传递给OpenCV,将从OpenCV获得最佳性能。sepFilter2D()与filter2D()类似,除了它期望这两个一维内核而不是一个二维内核。

cv::sepFilter2D(

cv::InputArray src,

cv::OutputArray dst,

int ddepth,

cv::InputArray rowKernel,

cv::InputArray columnKernel,

cv::Point anchor = cv::Point(-1,-1),

double delta = 0,

int borderType = cv::BORDER_DEFAULT

);

sepFilter2D()的所有参数都与cv :: filter2D()的参数相同,但使用rowKernel和columnKernel参数替换内核参数除外。后者为n1×1和1×n2阵列,n1不一定等于n2。

3、构建内核

getDerivKernel()构造Sobel和Scharr内核,getGaussianKernel()构造高斯内核。

void cv::getDerivKernels(

cv::OutputArray kx,

cv::OutputArray ky,

int dx,

int dy,

int ksize,

bool normalize = true,

int ktype = CV_32F

);

getDerivKernel()的结果放置在kx和ky参数中。内核(Sobel和Scharr)是可分离的内核,将返回两个数组,一个是1×ksize(行系数,kx),另一个是ksize×1(列系数,ky)。这些是从x和y导数阶dx和dy计算而来的。衍生内核总是方形的,因此大小参数ksize是一个整数。ksize可以是1,3,5,7或cv ::SCHARR中的任何一个。normalize参数告诉getDerivKernels()是否应该对内核元素进行归一化。对于在浮点图像上操作的情况,将normalize设置为true,但是当正在操作整数数组时,通常更为明智的做法是,在一些数组之前不对数组进行归一化,这样就不会丢掉以后需要的精度。最后一个参数ktype表示滤波器系数的类型。 ktype的值可以是CV_32F或CV_64F。

高斯滤波器的实际内核数组由getGaussianKernel()生成。

cv::Mat cv::getGaussianKernel(

int ksize, // Kernel size

double sigma, // Gaussian half-width

int ktype = CV_32F // Type for filter coefficients

);

与派生内核一样,高斯内核是可分离的。因此,getGaussianKernel()只计算一个ksize×1的系数数组。ksize的值可以是任何奇数正数。参数sigma设置近似高斯分布的标准偏差。根据以下函数从sigma计算系数:

也就是说,计算系数α使得滤波器整体被归一化。可以将其设置为-1,在这种情况下,将根据ksize大小自动计算σ值。在这种情况下,

例1是具体的使用方法,从中能看出构造的每个卷积核的用途吗?

例1:filter2D、sepFilter2D、getDerivKernels、getGaussianKernel功能演示。

#include <iostream>
#include <opencv2opencv.hpp>
using namespace std;
using namespace cv;
int main(int argc, char** argv)
{Mat src = imread("E:/ img.bmp", 1);namedWindow("原始噪声图像", 0);imshow("原始噪声图像", src);//构造滤波器Mat kernal = Mat::ones(3, 3, CV_32FC1);kernal/= 9;Mat filterDst;filter2D(src, filterDst, src.depth(), kernal);namedWindow("filter2D结果1", 0);imshow("filter2D结果1", filterDst);Mat kernal2 = (Mat_<char>(3, 3) << 0, -1, 0,-1, 5, -1,0, -1, 0);Mat dst1;filter2D(filterDst, dst1, src.depth(), kernal2);namedWindow("filter2D结果2", 0);imshow("filter2D结果2", dst1);Mat kx = (Mat_<float>(1, 3) << 0, -1, 0);Mat ky = (Mat_<float>(1, 3) << -1, 0, -1);sepFilter2D(filterDst, dst1, src.depth(), kx, ky);// , Point(-1, -1), 0, BORDER_DEFAULT);namedWindow("sepFilter2D结果", 0);imshow("sepFilter2D结果", dst1);getDerivKernels(kx, ky, 1, 1, 3, true);cout << kx << endl;cout << ky << endl;Mat dst2;sepFilter2D(filterDst, dst2, src.depth(), kx, ky);// , Point(-1, -1), 0, BORDER_DEFAULT);cv::normalize(dst2, dst2, 0, 255, NORM_MINMAX, CV_8UC1);namedWindow("sepFilter2D结果2", 0);imshow("sepFilter2D结果2", dst2);Mat gaussKernal;gaussKernal = getGaussianKernel(7, -1);filter2D(src, filterDst, src.depth(), gaussKernal);namedWindow("Filter2D结果3", 0);imshow("Filter2D结果3", filterDst);waitKey(0);return 0;
}

图2 操作结果示意图

opencv 的norm_22、OpenCV用卷积Filter2D进行滤波器相关推荐

  1. 【OpenCV 例程200篇】54. OpenCV 实现图像二维卷积

    [OpenCV 例程200篇]54. OpenCV 实现图像二维卷积 欢迎关注 『OpenCV 例程200篇』 系列,持续更新中 欢迎关注 『Python小白的OpenCV学习课』 系列,持续更新中 ...

  2. 【OpenCV 例程200篇】96. 谐波平均滤波器

    [OpenCV 例程200篇]96. 谐波平均滤波器 欢迎关注 『OpenCV 例程200篇』 系列,持续更新中 欢迎关注 『Python小白的OpenCV学习课』 系列,持续更新中 3. 仅噪声存在 ...

  3. 【youcans 的 OpenCV 例程200篇】193.基于Gabor 滤波器的特征提取

    OpenCV 例程200篇 总目录-202205更新 [youcans 的 OpenCV 例程200篇]193.基于Gabor 滤波器的特征提取 6.5 Gabor 滤波器 Gabor 变换是一种加窗 ...

  4. 【OpenCV 例程 200篇】98. 统计排序滤波器

    [OpenCV 例程 200篇]98. 统计排序滤波器 欢迎关注 『OpenCV 例程 200 篇』 系列,持续更新中 欢迎关注 『Python小白的OpenCV学习课』 系列,持续更新中 3.5 统 ...

  5. 【opencv】1.opencv安装、编译、运行等踩坑记录

    1.安装python2环境下opencv2.4.9安装不成功的解决方法 2.查看linux下的各种安装库的安装位置和版本,以opencv为例 3.cmake与g++: opencv之在Linux下编译 ...

  6. 解决OpenCV问题:OpenCV Error: Assertion failed (!empty()) in cv::CascadeClassifier::detectMultiScale,

    解决OpenCV问题:OpenCV Error: Assertion failed (!empty()) in cv::CascadeClassifier::detectMultiScale, 目录 ...

  7. OpenCV内置OpenCV的实例(附完整代码)

    OpenCV内置OpenCV的实例 OpenCV内置OpenCV的实例 OpenCV内置OpenCV的实例 #include "opencv2/core.hpp" #include ...

  8. opencv学习(part1)--OpenCv框架介绍

    学习笔记,仅供参考,有错必究 文章目录 opencv学习 OpenCv框架介绍 二值图像分析 二值图像定义与说明 图像二值化介绍 常见的二分类分割方法 opencv学习 OpenCv框架介绍 Open ...

  9. 【OpenCV实战】OpenCV实现人脸检测详解(含代码)

    OpenCV中有许多可以进行人脸.人眼检测的特征文件,今天我们利用OpenCV中自带的特征文件haarcascade_frontalface_default.xml来进行人脸检测. [OpenCV实战 ...

最新文章

  1. 安装CDH5时出错 5.68.168.192.in-addr.arpa domain name pointer bogon.
  2. SQL数据库隐藏服务器后需要在连接字符串增加端口号,(provider: 命名管道提供程序, error: 40 - 无法打开到 SQL Server 的连接)]...
  3. Apache 日志配置,包含过滤配置
  4. Boost.Asio取消异步操作
  5. Flex布局使用总结
  6. button html ios,iOS实现UIButton图标和文字上下布局
  7. 不小心将.gitignore中标记忽略类型的文件提交到了远端仓库,怎么办?
  8. 测试用例管理工具-TestLink
  9. Elsevier旗下期刊利用latex模板撰写论文记录
  10. jsp内置对象request
  11. CodeGenerator代码生成器使用
  12. arm的一些概念(ARM9、Cortex的区别)
  13. CentOS8报错:Error: Failed to download metadata for repo ‘appstream‘: Cannot prepare internal mirrorlis
  14. 精彩的“利益均衡”,尤其是“四”
  15. Windows 10安装WSA(WindowsSubsystemForAndroid)
  16. JAVA音视频解决方案----音频处理方案
  17. 金融组织做规模化敏捷怎么划小队,一文讲清
  18. Java--Java语言基础
  19. 黑客技术真的能破解手机密码?对发展中的人工智能技术有影响吗?
  20. java计算图片相似度_图片相似度比较--算法

热门文章

  1. 重磅!大数据知识总结和调参技巧开放下载了
  2. ESL:我们如何使用首云混合云产品实现提效降本
  3. 华为组织架调整,CloudAI升至第四大BG,打通全球第一款集成5G模组的4K直播编码器网络通信服务;谷歌宣布与IBM合作……...
  4. 【10.23头条】阿里云存储负责人吴结生:安全可靠是云存储立身之本, 智能技术将激活存储技术新变革...
  5. ps4看b站 f怎么调html5,b站html5,b站怎么切换到HTML5版播放器?
  6. python复制列表元素_Python学习教程:Python列表赋值,复制,深拷贝及5种浅拷贝详解...
  7. Oracle run leve,UNIX自动启动oracle
  8. mysql 防注入 php_PHP+mysql防止SQL注入的方法小结
  9. Linux图片马PHP,php 根据请求生成缩略图片保存到Linux图片服务器的代码
  10. linux环境 Oracle客户端连接远程Oracle服务端