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 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);

	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 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);

	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 test
	Mat 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 kernel
	Mat 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 kernel
	Mat 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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

python爬虫(9)之requests模块

1、获取动态加载的数据 1、在开发者工具中查看动态数据 找到csdn的门户的开发者工具后到这一页面。 2、加载代码 import requests headers {User-Agent:Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36…

数据仓库为什么要分层建设?每一层的作用是什么?

在数字化时代&#xff0c;数据已成为企业最宝贵的资产之一。为了更好地管理和利用这些数据&#xff0c;许多企业都建立了数据仓库。然而&#xff0c;数据仓库并非简单的数据存储工具&#xff0c;而是一个复杂的数据处理和分析系统。其中&#xff0c;分层建设是数据仓库设计的重…

第六篇【传奇开心果系列】Python的自动化办公库技术点案例示例:大学生数据全方位分析挖掘经典案例

传奇开心果博文系列 系列博文目录Python的自动化办公库技术点案例示例系列 博文目录前言一、Pandas库全方位分析挖掘大学生数据能力介绍二、大学生学生成绩数据分析数据挖掘示例代码三、大学生选课数据分析数据挖掘示例代码四、大学生活动参与数据分析数据挖掘示例代码五、大学…

如何在 Azure 上备份 windows 虚拟机并恢复

起因 Azure 在 windows 虚拟机备份/还原上和通常的虚拟机备份有所区别&#xff0c;一般的虚拟机备份在控制台的上的操作通常是选择将目标虚拟机备份成镜像&#xff0c;还原的时候选择备份好的镜像即可。 但是对于 windows 虚拟机的备份/还原需要借助其磁盘进行操作。下面是操…

MySQL学习Day32——数据库备份与恢复

在任何数据库环境中&#xff0c;总会有不确定的意外情况发生&#xff0c;比如例外的停电、计算机系统中的各种软硬件故障、人为破坏、管理员误操作等是不可避免的&#xff0c;这些情况可能会导致数据的丢失、 服务器瘫痪等严重的后果。存在多个服务器时&#xff0c;会出现主从服…

【CSP试题回顾】201803-1-跳一跳

CSP-201803-1-跳一跳 解题代码 #include <iostream> using namespace std;int score, s, last_s -1;int main() {while (true){cin >> s;if (s 0) break;else if (s 1) {score s;last_s s;}else if (s 2) {if (last_s>2){score last_s;last_s 2;}else…

Controller Spawner couldn‘t find the expected controller_manager ROS interface.

rosservice list | grep controller_manager 如果没有输出&#xff0c;说明controllermanager没启动 具体通过以下启动&#xff1a; <gazebo> <plugin name"ros_control" filename"libgazebo_ros_control.so"> <!-- robotNamespace>…

Vue:内置组件:KeepAlive(缓存组件实例)

一、作用 <KeepAlive></KeepAlive>能缓存包裹的所有组件&#xff0c;保证组件在切换时维持组件状态。 默认情况下&#xff0c;一个组件实例在被替换掉后会被销毁。这会导致它丢失其中所有已变化的状态——当这个组件再一次被显示时&#xff0c;会创建一个只带有初…

深入学习React开发:从基础到实战

&#x1f482; 个人网站:【 海拥】【神级代码资源网站】【办公神器】&#x1f91f; 基于Web端打造的&#xff1a;&#x1f449;轻量化工具创作平台&#x1f485; 想寻找共同学习交流的小伙伴&#xff0c;请点击【全栈技术交流群】 引言 React是一款流行的JavaScript库&#xf…

EMC测试整改:优化电磁兼容性,提升产品质量?|深圳比创达电子EMC

在电子设备领域&#xff0c;电磁兼容性&#xff08;Electromagnetic Compatibility&#xff0c;简称EMC&#xff09;测试是确保产品在电磁环境下能够正常工作而不对周围环境和其他设备造成干扰的关键步骤。然而&#xff0c;即使通过了初步的EMC测试&#xff0c;仍然可能存在一些…

基于uniapp的新闻文章视频资讯系统 微信小程序

基于Android的视频资讯APP组织结构如下&#xff1a; 第一章系统概述&#xff0c;首先简单的阐述基于Android的视频资讯APP背景&#xff0c;分析基于Android的视频资讯APP的意义&#xff0c;说明基于Android的视频资讯APP的研究内容。 第二章技术介绍&#xff0c;介绍基于Androi…

4.MAC平台Python的下载、安装(含Python2.7+Python3.12双版本环境变量配置)——《跟老吕学Python编程》

4.MAC平台Python的下载、安装&#xff08;含Python2.7Python3.12双版本环境变量配置&#xff09;——《跟老吕学Python编程》&#xff09;——跟老吕学Python编程 一、下载MAC版Python1.Python官网2.MAC版Python下载网址 二、在MAC安装Python1.在MAC安装Python2.阅读Python重要…

每日学习笔记:C++ STL 的forward_list

定义 特点 操作函数 元素查找、移除或安插 forward_list::emplace_after arg...指的是元素构造函数的参数&#xff08;0~N个&#xff09; #include <iostream> #include <memory> #include <list> #include <forward_list> using namespace std;class…

SSA-LSTM多输入分类预测 | 樽海鞘优化算法-长短期神经网络 | Matlab

目录 一、程序及算法内容介绍&#xff1a; 基本内容&#xff1a; 亮点与优势&#xff1a; 二、实际运行效果&#xff1a; 三、算法介绍&#xff1a; 四、完整程序下载&#xff1a; 一、程序及算法内容介绍&#xff1a; 基本内容&#xff1a; 本代码基于Matlab平台编译&am…

《动手学深度学习》第2章 预备知识 部分笔记

文章目录 一、数据操作二、数据预处理1.函数&#xff08;1&#xff09;递归创建目录&#xff1a;os.makedirs()&#xff08;2&#xff09;读取CSV文件&#xff1a;pandas.read_csv()&#xff08;3&#xff09;合并路径&#xff1a;os.path.join()&#xff08;4&#xff09;按索…

stl--set和map使用技巧

文章目录 set使用场景&#xff1a;简单使用 map使用场景&#xff1a;简单实用 set 使用场景&#xff1a; 底层实现为红黑树&#xff0c;默认排序&#xff0c;适合搜索数组中的某一个元素使用。 简单使用 set<int> s1 {1,3,4,5};s1.insert(2);s1.erase(3);for(auto &…

用户视角的比特币和以太坊外围技术整理

1. 引言 要点&#xff1a; 比特币L2基本强调交易内容的隐蔽性&#xff0c;P2P交易&#xff08;尤其是支付&#xff09;成为主流&#xff0c;给用户带来一定负担&#xff08;闪电网络&#xff09;在以太坊 L2 中&#xff0c;一定程度上减少了交易的隐蔽性&#xff0c;主流是实…

手撕快速排序

定义 快速排序是Hoare于1962年提出的一种二叉树结构的交换排序方法. 其基本思想为:任取待排序的某个元素作为基准值,按照该排序码将待排序集合分割成两个子序列, 左子序列中所有元素均小于基准值,右子序列均大于基准值,然后左右子序列重复该过程,知道所有元素都有序为止. (核心…

unity3d Animal Controller的Animal组件中General基础部分理解

控制器介绍 动物脚本负责控制动物的所有运动逻辑.它管理所有的动画师和刚体参数,以及所有的状态和模式,动物可以做。 动物控制器 是一个动画框架控制器,根动或到位,为任何生物或人形。它利用刚体与物理世界的互动和动画师的玩动画。 States States 是不互相重叠的动画。例如…

C++ 矩形类

思维导图&#xff1a; #include <iostream> using namespace std; class Rect { private:int width;int height; public:void init(int w,int h){widthw;heighth;}void set_w(int w){widthw;}void set_h(int h){heighth;}void show(){cout << "perimeter &qu…