11- OpenCV:自定义线性滤波(卷积,卷积边缘)

目录

一、卷积

1、卷积概念

2、卷积如何工作

3、常见算子(卷积核 Kenel)

4、自定义卷积模糊

5、代码演示

二、卷积边缘

1、卷积边缘问题

2、处理边缘

3、相关的API说明

4、代码演示


一、卷积

1、卷积概念

(1)在OpenCV中,卷积是一种常用的图像处理操作,用于图像滤波、特征提取等任务。它基于滑动窗口的概念,通过将一个小的核Kenel(也称为滤波器)与图像进行逐像素的乘法和求和运算来实现。

— 卷积是图像处理中一个操作,是kernel在图像的每个像素上的操作。

— Kernel本质上一个固定大小的矩阵数组,其中心点称为锚点(anchor point)

(2)卷积操作可以理解为在图像上滑动一个小的核,并将核的每个元素与对应位置的图像像素值相乘,然后将所有乘积结果相加得到输出图像的对应像素值。这个过程可以简单地表示为:

output(x, y) = sum(kernel(i, j) * input(x+i, y+j))

其中,output(x, y)是输出图像的像素值,kernel(i, j)是核的元素值,input(x+i, y+j)是输入图像的像素值。

(3)卷积操作在图像处理中有多种应用,其中最常见的是图像滤波。通过选择不同的核,可以实现不同的滤波效果,例如平滑滤波、边缘检测等。卷积操作还可以用于图像特征提取,例如使用卷积神经网络(CNN)进行图像分类、目标检测等任务。

在OpenCV中,可以使用cv::filter2D函数来进行卷积操作。该函数接受输入图像、核以及输出图像作为参数,并将卷积结果存储在输出图像中。

2、卷积如何工作

把kernel放到像素数组之上,求锚点周围覆盖的像素乘积之和(包括锚点),用来替换锚点覆盖下像素点值称为卷积处理。数学表达如下

公式讲解:

K(i,j):卷积核的大小

I里面的参数就是窗口的半径

两个方向X、Y方向上的求和

例子:从左到右,从上到下进行计算

Sum = 8x1+6x1+6x1+2x1+8x1+6x1+2x1+2x1+8x1

New pixel = sum / (m*n)

3、常见算子(卷积核 Kenel)

(1)Robert算子:又称“梯度算子”

(2)Sobel算子:中间2*2,更大,比Robert算子的差异更大,效果可能更明显了

(3)拉普拉斯算子

4、自定义卷积模糊

(1)filter2D方法

filter2D (

Mat src, //输入图像

Mat dst, // 模糊图像

int depth, // 图像深度32/8,不知道的就默认-1,系统也默认和src的深度一样

Mat kernel, // 卷积核/模板

Point anchor = Point(-1,-1) , // 锚点位置,3、5、7、9,或者默认自动寻找中心位置

double delta = 0 // 计算出来的像素+delta

其中 kernel是可以自定义的卷积核

5、代码演示
#include <opencv2/opencv.hpp>
#include <iostream>
#include <math.h>using namespace cv;
int main(int argc, char** argv)
{Mat src, dst;int ksize = 0;src = imread("test.jpg");if (!src.data){printf("could not load image...\n");return -1;}char INPUT_WIN[] = "input image";char OUTPUT_WIN[] = "Custom Blur Filter Result";namedWindow(INPUT_WIN, CV_WINDOW_AUTOSIZE);namedWindow(OUTPUT_WIN, CV_WINDOW_AUTOSIZE);imshow(INPUT_WIN, src);// Robert 算子 X 方向//Mat Robert_x = (Mat_<int>(2, 2) << 1, 0, 0, -1);//Mat mat_Robert_x;//filter2D(src, mat_Robert_x, -1, Robert_x);//imshow("Robert x", mat_Robert_x);Robert 算子 Y 方向//Mat Robert_y = (Mat_<int>(2, 2) << 0, 1, -1, 0);//Mat mat_Robert_y;//filter2D(src, mat_Robert_y, -1, Robert_y);//imshow("Robert y", mat_Robert_y);// Sobel X 方向Mat kernel_x = (Mat_<int>(3, 3) << -1, 0, 1, -2, 0, 2, -1, 0, 1);filter2D(src, dst, -1, kernel_x, Point(-1, -1), 0.0);imshow("Sobel X", dst);// Sobel Y 方向Mat yimg;Mat kernel_y = (Mat_<int>(3, 3) << -1, -2, -1, 0, 0, 0, 1, 2, 1);filter2D(src, yimg, -1, kernel_y, Point(-1, -1), 0.0);imshow("Sobel Y", yimg);// 拉普拉斯算子//Mat kernel_y = (Mat_<int>(3, 3) << 0, -1, 0, -1, 4, -1, 0, -1, 0);//filter2D(src, dst, -1, kernel_y, Point(-1, -1), 0.0);//imshow("拉普拉斯", dst);waitKey(0);// 自定义卷积模糊//int c = 0;//int index = 0;//while (true)null//{//	c = waitKey(500);//	if ((char)c == 27) // ESC//	{ //		break;//	}//	ksize = 5 + (index % 8) * 2;//	Mat kernel = Mat::ones(Size(ksize, ksize), CV_32F) / (float)(ksize * ksize);//	filter2D(src, dst, -1, kernel, Point(-1, -1));//	index++;//	imshow(OUTPUT_WIN, dst);//}return 0;
}

效果展示:

(1)Robert算子,在X与Y方向上呈现出差异性

(2)Sobel算子:相对与Robert算子,差异会明显一些

(3)拉普拉斯算子:碎发也没看到了

二、卷积边缘

1、卷积边缘问题

卷积边缘问题:图像卷积的时候边界像素,不能被卷积操作。

原因:在于边界像素没有完全跟kernel重叠,所以当3x3滤波时候有1个像素的边缘没有被处理,5x5滤波的时候有2个像素的边缘没有被处理。

2、处理边缘

在卷积开始之前增加边缘像素,填充的像素值为0或者RGB黑色,比如3x3在 四周各填充1个像素的边缘,这样就确保图像的边缘被处理,在卷积处理之 后再去掉这些边缘。

openCV中默认的处理方法是: BORDER_DEFAULT,此外 常用的还有如下几种:

- BORDER_CONSTANT – 填充边缘用指定像素值  

- BORDER_REPLICATE – 填充边缘像素用已知的边缘像素值

- BORDER_WRAP – 用另外一边的像素来补偿填充

3、相关的API说明

给图像添加边缘API:copyMakeBorder

copyMakeBorder(  

- Mat src, // 输入图像  

- Mat dst, // 添加边缘图像  

- int top, // 边缘长度,一般上下左右都取相同值,

 - int bottom,  

- int left,  

- int right,  

- int borderType // 边缘类型  

- Scalar value

4、代码演示

增加边缘的四种策略,都适用于什么场景,如何处理卷积的边缘。

先认识下:GaussianBlur()

GaussianBlur函数用于对图像进行高斯模糊操作。它可以有效地去除图像中的噪声,并平滑图像的细节。

void GaussianBlur (

InputArray src, // 输入图像,可以是单通道或多通道图像

OutputArray dst, // 输出图像,与输入图像具有相同的尺寸和类型

Size ksize, // 高斯核的大小,用Size(w, h)表示。它必须是正奇数,例如(3, 3)、(5, 5)等。

double sigmaX, // 高斯核在X方向上的标准差

double sigmaY = 0, // 高斯核在Y方向上的标准差。如果为0,则默认使用sigmaX的值

int borderType = BORDER_DEFAULT // 边界处理方式,默认为BORDER_DEFAULT

);

int main(int argc, char** argv) 
{Mat src, dst;src = imread("test.jpg");if (!src.data) {printf("could not load image...\n");return -1;}char INPUT_WIN[] = "input image";char OUTPUT_WIN[] = "Border Demo";namedWindow(INPUT_WIN, CV_WINDOW_AUTOSIZE);namedWindow(OUTPUT_WIN, CV_WINDOW_AUTOSIZE);imshow(INPUT_WIN, src);/*int top = (int)(0.05*src.rows);int bottom = (int)(0.05*src.rows);int left = (int)(0.05*src.cols);int right = (int)(0.05*src.cols);RNG rng(12345);int borderType = BORDER_DEFAULT;int c = 0;while (true) {c = waitKey(500);// ESCif ((char)c == 27) break;if ((char)c == 'r') borderType = BORDER_REPLICATE;else if((char)c == 'w') borderType = BORDER_WRAP;else if((char)c == 'c') borderType = BORDER_CONSTANT;Scalar color = Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255));copyMakeBorder(src, dst, top, bottom, left, right, borderType, color);imshow(OUTPUT_WIN, dst);}*/// 上面的代码可以直接用下面接口替换GaussianBlur(src, dst, Size(5, 5), 0, 0);imshow(OUTPUT_WIN, dst);waitKey(0);return 0;
}

效果展示:

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

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

相关文章

生成当天递增唯一的流水号的几种方式

说明&#xff1a;当开发中&#xff0c;如交易、文件传输过程中的文件名&#xff0c;可能需要我们使用一串唯一的数字来锁定这一条“交互记录”&#xff0c;即流水号。 本文介绍几种生成6位递增唯一&#xff0c;且每日重置的流水号的方式。 方式一&#xff1a;使用Redis 我们…

SpringSecurity(11)——核心组件和认证流程

获取用户信息 // 获取安全上下文对象&#xff0c;就是那个保存在 ThreadLocal 里面的安全上下文对象 // 总是不为null(如果不存在&#xff0c;则创建一个authentication属性为null的empty安全上下文对象) SecurityContext securityContext SecurityContextHolder.getContext(…

微信轰炸-python实现方法

新手&#xff0c;一般都需要执行以下命令&#xff0c;用来导入对应模块 pip install -i Simple Index pynput 键盘winr进入输入cmd 执行该命令即可&#xff1a;pip install -i https://pypi.tuna.tsinghua.edu.cn/simple pynput 打开pycharm,输入代码如下 from pynput.keybo…

AI视频智能识别技术在智慧农业大棚升级改造管理场景中的应用方案

一、需求分析 随着科技的进步和农业现代化的推进&#xff0c;智能化技术逐渐成为现代农业发展的重要支撑。农业大棚作为现代农业的重要组成部分&#xff0c;其智能化改造对于提高农业生产效率、降低成本、增加收益具有重要意义。利用先进的信息化手段来对农业大棚进行管理&…

NOC总线(2)

1. NoC的路由 在NoC交换信息时&#xff0c;需要确定从源节点到目标节点所经过的路径&#xff0c;这时就需要路由算法来确定该路径。路由算法分为静态路由算法和动态路由算法两种。 静态路由算法对于两节点之间的路径是固定的&#xff0c;结构简单&#xff0c;便于硬件实…

【算法分析与设计】二叉树的层序遍历

&#x1f4dd;个人主页&#xff1a;五敷有你 &#x1f525;系列专栏&#xff1a;算法分析与设计 ⛺️稳中求进&#xff0c;晒太阳 题目 给你二叉树的根节点 root &#xff0c;返回其节点值的 层序遍历 。 &#xff08;即逐层地&#xff0c;从左到右访问所有节点&#xf…

idea插件开发

1&#xff0c; file-new project 如图&#xff0c;选择了安装路径&#xff0c;报错【select home directory for intellij platform plugin sdk】。&#xff08;注意是安装路径最外层的文件夹&#xff0c;不是里面的lib&#xff0c;jbr这一层级&#xff09; 2&#xff0c;点击了…

HTML前端CSS实现只显示1行或者2行、3行剩余显示省略号

想要做的效果: 文本只一行显示 /**实现思路&#xff1a;1.设置inline-block属相2.强制不换行3.固定高度4.隐藏超出部分5.显示“……”*/ {display: inline-block;white-space: nowrap; width: 100%; overflow: hidden;text-overflow:ellipsis; }文本只多行显示 /** 实现思路&…

【Java发送邮箱】spring boot 发送邮箱

导入依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-mail</artifactId> </dependency> 2.在properties配置邮箱 # 发件人QQ号 spring.mail.username2508575653qq.com # QQ邮箱授权码 sp…

xshell配置隧道转移规则

钢铁知识库&#xff0c;一个学习python爬虫、数据分析的知识库。人生苦短&#xff0c;快用python。 xshell是什么 通俗点说就是一款强大ssh远程软件&#xff0c;可以方便运维人员对服务器进行管理操作&#xff0c;功能很多朋友们自行探索&#xff0c;今天只聊其中一个功能点那…

HNU-数据挖掘-实验2-数据降维与可视化

数据挖掘课程实验实验2 数据降维与可视化 计科210X 甘晴void 202108010XXX 文章目录 数据挖掘课程实验<br>实验2 数据降维与可视化实验背景实验目标实验数据集说明实验参考步骤实验过程1.对数据进行初步降维2.使用无监督数据降维方法&#xff0c;比如PCA&#xff0c;I…

既是API调试平台也是自动化测试工具?Apipost

Apipost提供可视化的API自动化测试功能&#xff0c;使用Apipost研发人员可以设计、调试接口&#xff0c;测试人员可以基于同一数据源进行测试&#xff0c;Apipost 接口自动化功能在上次更新中进行了逻辑调整&#xff0c;带来更好的交互操作、更多的控制器选择&#xff0c;同时新…

SpringMvc中拦截器的配置及应用

拦截器原理 在 Spring MVC 中&#xff0c;拦截器&#xff08;Interceptor&#xff09;是一种机制&#xff0c;用于拦截请求并在处理程序&#xff08;Controller&#xff09;执行之前或之后执行一些操作。拦截器允许您在请求的不同阶段&#xff08;如处理程序执行前、处理程序执…

AI大模型中的Bert

1.全方位上下文理解&#xff1a;与以前的模型&#xff08;例如GPT&#xff09;相比&#xff0c;BERT能够双向理解上下文&#xff0c;即同时考虑一个词 的左边和右边的上下文。这种全方位的上下文理解使得BERT能够更好地理解语言&#xff0c;特别是在理解词义、 消歧等复杂任务上…

智慧安防GB28181视频监控EasyCVR v3.5系统增加录像保存地址的配置

智慧安防监控EasyCVR视频管理平台能在复杂的网络环境中&#xff0c;将前端设备统一集中接入。在网络传输上&#xff0c;平台支持设备通过4G、5G、WIFI、有线等方式进行视频流的快捷传输&#xff0c;视频流经平台处理后可对外进行多格式的分发&#xff0c;实现多展示终端观看&am…

消息中间件之Kafka(二)

1.Kafka线上常见问题 1.1 为什么要对topic下数据进行分区存储? 1.commit log文件会受到所在机器的文件系统大小的限制&#xff0c;分区之后可以将不同的分区放在不同的机器上&#xff0c; 相当于对数据做了分布式存储&#xff0c;理论上一个topic可以处理任意数量的数据2.提…

TCP高并发服务器简介(select、poll、epoll实现与区别)

select、poll、epoll三者的实现&#xff1a; select实现TCP高并发服务器的流程&#xff1a; 一、创建套接字&#xff08;socket函数&#xff09;&#xff1a;二、填充服务器的网络信息结构体&#xff1a;三、套接字和服务器的网络信息结构体进行绑定&#xff08;bind函数&…

大模型笔记【3】 gem5 运行模型框架LLama

一 LLama.cpp LLama.cpp 支持x86&#xff0c;arm&#xff0c;gpu的编译。 1. github 下载llama.cpp https://github.com/ggerganov/llama.cpp.git 2. gem5支持arm架构比较好&#xff0c;所以我们使用编译LLama.cpp。 以下是我对Makefile的修改 开始编译&#xff1a; make UNAME…

Kotlin协程的JVM实现源码分析(下)

协程 根据 是否保存切换 调用栈 &#xff0c;分为&#xff1a; 有栈协程&#xff08;stackful coroutine&#xff09;无栈协程&#xff08;stackless coroutine&#xff09; 在代码上的区别是&#xff1a;是否可在普通函数里调用&#xff0c;并暂停其执行。 Kotlin协程&…

【git分支管理策略】

文章目录 前言一、分支管理策略简介二、git基本操作三、git分支远程分支本地分支 四、gitflow分支管理策略分支定义gitflow分支管理策略评价 五、GITHUB FLOW分支管理策略分支使用流程创建分支&#xff08;Create a branch&#xff09;新增提交(add and commit)提出 Pull 请求&…