opencv#28 图像卷积

图像卷积

图像卷积是图像处理中最为基础的操作之一,其常用在图像的边缘检测,图像的去噪声以及图像压缩等领域。

图像卷积主要步骤:


Step1:将卷积模板旋转180°。

Step2:卷积模板移动到对应位置。

Step3:模板内求和,保存求和结果。

Step4:滑动卷积模板,处理所有结果。

  卷积函数在这里称卷积模板卷积模板通常是一个方形的卷积,同时也是一个奇数的卷积,卷积模板通常使用的是一个中心对称的形式。

  例如上图,在将模板旋转180°时,需要确定一个旋转中心,也就是我们卷积模板的中心,围绕这个中心旋转180°得到的结果便是我们需要进行卷积操作的结果。由于,我们常用的卷积模板是一个中心对称的模板,所以我们常看到在进行卷积时,无需进行180°的操作, 但是,我们要清楚,卷积首先重要的第一步是对模板进行旋转,否则,当我们使用非中心对称模板的时候,那么我们再对卷积模板进行旋转之后,得到的结果与原结果不一致,此时进行卷积旋转和不旋转的结果时不同的,之后将我们的模板移动到需要进行卷积图像或矩阵的对应位置,例如上图,我们将模板移动到像素值为7的中心区域上,我们将卷积模板完整覆盖在此区域上,第三步,将模板覆盖的区域与模板求和,首先是对应位置求乘积 ,也就是1*1+2*2+3*1....依次相乘再相加,得到的结果便是我们卷积之后的结果,将此结果替换掉原先待卷积矩阵中,这样得到的结果便是我们卷积之后的矩阵的结果。之后将卷积模板移动到下一位,也就是将中心位置覆盖在像素值为8的区域,继续对应位置相乘再相加得到的结果为96,这个96就替换掉原先图像中的8,依次运行下去,每一步都进行替换。   这里可以发现,在移动的时候,我们的中心像素只能覆盖我们原先像素的中心位置,其边缘位置是没有办法进行处理的,如上图,我们卷积后的结果只有中心3*3的像素进行了改变,而其他周围的像素是没有进行改变的,我们知道,对于图像来说,最边缘的一行和一列像素对图像整体的信息表达没有太多的作用,但是有的时候我们依然想得到一个边缘经过处理的结果,因此,我们将原图像边缘进行扩充一行一列像素,那么此时再进行卷积运算时,我们的卷积模板中心就可以覆盖在我们原图像中最边缘区域上,这样,我们可以在边缘上依次移动,得到结果,这里面对于边缘填充有很多种方法,例如,可以用全是0来填充,也可以复制最边缘的值进行填充。当我们的卷积模板为5*5的形式,那么我们对于边缘扩充就要两行两列,这样才能保证最边缘的图像能够被我的卷积模板中心所覆盖。

  可以发现,进行卷积后,像素值变得很大,扩大了很多倍数,若像素值是0~255之间,当中心像素为25时,可能计算结果就会超过最大值,那么就会影响卷积结果,因此在卷积操作的时候,我们还需要进行归一化的操作,就是将卷积模板进行归一化,将模板中每一个数除以模板中所有系数之和得到归一化后的结果,这样得到的结果就可以保证不会经过卷积后数值不会越界。

图像卷积函数

filter2D()

void cv::filter2D(InputArray   src,OutputArray  dst,int          ddepth,InputArray   kemel,Point        anchor = Point(-1,-1),double       deta = 0,int          borderType = BORDER_DEFAULT)

·src:输入图像。

·dst:输出图像,与输入图像具有相同的尺寸和通道数。(经过卷积后的图像,由于卷积运算可能会出现小数,因此输入和输出图像的数据类型可能会不同)

·ddepth:输出图像的数据类型(深度),根据输入图像的数据类型不同拥有不同的取值范围。(例如输入图像是8U形式,那么输出图像就可包含8U,但是若输入的是一个32F的形式,那么输出图像中就不可能包含8U形式,因为经过处理后得到的结果精度一定比没有经过处理的精度高。)

·kernel:卷积核(卷积模板),CV_32FC1(浮点类型单通道矩阵)类型的矩阵(通常矩阵形式是一个奇数的正方形矩阵)。

·anchor:内核的基准点(锚点),默认值(-1,-1)代表内核基准点位于kernel的中心位置。

·delta:偏值,在计算结果中加上偏值(默认情况下此值为0,也就是卷积后的结果是没有进行偏移的)。

·borderType:像素外推法选择标志(也就是对图像进行外围扩充的形式)。

在了解上函数后,发现并没有进行卷积模板的旋转,因此我们需要人在进行卷积函数时,人为旋转180°。

示例
#include <opencv2/opencv.hpp>
#include <iostream>using namespace cv; //opencv的命名空间
using namespace std;//主函数
int main()
{//待卷积矩阵uchar points[25] = { 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25 };Mat img(5, 5, CV_8UC1, points);//卷积模板(需要32FC1形式,所以要设置为float)Mat kernel = (Mat_<float>(3, 3) << 1, 2, 1,2, 0, 2,1, 2, 1);Mat kernel_norm = kernel / 12;//卷积模板归一化Mat result, result_norm; //未归一化的卷积结果和归一化的卷积结果filter2D(img, result, CV_32F, kernel, Point(-1, -1), 2, BORDER_CONSTANT);filter2D(img, result_norm, CV_32F, kernel_norm, Point(-1, -1), 2, BORDER_CONSTANT);cout << "result" << endl << result << endl;//图像卷积Mat lena = imread("E:/opencv/opencv-4.6.0-vc14_vc15/opencv/lenac.png");if (lena.empty()){cout << "请确认图像文件名称是否正确" << endl;return -1;}Mat lena_filter;filter2D(lena, lena_filter, -1, kernel_norm, Point(-1, -1), 2, BORDER_CONSTANT);imshow("lena_filter", lena_filter);waitKey(0);//等待函数用于显示图像return 0;}

运行程序后,发现图像卷积最大的作用是可以对图像进行模糊,模糊的作用可以减小噪声,同时也可以增加后续处理的精度,这里面虽然进行了边缘扩充,但是对于整个图像来说并没有影响我们观看图像所能获得的信息。

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

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

相关文章

美易官方:Brevan Howard首席经济学家对2024年美国经济衰退的预测

随着全球经济的波动&#xff0c;投资者对未来的经济走势越发关注。近日&#xff0c;对冲基金Brevan Howard的首席经济学家发出预警&#xff0c;预计2024年美国经济将出现衰退。这一预言无疑给正在寻求投资机会和策略的个人和机构投资者敲响了警钟。在这样的大环境下&#xff0c…

容器技术2-镜像与容器储存

目录 一、镜像制作 1、ddocker build 2、docker commit 二、镜像存储 1、公共仓库 2、私有仓库 三、镜像使用 四、容器存储 1、镜像元数据 2、存储驱动 3、数据卷 一、镜像制作 1、ddocker build 基于 Dockerfile 自动构建镜像 其机制为&#xff1a;每一行都会基于…

<C++>STL->string

string类的由来 这是string的定义&#xff1a; string类是模板实例化后的别名&#xff0c;basic_string是字符串类模板&#xff0c;常见的字符串类型有wchar_t char char16_t char32_t &#xff0c;basic_string类针对的是所有字符串类型设计出来的一个模板&#xff0c;而我…

《幻兽帕鲁》服务器该如何选购

幻兽帕鲁作为目前火爆的一款游戏&#xff0c;幻兽帕鲁的服务器要能够承受其强大的力量和能力&#xff0c;需要具备一定的配置和性能。因此针对<幻兽帕鲁>这款游戏我们来总结一些可能用于承载幻兽帕鲁的服务器类型: 高性能服务器:幻兽帕鲁的能力强大&#xff0c;可能需要…

JavaScript 遍历数组的几种方式

文章目录 创建数组获取数组的长度遍历数组使用普通for循环来遍历数组使用ES5 for in循环使用ES6 for of循环使用forEach来进行迭代箭头函数测试遍历数组 创建数组 括号内的数字是数组的长度 let ar new Array(4) //向数组添加元素 ar[0] 100 ar[1] true ar[2] etoak ar[3…

嵌入式培训机构四个月实训课程笔记(完整版)-C++和QT编程第五天-Qt编程技巧若干解答(物联技术666)

链接&#xff1a;https://pan.baidu.com/s/1-u7GvgM0TLuiy9z7LYQ80Q?pwd1688 提取码&#xff1a;1688 QT在Windows下制作图表 QT是跨平台的程序设计库&#xff0c;在windows下的程序往往想要有一个好看的图标&#xff0c;方法如下&#xff1a; 1.准备个ICO图标。例如&…

Elasticsearch基础篇(八):常用查询以及使用Java Api Client进行检索

ES常用查询以及使用Java Api Client进行检索 1. 检索需求 参照豆瓣阅读的列表页面 需求&#xff1a; 检索词需要在数据库中的题名、作者和摘要字段进行检索并进行高亮标红返回的检索结果需要根据综合、热度最高、最近更新、销量最高、好评最多进行排序分页数量为10&#xf…

flutter设置windows是否显示标题栏和状态栏和全屏显示

想要让桌面软件实现全屏和不显示状态栏或者自定义状态栏&#xff0c;就可以使用window_manager这个依赖库&#xff0c;使用起来还是非常方便的&#xff0c;可以自定义显示窗口大小和位置&#xff0c;还有设置标题栏是否展示等内容&#xff0c;也可以设置可拖动区域。官方仓库地…

OpenHarmony当前进展和未来趋势

操作系统自20世纪50年代诞生&#xff0c;经历了从专用操作系统到通用操作系统的转变。整体可以将操作系统的发展历史分为3个阶段&#xff1a;PC时代、移动互联网时代、万物互联时代。 PC时代主要以计算机为主&#xff0c;用户规模从1970年的10亿增长到1990年的30亿。这一时代诞…

一些aarch64 pwn

从x86_64过来&#xff0c;把这个看完&#xff0c;arm-aarch64基本上心里有底了&#xff0c;讲的蛮好的 https://xz.aliyun.com/t/3154 一些汇编指令和示例 https://zhuanlan.zhihu.com/p/673591189 https://liujiaboy.github.io/2021/04/13/%E9%80%86%E5%90%91/ARM%E6%B1%87%E…

Nginx之Centos7安装及配置代理多个后端服务

Nginx之Centos7安装 文章目录 Nginx之Centos7安装1. 离线安装1. 下载2.安装依赖3. 编译并安装4. 启动5. 访问6. 访问出现403问题处理7. 80端口代理多个后端服务 2. Nginx常用命令 1. 离线安装 1. 下载 官网地址&#xff1a;http://nginx.org/ 本文下载的是nginx-1.21.1.tar.…

淘客返利系统自动赚佣金机器人深度解析

淘客返利系统自动赚佣金机器人深度解析 大家好&#xff0c;我是免费搭建查券返利机器人赚佣金就用微赚淘客系统3.0的小编&#xff0c;也是冬天不穿秋裤&#xff0c;天冷也要风度的程序猿&#xff01;今天&#xff0c;让我们一同深度解析淘客返利系统中的自动赚佣金机器人&…

鸿蒙原生应用/元服务实战-DevEco Studio 模拟器资源经常不足

DevEco Studio 模拟器资源经常不足&#xff0c;模拟器是最方便和最广泛的开发者可以快速体验应用元服务效果的途径&#xff0c;还是要加强。 除了Wearable,其他都用不了。 只能用预览器看效果&#xff0c;或者使用远程真机或者本地真机了。 在API9&#xff0c;比如分享等&…

数据结构-学习笔记

注意&#xff1a;该文章摘抄之百度&#xff0c;仅当做学习笔记供小白使用&#xff0c;若侵权请联系删除&#xff01; 什么是数据结构&#xff1f; 数据结构是计算机存储、组织数据的方式。 数据结构是指相互之间存在一种或多种特定关系的数据元素的集合。 结构包括逻辑结构和物…

php 文件移动、拷贝和删除

目录 1.rename 2.copy 3.unlink 1.rename rename(旧名, 新名); //重命名 <?php header("Content-Type: text/html; charsetutf-8");$a dirname(__FILE__);//获取当前文件绝对路径的目录$ret rename($a.\\test2.txt, $a.\\test.txt);//将test2.txt改名为test.…

leetcode第 381 场周赛最后一题 差分,对称的处理

第 381 场周赛 - 力扣&#xff08;LeetCode&#xff09;最后一题3017. 按距离统计房屋对数目 II - 力扣&#xff08;LeetCode&#xff09; dijkstra超时了&#xff0c;看了灵神的解题方法力扣&#xff08;LeetCode&#xff09;官网 - 全球极客挚爱的技术成长平台&#xff0c;其…

二.用户与权限管理(二)

用户与权限管理 5.角色管理5.1角色的理解5.2创建角色5.3给角色赋予权限5.4查看角色的权限5.5回收角色的权限5.6删除角色5.7给用户赋予角色5.8激活角色5.9撤销用户角色5.10设置强制角色(mandatory role) 6.配置文件的使用6.1配置文件格式6.2 启动命令与选项组6.3 特定MySQL版本的…

【笔记】Helm-3 主题-10 Kubernetes分发指南

Kubernetes分发指南 Helm应该适用于任何 符合标准的Kubernetes版本 &#xff08;无论是否经过 认证 &#xff09;。 https://github.com/cncf/k8s-conformance Certified Kubernetes Software Conformance | CNCF 该文档捕获在特定Kubernetes环境中使用Helm的有关信息。如果…

java数组ArrayList(存对象)

1、dade文件 package model;public class dade {private int id;private String name;public dade() {}public dade(int id, String name) {this.id id;this.name name;}public int getId() {return id;}public void setId(int id) {this.id id;}public String getName() {…

推荐IDEA一个小插件,实用性很高!!

插件&#xff1a; Convert YAML and Properties File 由于每个人的开发习惯不同&#xff0c;在开发过程中会遇到各种小细节的问题。今天给大家介绍一个小插件&#xff0c;作用不大&#xff0c;细节很足。 就是properties类型文件和yml文件互相自由转换 解决&#xff1a;…