OpenCV filter2D函数详解

     OpenCV filter2D函数简介   

        OpenCV filter2D将图像与内核进行卷积,将任意线性滤波器应用于图像。支持就地操作。当孔径部分位于图像之外时,该函数根据指定的边界模式插值异常像素值。

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

  filter2D函数的原型如下:

        void cv::filter2D(InputArray src,

                                        OutputArray dst,

                                        int  ddepth,

                                        InputArray  kernel,

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

                                        double  delta = 0,

                                        int       borderType = BORDER_DEFAULT

                                        )

参数:

        src 输入图像

       dst  输出图像,与 src 大小相同、通道数相同

       ddepth  目标图像的所需深度

        kernel 卷积核(或者更确切地说是相关核),单通道浮点矩阵;如果要将不同的内核应用于                        不同的通道,请使用 split 将图像分割为单独的颜色平面并单独处理它们。

        anchor 内核的锚点,指示内核中过滤点的相对位置;锚应该位于内核内;默认值(-1,-1)                      表示锚点位于内核中心。

        delta  在将过滤像素存储到 dst 之前添加到过滤像素的可选值。

        borderType 像素外推方法。可以选以下几种:BORDER_CONSTANT,BORDER_REPLICATE,BORDER_REFLECT,BORDER_REFLECT_101,BORDER_TRANSPARENT,BORDER_REFLECT101,BORDER_DEFAULT,BORDER_ISOLATED。

        OpenCV filter2D函数应用

        使用OpenCV filter2D函数,通过改变卷积核(kernel)可达成不同的滤波效果。下面就OpenCV filter2D函数的几种常用场景做说明,并以实例做演示。

        图像锐化

        图像锐化使用的卷积核如下:

        Mat kernel = (Mat_<char>(3, 3) << 0, -1, 0, -1, 5, -1, 0, -1, 0);

        下面以实例演示图像锐化操作及锐化效果,示例代码如下:

#include <iostream>
#include <opencv2/opencv.hpp>using namespace cv;
using namespace std;int main(int argc, char** argv)
{Mat src = imread("1.jpg");if (src.empty()){cout << "Cann't open Image" << endl;return -1;}imshow("Input Image", src);Mat kernel = (Mat_<char>(3, 3) << 0, -1, 0, -1, 5, -1, 0, -1, 0);Mat dst;filter2D(src, dst, src.depth(), kernel);imshow("Output Image", dst);waitKey(0);return 0;
}

试运行,结果如下:

        可以看到经过Filter2D滤波后的图像变得更清晰。

均值滤波

        OpenCV filter2D函数实现均值滤波的卷积核如下:

Mat kernel = (Mat_<float>(3, 3) << 1, 1, 1, 1, 1, 1, 1, 1, 1) / 9;

下面以实例演示filter2D实现图像均值滤波操作及滤波效果,示例代码如下:

#include <iostream>
#include <opencv2/opencv.hpp>using namespace cv;
using namespace std;int main(int argc, char** argv)
{//sharp test/*Mat src = imread("1.jpg");if (src.empty()){cout << "Cann't open Image" << endl;return -1;}imshow("Input Image", src);Mat kernel = (Mat_<char>(3, 3) << 0, -1, 0, -1, 5, -1, 0, -1, 0);Mat dst;filter2D(src, dst, src.depth(), kernel);imshow("Output Image", dst);*///Mean filter testMat src = imread("3.png");if (src.empty()){cout << "Cann't open Image" << endl;return -1;}imshow("Input Image", src);Mat kernel = (Mat_<float>(3, 3) << 1, 1, 1, 1, 1, 1, 1, 1, 1) / 9;Mat dst;filter2D(src, dst, src.depth(), kernel);for (size_t i = 0; i < 15; i++){filter2D(dst, dst, src.depth(), kernel);}imshow("Output Image", dst);waitKey(0);return 0;
}

       试运行,结果如下:

 

可以看出,均值滤波可以去除图像椒盐噪声,达到磨皮效果。

 高斯滤波

OpenCV filter2D函数实现高斯滤波的卷积核可由高斯核转换得到,方法如下:

Mat kernelGaussian = getGaussianKernel(9, 1.5);
Mat  kernel = kernelGaussian * kernelGaussian.t();

下面以实例演示filter2D实现图像高斯滤波操作及滤波效果,示例代码如下:

#include <iostream>
#include <opencv2/opencv.hpp>using namespace cv;
using namespace std;int main(int argc, char** argv)
{//filter2d sharp test/*Mat src = imread("1.jpg");if (src.empty()){cout << "Cann't open Image" << endl;return -1;}imshow("Input Image", src);Mat kernel = (Mat_<char>(3, 3) << 0, -1, 0, -1, 5, -1, 0, -1, 0);Mat dst;filter2D(src, dst, src.depth(), kernel);imshow("Output Image", dst);*///filter2d Mean filter test/*Mat src = imread("3.png");if (src.empty()){cout << "Cann't open Image" << endl;return -1;}imshow("Input Image", src);Mat kernel = (Mat_<float>(3, 3) << 1, 1, 1, 1, 1, 1, 1, 1, 1) / 9;Mat dst;filter2D(src, dst, src.depth(), kernel);for (size_t i = 0; i < 15; i++){filter2D(dst, dst, src.depth(), kernel);}imshow("Output Image", dst);*///filter2d Gaussian filter testMat src = imread("3.png");if (src.empty()){cout << "Cann't open Image" << endl;return -1;}imshow("Input Image", src);Mat kernelGaussian = getGaussianKernel(9, 1.5);Mat  kernel = kernelGaussian * kernelGaussian.t();Mat dst;filter2D(src, dst, src.depth(), kernel);for (size_t i = 0; i < 6; i++){filter2D(dst, dst, src.depth(), kernel);}imshow("Output Image", dst);waitKey(0);return 0;
}

试运行,结果如下:

可以看出,同样filter2D均高斯滤波同样可以去除图像椒盐噪声,达成磨皮效果,且所需次数更少。

 边缘检测

 filter2D还可以使用sobel内核实现边缘检测,soble内核如下:

Mat sobelX = (Mat_<float>(3, 3) << -1, 0, 1,-2, 0, 2,-1, 0, 1);
Mat sobelY = (Mat_<float>(3, 3) << -1, -2, -1,0, 0, 0,1, 2, 1);

下面以实例演示filter2D 用sobel核实现图像边缘检测操作及滤波效果,示例代码如下:

#include <iostream>
#include <opencv2/opencv.hpp>using namespace cv;
using namespace std;int main(int argc, char** argv)
{//filter2d sharp test/*Mat src = imread("1.jpg");if (src.empty()){cout << "Cann't open Image" << endl;return -1;}imshow("Input Image", src);Mat kernel = (Mat_<char>(3, 3) << 0, -1, 0, -1, 5, -1, 0, -1, 0);Mat dst;filter2D(src, dst, src.depth(), kernel);imshow("Output Image", dst);*///filter2d Mean filter test/*Mat src = imread("3.png");if (src.empty()){cout << "Cann't open Image" << endl;return -1;}imshow("Input Image", src);Mat kernel = (Mat_<float>(3, 3) << 1, 1, 1, 1, 1, 1, 1, 1, 1) / 9;Mat dst;filter2D(src, dst, src.depth(), kernel);for (size_t i = 0; i < 15; i++){filter2D(dst, dst, src.depth(), kernel);}imshow("Output Image", dst);*///filter2d Gaussian filter test/*Mat src = imread("3.png");if (src.empty()){cout << "Cann't open Image" << endl;return -1;}imshow("Input Image", src);Mat kernelGaussian = getGaussianKernel(9, 1.5);Mat  kernel = kernelGaussian * kernelGaussian.t();Mat dst;filter2D(src, dst, src.depth(), kernel);for (size_t i = 0; i < 6; i++){filter2D(dst, dst, src.depth(), kernel);}imshow("Output Image", dst);*///filter2d detect edges testMat src = imread("4.png");if (src.empty()){cout << "Cann't open Image" << endl;return -1;}threshold(src, src, 127, 255, THRESH_BINARY);imshow("Input Image", src);Mat sobelX = (Mat_<float>(3, 3) << -1, 0, 1,-2, 0, 2,-1, 0, 1);Mat sobelY = (Mat_<float>(3, 3) << -1, -2, -1,0, 0, 0,1, 2, 1);Mat edges,edgesX, edgesY;filter2D(src, edgesX, CV_16S, sobelX);filter2D(src, edgesY, CV_16S, sobelX);convertScaleAbs(edgesX, edgesX);convertScaleAbs(edgesY, edgesY);addWeighted(edgesX, 0.5, edgesY, 0.5, 0, edges);imshow("Edges", edges);waitKey(0);return 0;
}

试运行,结果如下:

        可以看出确实检测到了边缘,效果并不是很好。

        filter2D还可以使用Prewitt核,实现边缘检测。Prewitt核如下:

        Mat prewitt_x = (Mat_<int>(3, 3) << -1, 0, 1, -1, 0, 1, -1, 0, 1);
        Mat prewitt_y = (Mat_<int>(3, 3) << -1, -1, -1,0, 0, 0, 1, 1, 1);

        下面以实例演示filter2D 用Prewitt核实现图像边缘检测操作及滤波效果,示例代码如下:

#include <iostream>
#include <opencv2/opencv.hpp>using namespace cv;
using namespace std;int main(int argc, char** argv)
{//filter2d sharp test/*Mat src = imread("1.jpg");if (src.empty()){cout << "Cann't open Image" << endl;return -1;}imshow("Input Image", src);Mat kernel = (Mat_<char>(3, 3) << 0, -1, 0, -1, 5, -1, 0, -1, 0);Mat dst;filter2D(src, dst, src.depth(), kernel);imshow("Output Image", dst);*///filter2d Mean filter test/*Mat src = imread("3.png");if (src.empty()){cout << "Cann't open Image" << endl;return -1;}imshow("Input Image", src);Mat kernel = (Mat_<float>(3, 3) << 1, 1, 1, 1, 1, 1, 1, 1, 1) / 9;Mat dst;filter2D(src, dst, src.depth(), kernel);for (size_t i = 0; i < 15; i++){filter2D(dst, dst, src.depth(), kernel);}imshow("Output Image", dst);*///filter2d Gaussian filter test/*Mat src = imread("3.png");if (src.empty()){cout << "Cann't open Image" << endl;return -1;}imshow("Input Image", src);Mat kernelGaussian = getGaussianKernel(9, 1.5);Mat  kernel = kernelGaussian * kernelGaussian.t();Mat dst;filter2D(src, dst, src.depth(), kernel);for (size_t i = 0; i < 6; i++){filter2D(dst, dst, src.depth(), kernel);}imshow("Output Image", dst);*///filter2d detect edges test/*//sobel kernelMat src = imread("4.png");if (src.empty()){cout << "Cann't open Image" << endl;return -1;}threshold(src, src, 127, 255, THRESH_BINARY);imshow("Input Image", src);Mat sobelX = (Mat_<float>(3, 3) << -1, 0, 1,-2, 0, 2,-1, 0, 1);Mat sobelY = (Mat_<float>(3, 3) << -1, -2, -1,0, 0, 0,1, 2, 1);Mat edges,edgesX, edgesY;filter2D(src, edgesX, CV_16S, sobelX);filter2D(src, edgesY, CV_16S, sobelX);convertScaleAbs(edgesX, edgesX);convertScaleAbs(edgesY, edgesY);addWeighted(edgesX, 0.5, edgesY, 0.5, 0, edges);imshow("Edges", edges);*///Prewitt kernelMat src = imread("4.png");if (src.empty()){cout << "Cann't open Image" << endl;return -1;}threshold(src, src, 127, 255, THRESH_BINARY);imshow("Input Image", src);Mat prewitt_x = (Mat_<int>(3, 3) << -1, 0, 1, -1, 0, 1, -1, 0, 1);Mat prewitt_y = (Mat_<int>(3, 3) << -1, -1, -1,0, 0, 0, 1, 1, 1);Mat edges, edgesX, edgesY;filter2D(src, edgesX, src.depth(), prewitt_x);filter2D(src, edgesY, src.depth(), prewitt_y);addWeighted(edgesX, 0.5, edgesY, 0.5, 0, edges);imshow("Edges", edges);waitKey(0);return 0;
}

试运行,结果如下:

        从结果可以看出,filter2D使用Prewitt核检测边缘的结果,与使用sobel核边缘检测的结果是有差异的。

      OpenCV  filter2D函数就介绍到这里。博文示例是基于OpenCV4.8(opencv目录位于d盘根目录下)及VS2022。示例源码已上传到CSDN,其链接为:https://mp.csdn.net/mp_blog/creation/editor/136590730

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/527596.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C++20四大特性之Ranges

C20 Ranges 1.基础概念2.使用 在之前的文章已经写过另外三大特性&#xff0c;直通点&#xff1a; C那些事之C20协程开篇 盘点C20模块那些事 C20&#xff1a;从0到1学懂concept 那么&#xff0c;本篇将开始学习另外一个特性ranges。 ranges是C20的主要特性之一&#xff0c;其中&…

WebRTC简介及实战应用 — 从0到1实现实时音视频聊天等功能

一、WebRTC简介 WebRTC 是由一家名为 Gobal IP Solutions,简称 GIPS 的瑞典公司开发的。Google 在 2011 年收购了 GIPS,并将其源代码开源。然后又与 IETF 和 W3C 的相关标准机构合作,以确保行业达成共识。其中: Web Real-Time Communications (WEBRTC) W3C 组织:定义浏览…

Nginx的页面优化,安全优化,日志分割,配置防盗链,图片缓存,解决部分问题

一、隐藏版本号 他人可以使用调试代理工具&#xff08;fiddler工具&#xff09;、浏览器插件等&#xff0c;通过识别网站的响应头信息来获取你的 Nginx 版本号。为了增强服务器的安全和隐私&#xff0c;可以进行隐藏版本号&#xff0c;也可以在 nginx.h 文件中修改服务名称和版…

力扣同类题:重排链表

很明显做过一次 class Solution { public:void reorderList(ListNode* head) {if(!head||!head->next)return;ListNode *fasthead,*lowhead;ListNode *prenullptr,*curnullptr,*nextnullptr;while(fast->next!nullptr){fastfast->next;if(fast->next)fastfast->…

Yolov8-pose关键点检测:特征融合涨点篇 | 广义高效层聚合网络(GELAN) | YOLOv9

💡💡💡本文独家改进:即结合用梯度路径规划(CSPNet)和(ELAN)设计了一种广义的高效层聚合网络(GELAN),高效结合YOLOv8-pose,实现涨点。 将GELAN添加在backbone和head处,提供多个yaml改进方法 Yolov8-Pose关键点检测专栏介绍:https://blog.csdn.net/m0_6377421…

开源组件安全风险及应对

在软件开发的过程中&#xff0c;为了提升开发效率、软件质量和稳定性&#xff0c;并降低开发成本&#xff0c;使用开源组件是开发人员的不二选择&#xff08;实际上&#xff0c;所有软件开发技术的演进都是为了能够更短时间、更低成本地构建软件&#xff09;。这里的开源组件指…

2023年终总结——跌跌撞撞不断修正

目录 一、回顾1.一月&#xff0c;鼓足信心的开始2.二月&#xff0c;焦躁不安3.三月&#xff0c;路还是要一步一步的走4.四月&#xff0c;平平淡淡的前行5.五月&#xff0c;轰轰烈烈的前行6.六月&#xff0c;看事情更底层透彻了7.七月&#xff0c;设计模式升华月8.八月&#xff…

前端WebRTC局域网1V1视频通话

基本概念 WebRTC&#xff08;Web Real-Time Communications&#xff09; 网络实时通讯&#xff0c;它允许网络应用或者站点&#xff0c;在不借助中间媒介的情况下&#xff0c;建立点对点&#xff08;Peer-to-Peer&#xff09;的连接&#xff0c;实现视频流和音频流或者其他任…

智慧公厕_智慧化的公厕_智慧公厕系统_智慧公厕管理系统

一、什么是智慧公厕系统&#xff1f; 智慧公厕系统是一种利用物联网、互联网、大数据、云计算等前沿技术&#xff0c;将公共厕所信息化、数字化、智能化的系统。随着科技的进步&#xff0c;智慧公厕系统成为城市建设的一个重要部分&#xff0c;&#xff08;ZonTree中期科技&am…

软文营销的误区及提高推广效果的方法

传媒如春雨&#xff0c;润物细无声&#xff0c;大家好&#xff0c;我是51媒体网胡老师。 一&#xff0c;软文营销的五大误区 误区一&#xff1a;需要时才做推广 问题&#xff1a;许多企业在需要快速获得曝光或销售提升时才考虑软文营销&#xff0c;但这样零散的推广很难形成…

MySQL 的基础操作

数据库的基础操作 1. 库操作2. 表的操作3. 数据类型 数据库是现代应用程序中至关重要的组成部分&#xff0c;通过数据库管理系统&#xff08;DBMS&#xff09;存储和管理数据。 1. 库操作 创建数据库 创建数据库是开始使用数据库的第一步。下面是一些常见的创建数据库的示例&a…

深入了解二叉搜索树:原理、实现与应用

目录 一、介绍二叉搜索树 二、二叉搜索树的基本性质 三、二叉搜索树的实现 四、总结 在计算机科学中&#xff0c;数据结构是构建算法和程序的基础。其中&#xff0c;二叉搜索树&#xff08;Binary Search Tree&#xff0c;简称 BST&#xff09;作为一种常见的数据结构&#…