当前位置: 首页 > news >正文

【OpenCV C++20 学习笔记】拉普拉斯(Laplace)二阶求导-边缘检测

拉普拉斯二阶求导

  • 原理
    • 拉普拉斯算子(Laplacian Operator)
  • API
  • 实例

原理

在OpenCV中,Sobel算法可以对图片中的值求一阶导数,从而计算出图片中的边缘线。其原理如下面的示意图:
Sobel求导示意图
那么,如果再求一次导数的,即求二阶导数,其实也可以找出这个颜色值显著变化的分界点:
Laplace二阶求导示意图
可以看到,现在颜色值显著变化的位置,其导数值为0.
但是这有一个问题,就是二阶导数为0的也可以是一些无意义的值。所以,必须要进行一些过滤。

拉普拉斯算子(Laplacian Operator)

拉普拉斯算子的算法公式定义如下:
L a p l a c e ( f ) = ∂ 2 f ∂ x 2 + ∂ 2 f ∂ y 2 Laplace(f) = \frac{\partial^2f}{\partial x^2} + \frac{\partial^2f}{\partial y^2} Laplace(f)=x22f+y22f
可以看到拉普拉斯算法可以同时对两个维度进行求导,这是它相对于Sobel算法的优势。但是由于拉普拉斯算法还是要求斜率,所以其内部仍然调用了Sobel算法。

API

在OpenCV中,使用Laplacian()函数来进行拉普拉斯计算,其函数原型如下:

void cv::Laplacian(	InputArray	src,							//输入图OutputArray	dst,							//输出图int			ddepth,							//输出的数据类型,-1表示与输入图一致int			ksize = 1,						//卷积核尺寸,必须是正奇数double		scale =1,						//计算结果的放大系数,默认为1,即不放大double		delta = 0,						//计算结果的偏移值,默认为0,即不偏移int			borderType = BORDER_DEFAULT)	//图像边缘的扩充方式,默认为镜像复制
  • ksize = 1时,使用一个 3 × 3 3 \times 3 3×3的卷积核,如下:
    [ 0 1 0 1 − 4 1 0 1 0 ] \begin{bmatrix} 0 & 1 & 0 \\ 1 & -4 & 1 \\ 0 & 1 & 0 \end{bmatrix} 010141010

实例

在进行拉普拉斯求导之前也要进行滤波和灰度化,以去除噪音。
这里我们将拉普拉斯计算的结果中的数据类型定义为CV_16S,是为了防止溢出。接着又通过convertScaleAbs()函数转换回了CV_8U类型。
完整代码如下:

#include <opencv2/imgproc.hpp>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/highgui.hpp>using namespace cv;int main() {Mat src{ imread("lena.jpg") };//高斯滤波Mat blured;GaussianBlur(src, blured, Size(3, 3), 0, 0, BORDER_DEFAULT);//灰度化Mat gray;cvtColor(blured, gray, COLOR_BGR2GRAY);//拉普拉斯Mat dst;Laplacian(gray, dst, CV_16S, 3, 1, 0, BORDER_DEFAULT);//转换为CV_8UMat abs_dst;convertScaleAbs(dst, abs_dst);imshow("原图", src);imshow("Laplace", abs_dst);waitKey(0);
}

运行结果如下:
拉普拉斯运算结果

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 【游戏引擎之路】登神长阶(九)——《3D游戏编程大师技巧》:我想成为游戏之神!
  • 【JavaEE精炼宝库】网络原理基础——UDP详解
  • QT实现一个系统参数管理窗口
  • 深入理解单元测试与JUnit:从基础概念到实践操作
  • 计算机网络408考研 2014
  • 解密RCE漏洞:原理剖析、复现与代码审计实战
  • Android.mk(TODO)
  • 秋招复习笔记——八股文部分:网络IP
  • 09.XSS跨站脚本攻击(超详细!!!)
  • 充电不再难,高质量充电体系‘智’领绿色出行新时代
  • Mathtype安装教程/常见使用问题及快捷键大全
  • linux 011 注释13:缺页中断,新设计艺术团队第二版,第四章 4-39 至 4-
  • 大学生实验报告模板分享
  • java关于前端传布尔值后端接收一直为false问题
  • 公交车辆4G无线视频监控系统应用解决方案(视频监控统一接入平台)
  • Docker入门(二) - Dockerfile
  • Github访问慢解决办法
  • hadoop入门学习教程--DKHadoop完整安装步骤
  • js学习笔记
  • SAP云平台运行环境Cloud Foundry和Neo的区别
  • UEditor初始化失败(实例已存在,但视图未渲染出来,单页化)
  • v-if和v-for连用出现的问题
  • vue学习系列(二)vue-cli
  • 从零开始在ubuntu上搭建node开发环境
  • 动态魔术使用DBMS_SQL
  • 基于Android乐音识别(2)
  • 计算机常识 - 收藏集 - 掘金
  • 前端技术周刊 2019-02-11 Serverless
  • 人脸识别最新开发经验demo
  • 什么是Javascript函数节流?
  • 使用putty远程连接linux
  • 双管齐下,VMware的容器新战略
  •  一套莫尔斯电报听写、翻译系统
  • 正则表达式
  • raise 与 raise ... from 的区别
  • zabbix3.2监控linux磁盘IO
  • 我们雇佣了一只大猴子...
  • ​LeetCode解法汇总1410. HTML 实体解析器
  • ​探讨元宇宙和VR虚拟现实之间的区别​
  • # 数论-逆元
  • #define、const、typedef的差别
  • (7) cmake 编译C++程序(二)
  • (8)Linux使用C语言读取proc/stat等cpu使用数据
  • (ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_READ_ONLY)讲解
  • (二)构建dubbo分布式平台-平台功能导图
  • (十六)串口UART
  • (四)图像的%2线性拉伸
  • (一)使用Mybatis实现在student数据库中插入一个学生信息
  • (转)iOS字体
  • .MSSQLSERVER 导入导出 命令集--堪称经典,值得借鉴!
  • .NET C# 使用GDAL读取FileGDB要素类
  • .NET Micro Framework初体验(二)
  • .net SqlSugarHelper
  • .net 提取注释生成API文档 帮助文档
  • .NET/C# 在代码中测量代码执行耗时的建议(比较系统性能计数器和系统时间)