OpenCV filter2D函数详解

news2024/11/17 9:29:42

     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

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Spark编程基础】实验一Spark编程初级实践(附源代码)

文章目录 一、实验目的二、实验平台三、实验内容和要求1. 计算级数2. 模拟图形绘制3.统计学生成绩 一、实验目的 1.掌握 Scala 语言的基本语法、数据结构和控制结构&#xff1b; 2.掌握面向对象编程的基础知识&#xff0c;能够编写自定义类和特质&#xff1b; 3.掌握函数式编程…

vue3速查笔记

文章目录 一、创建Vue3.0工程1.使用 vue-cli 创建2.使用 vite 创建 二、常用 Composition API1.拉开序幕的setup2.ref函数3.reactive函数4.Vue3.0中的响应式原理vue2.x的响应式Vue3.0的响应式 5.reactive对比ref6.setup的两个注意点7.计算属性与监视1.computed函数2.watch函数3…

Windows电脑安装Linux(Ubuntu 22.04)系统(图文并茂)

Windows电脑安装Ubuntu 22.04系统&#xff0c;其它版本的Ubuntu安装方法相同 Ubuntu 16.04、Ubuntu 18.04安装方法相同&#xff0c;制作U盘启动项的镜像文件下载你需要的版本即可&#xff01; Ubuntu的中文官网网址&#xff1a;https://cn.ubuntu.com/&#xff0c;聪明的你一定…

【线程】封装 | 安全 | 互斥

线程封装&#xff08;面向对象&#xff09; 1.组件式的封装出一个线程类&#xff08;像C11线程库那样去管理线程&#xff09; 我们并不想暴露出线程创建&#xff0c;终止&#xff0c;等待&#xff0c;分离&#xff0c;获取线程id等POSIX线程库的接口&#xff0c;我们也想像C1…

IDEA管理Git + Gitee 常用操作

文章目录 IDEA管理Git Gitee 常用操作1.Gitee创建代码仓库1.创建仓库1.点击新建仓库2.完成仓库信息填写3.创建成功4.管理菜单可以修改这个项目的设置 2.设置SSH公钥免密登录基本介绍1.找到.ssh目录2.执行指令 ssh-keygen3.将公钥信息添加到码云账户1.点击设置2.ssh公钥3.复制.…

React-配置别名@

1.概念 说明&#xff1a;路径解析配置(webpack),把/解析为src/&#xff1b;路径联想配置(VsCode),VsCode在输入/时&#xff0c;自动联想出来对应的src/下的子级目录。CRA本身把webpacki配置包装到了黑盒里无法直接修改&#xff0c;需要借助一个插件-craco。 2.实现步骤 2.1安…

docker常用操作-docker私有仓库的搭建(Harbor),并将本地镜像推送至远程仓库中。

1、docker-compose安装&#xff0c;下载docker-compose的最新版本 第一步&#xff1a;创建docker-compose空白存放文件vi /usr/local/bin/docker-compose 第二步&#xff1a;使用curl命令在线下载&#xff0c;并制定写入路径 curl -L "https://github.com/docker/compos…

npm市场发布包步骤

1.打开npm官网npm官网 2.创建自己的账号 3.查看当前npm的镜像源&#xff0c; 如果出现淘宝的镜像源则需要切换成官方的镜像源 npm config get registry //查看镜像源 https://registry.npm.taobao.org/ //淘宝的镜像源 https://registry.npmjs.org/ //官方的镜像源 …

IPO[困难]

优质博文IT-BLOG-CN 一、题目 假设你的公司即将开始IPO。为了以更高的价格将股票卖给风险投资公司&#xff0c;你的公司希望在IPO之前开展一些项目以增加其资本。 由于资源有限&#xff0c;它只能在IPO之前完成最多k个不同的项目。帮助你的公司设计完成最多k个不同项目后得到最…

基于遗传算法GA的机器人栅格地图最短路径规划,可以自定义地图及起始点(提供MATLAB代码)

一、原理介绍 遗传算法是一种基于生物进化原理的优化算法&#xff0c;常用于求解复杂问题。在机器人栅格地图最短路径规划中&#xff0c;遗传算法可以用来寻找最优路径。 遗传算法的求解过程包括以下几个步骤&#xff1a; 1. 初始化种群&#xff1a;随机生成一组初始解&…

LC3014 输入单词需要的最少按键次数Ⅰ与方法内容的易读性

题目 刷题做到力扣 3014&#xff0c;题目要求设计电话键盘上的按键映射&#xff0c;返回按出 word 单词的最小按键次数&#xff0c;1 ≤ word.length ≤ 26&#xff0c;且仅由小写英文字母组成&#xff0c;所有字母互不相同 我的题解 简单题&#xff0c;略加思索拿下&#x…

给定l,r(1e18),定义f(x):x中最大的数位减去最小数位。对于l<=x<=r, 求f(x)最小值

题目 #include <bits/stdc.h> using namespace std; #define int long long #define pb push_back #define fi first #define se second #define lson p << 1 #define rson p << 1 | 1 const int maxn 1e6 5, inf 1e18, maxm 4e4 5, base 397; const i…

【JAVA】CSS3伸缩盒案例、响应式布局、BFC

1.CSS3伸缩盒案例 效果&#xff1a;用伸缩盒模型 <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Document</title>&…

Day33:安全开发-JavaEE应用SQL预编译Filter过滤器Listener监听器访问控制

目录 JavaEE-预编译-SQL JavaEE-过滤器-Filter JavaEE-监听器-Listen 思维导图 Java知识点 功能&#xff1a;数据库操作&#xff0c;文件操作&#xff0c;序列化数据&#xff0c;身份验证&#xff0c;框架开发&#xff0c;第三方库使用等. 框架库&#xff1a;MyBatis&#…

复合查询【MySQL】

文章目录 复合查询测试表 单表查询多表查询子查询单行子查询多行子查询IN 关键字ALL 关键字ANY 关键字 多列子查询 合并查询 复合查询 测试表 雇员信息表中包含三张表&#xff0c;分别是员工表&#xff08;emp&#xff09;、部门表&#xff08;dept&#xff09;和工资等级表&…

Python刘诗诗

写在前面 刘诗诗在电视剧《一念关山》中饰演了女主角任如意&#xff0c;这是一个极具魅力的女性角色&#xff0c;她既是一位有着高超武艺和智慧的女侠士&#xff0c;也曾经是安国朱衣卫前左使&#xff0c;身怀绝技且性格坚韧不屈。剧中&#xff0c;任如意因不满于朱衣卫的暴行…

Java多线程实战-实现多线程文件下载,支持断点续传、日志记录等功能

&#x1f3f7;️个人主页&#xff1a;牵着猫散步的鼠鼠 &#x1f3f7;️系列专栏&#xff1a;Java全栈-专栏 &#x1f3f7;️个人学习笔记&#xff0c;若有缺误&#xff0c;欢迎评论区指正 目录 前言 1 基础知识回顾 1.1 线程的创建和启动 1.2 线程池的使用 2.运行环境说…

JVM学习之常见知识点汇总、2024详细版面试问题汇总;JVM组成、类加载器、GC垃圾回收、堆、栈、方法区

目录 JVM组成 什么是程序计数器 详细的介绍一下Java的堆 什么是虚拟机栈 堆和栈的区别 堆空间的分配策略 对于方法区的解释 IO和NIO拷贝数据的对比 JVM内存结构 JVM去除永久代改用元空间替代的原因 类加载器 什么是类加载器&#xff0c;类加载器有哪些 什么是双亲…

吴恩达机器学习-可选实验室:可选实验:使用逻辑回归进行分类(Classification using Logistic Regression)

在本实验中&#xff0c;您将对比回归和分类。 import numpy as np %matplotlib widget import matplotlib.pyplot as plt from lab_utils_common import dlc, plot_data from plt_one_addpt_onclick import plt_one_addpt_onclick plt.style.use(./deeplearning.mplstyle)jupy…

计算机组成原理实验报告1 | 实验1.1 运算器实验(键盘方式)

本文整理自博主大学本科《计算机组成原理》课程自己完成的实验报告。 —— *实验环境为学校机房实验箱。 目录 一、实验目的 二、实验内容 三、实验步骤及实验结果 Ⅰ、单片机键盘操作方式实验 1、实验连线&#xff08;键盘实验&#xff09; 2、实验过程 四、实验结果的…