二阶微分算子-拉普拉斯算子
在前面博客结尾,我们简要谈了一下二阶微分算子;对于图像;
从上面可以看出
一阶微分算子,就是求图像灰度变化曲线的导数,能够突出图像中的对象边缘;二阶微分算子,求图像灰度变化导数的导数,对图像中灰度变化强烈的地方很敏感,从而可以突出图像的纹理结构下面介绍几个常见二阶微分算子: 其模板为:
图(a)表示离散拉普拉斯算子的模板,图(b)表示其扩展模板,图(c)(d)则分别表示其他两种拉普拉斯的实现模板。从模板形式容易看出,如果在图像中一个较暗的区域中出现了一个亮点,那么用拉普拉斯运算就会使这个亮点变得更亮。因为图像中的边缘就是那些灰度发生跳变的区域,所以拉普拉斯锐化模板在边缘检测中很有用。一般增强技术对于陡峭的边缘和缓慢变化的边缘很难确定其边缘线的位置。但此算子却可用二次微分正峰和负峰之间的过零点来确定,对孤立点或端点更为敏感,因此特别适用于以突出图像中的孤立点、孤立线或线端点为目的的场合。同梯度算子一样,拉普拉斯算子也会增强图像中的噪声,有时用拉普拉斯算子进行边缘检测时,可将图像先进行平滑处理。
图像锐化处理的作用是使灰度反差增强,从而使模糊图像变得更加清晰。图像模糊的实质就是图像受到平均运算或积分运算,因此可以对图像进行逆运算,如微分运算能够突出图像细节,使图像变得更为清晰。由于拉普拉斯是一种微分算子,它的应用可增强图像中灰度突变的区域,减弱灰度的缓慢变化区域。因此,锐化处理可选择拉普拉斯算子对原图像进行处理,产生描述灰度突变的图像,再将拉普拉斯图像与原始图像叠加而产生锐化图像。拉普拉斯锐化的基本方法可以由下式表示:
这种简单的锐化方法既可以产生拉普拉斯锐化处理的效果,同时又能保留背景信息,将原始图像叠加到拉普拉斯变换的处理结果中去,可以使图像中的各灰度值得到保留,使灰度突变处的对比度得到增强,最终结果是在保留图像背景的前提下,突现出图像中小的细节信息。
下面实现简单的图像锐化,并调用函数实现边缘检测;
#include <opencv2/opencv.hpp> #include <iostream>using namespace cv; using namespace std;//手动实现拉普拉斯算子图像锐化 void sharpenImage1(const Mat &image, Mat &result) {result.create(image.size(), image.type());//为输出图像分配内容 /*拉普拉斯滤波核3*30 -1 0-1 5 -10 -1 0 *///处理除最外围一圈外的所有像素值 for (int i = 1; i<image.rows - 1; i++){const uchar * pre = image.ptr<const uchar>(i - 1);//前一行 const uchar * cur = image.ptr<const uchar>(i);//当前行,第i行 const uchar * next = image.ptr<const uchar>(i + 1);//下一行 uchar * output = result.ptr<uchar>(i);//输出图像的第i行 int ch = image.channels();//通道个数 int startCol = ch;//每一行的开始处理点 int endCol = (image.cols - 1)* ch;//每一行的处理结束点 for (int j = startCol; j < endCol; j++){ //输出图像的遍历指针与当前行的指针同步递增, 以每行的每一个像素点的每一个通道值为一个递增量, 因为要考虑到图像的通道数 //saturate_cast<uchar>保证结果在uchar范围内 *output++ = saturate_cast<uchar>(5 * cur[j] - pre[j] - next[j] - cur[j - ch] - cur[j + ch]);}}//将最外围一圈的像素值设为0 result.row(0).setTo(Scalar(0));result.row(result.rows - 1).setTo(Scalar(0));result.col(0).setTo(Scalar(0));result.col(result.cols - 1).setTo(Scalar(0));/*/或者也可以尝试将最外围一圈设置为原图的像素值image.row(0).copyTo(result.row(0));image.row(image.rows-1).copyTo(result.row(result.rows-1));image.col(0).copyTo(result.col(0));image.col(image.cols-1).copyTo(result.col(result.cols-1));*/ }//调用OpenCV函数实现拉普拉斯算子图像锐化 void sharpenImage2(const Mat &image, Mat &result) {Mat kernel = (Mat_<float>(3, 3) << 0, -1, 0, -1, 5, -1, 0, -1, 0);filter2D(image, result, image.depth(), kernel); }//main函数 void main() {Mat mat = imread("E:\\VS2015Opencv\\vs2015\\project\\picture\\01.jpg");Mat result1;Mat result2;Mat dst, gray;sharpenImage1(mat, result1);sharpenImage2(mat, result2);//滤波降噪GaussianBlur(mat, mat, Size(3, 3), 0, 0, BORDER_DEFAULT);//转成灰度图 cvtColor(mat, gray, COLOR_BGR2GRAY);//运行Sobel算子,得到边缘//求x方向梯度//Laplacian(src, dst, CV_16S, 3, 1,0,BORDER_DEFAULT);Laplacian(mat, dst, CV_16S);//后几个参数有默认值//由于是16位图片,需要将图片转化成为8位图形进行显示 convertScaleAbs(dst, dst);imshow("调函数检测边缘", dst);namedWindow("src");namedWindow("手动实现");namedWindow("opencv实现");imshow("src", mat);imshow("手动实现", result1);imshow("opencv实现", result2);waitKey(0); }
简单介绍一下自带函数:
使用拉普拉斯进行图像锐化可参考博文:https://www.cnblogs.com/liu-jun/archive/2012/08/12/2635373.html
在前面,我们谈到拉普莱斯变化有4个模板,我们一一实现,看看具体的情况
#include <opencv2/opencv.hpp> #include <iostream>using namespace cv; using namespace std;//调用OpenV函数实现拉普拉斯算子图像锐化 /*拉普拉斯滤波核3*3 0 -1 0 -1 5 -1 0 -1 0 */ void LA(const Mat &image, Mat &result) {Mat kernel = (Mat_<float>(3, 3) << 0, -1, 0, -1, 5, -1, 0, -1, 0);filter2D(image, result, image.depth(), kernel); }/*拉普拉斯滤波核3*3 0 -1 0 -1 4 -1 0 -1 0 */ void LB(const Mat &image, Mat &result) {Mat kernel = (Mat_<float>(3, 3) << 0, -1, 0, -1, 4, -1, 0, -1, 0);filter2D(image, result, image.depth(), kernel); } /*拉普拉斯滤波核3*3 0 1 0 1 -4 1 0 1 0 */ void LC(const Mat &image, Mat &result) {Mat kernel = (Mat_<float>(3, 3) << 0, 1, 0, 1, -4, 1, 0, 1, 0);filter2D(image, result, image.depth(), kernel); }/*拉普拉斯滤波核3*3 1 1 1 1 -8 1 1 1 1 */ void LD(const Mat &image, Mat &result) {Mat kernel = (Mat_<float>(3, 3) << 1, 1, 1, 1, -8, 1, 1, 1, 1);filter2D(image, result, image.depth(), kernel); }/*拉普拉斯滤波核3*3 -1 -1 -1 -1 8 -1 -1 -1 -1 */ void LE(const Mat &image, Mat &result) {Mat kernel = (Mat_<float>(3, 3) << -1, -1, -1, -1, 8, -1, -1, -1, -1);filter2D(image, result, image.depth(), kernel); } //main函数 void main() {Mat mat = imread("E:\\VS2015Opencv\\vs2015\\project\\picture\\01.jpg");Mat result1, A1, A2, A3;Mat result2;Mat dst, gray;//滤波降噪GaussianBlur(mat, mat, Size(3, 3), 0, 0, BORDER_DEFAULT);LA(mat, result1);LB(mat, A1);LC(mat, A2);LD(mat, A3);LE(mat, result2);//转成灰度图 cvtColor(mat, gray, COLOR_BGR2GRAY);//运行Sobel算子,得到边缘//求x方向梯度//Laplacian(src, dst, CV_16S, 3, 1,0,BORDER_DEFAULT);Laplacian(mat, dst, CV_16S);//后几个参数有默认值//由于是16位图片,需要将图片转化成为8位图形进行显示 convertScaleAbs(dst, dst);imshow("调函数检测边缘", dst);namedWindow("src");imshow("src", mat);imshow("LA", result1);imshow("LB", A1);imshow("LC", A2);imshow("LC", A3);imshow("LD", result2);waitKey(0); }
发现不同的模板,结果也不同。
转载于:https://www.cnblogs.com/fcfc940503/p/11294874.html
二阶微分算子-拉普拉斯算子相关推荐
- OpenCV(十六)边缘检测2 -- Laplace(拉普拉斯)二阶微分算子
目录 一.基础理论 1.原理 2.过程 3.Laplacian函数 代码 效果 参考资料 一.基础理论 1.原理 Laplace算子作为边缘检测之一,和Sobel算子一样也是工程数学中常用的一种积分变 ...
- python 拉普拉斯锐化_(二十四)用二阶微分(拉普拉斯算子)实现图像锐化
时间为友,记录点滴. 我们已经了解过了梯度(一阶微分)的作用,那么为什么要引入二阶微分呢?二阶微分的作用是什么? 还是看图说话: 很明显,一阶微分已经可以把轮廓辨识出来,但是,对于变化较缓的地方,一阶 ...
- matlab拉普拉斯算子边缘提取_(二十四)用二阶微分(拉普拉斯算子)实现图像锐化...
时间为友,记录点滴. 我们已经了解过了梯度(一阶微分)的作用,那么为什么要引入二阶微分呢? 二阶微分的作用是什么? 还是看图说话: 很明显,一阶微分已经可以把轮廓辨识出来,但是,对于变化较缓的地方,一 ...
- 用图直观上理解梯度算子(一阶)与拉普拉斯算子(二阶)的区别,线检测与边缘检测的区别
梯度算子(一阶)与拉普拉斯算子(二阶)的区别 下面都是针对上图进行处理 取90度方向的梯度算子和拉普拉斯算子,以下为在空间域中的核 拉普拉斯算子(二阶) [−12−1−12−1−12−1]\left[ ...
- 边缘检测:Sobel、拉普拉斯算子
边缘 边缘(edge)是指图像局部强度变化最显著的部分.主要存在于目标与目标.目标与背景.区域与区域(包括不同色彩)之间,是图像分割.纹理特征和形状特征等图像分析的重要基础. 图像强度的显著变化可分为 ...
- 空间滤波_第三章 灰度变换与空间滤波-(六)锐化空间滤波器之拉普拉斯算子...
我们知道的东西是有限的,我们不知道的东西则是无穷的.----拉普拉斯 普拉斯算子 既然我们知道了二阶微分是对图像锐化处理的一大利器,我们本节就来讨论二阶微分在数字图像领域的实际应用. 拉普拉斯在就为我 ...
- 梯度与散度与拉普拉斯算子
梯度(矢量) 梯度的本意是一个向量(矢量),表示某一函数在该点处的方向导数沿着该方向取得最大值,即函数在该点处沿着该方向(此梯度的方向)变化最快,变化率最大(为该梯度的模) 假设一个三元函数 在空间 ...
- 图像的拉普拉斯算子之c++实现(qt + 不调包)
1.基本原理 拉普拉斯算子为二阶微分算子, 可转换成公式: 1.一般应用的时候,会涉及到正相拉普拉斯模板和反相拉普拉斯模板 2.拉普拉斯素描 第一步:用正相拉普拉斯模板求边缘 第二步:去除 ...
- 拉普拉斯矩阵 拉普拉斯算子 图论
图函数 我们知道,互相连接的节点可以构成一个图,其中包含所有节点构成的集合V,和所有边构成的集合E. 对于实数域上的函数y=f(x)y=f(x)y=f(x), 我们可以理解为一种对于x的映射,将每个可 ...
最新文章
- iOS视图控制器之间delegate传值
- 网站内页权重高于首页的原因及解决方法攻略总结!
- 更新版vimrc(java自动补全)
- IP地址修改后ORACLE不能使用问题
- 操作系统(十六)调度算法(一)
- 连接mysql报zone时区错误
- python访问序列元素的编号用什么括起来_python-重新编号数组中元素的有效方法...
- 语法手册_程序员必备——SQL语法速成手册
- 小新pro13 重装注意_新款小新pro 13注意什么?买前必读
- ubuntu10.10和windows双系统启动顺序的修改(转)
- C# 中 动态获得或设置一个对象的值
- 线程--匿名内部类实现多线程的2种方式
- 统计各种字符数量(包括汉字)
- pythonidle是什么_Python入门 | IDLE的介绍和使用方法
- 大量数据导出Excel 之 多重影分身之术 [转]
- 详解ip地址和mac地址即ARP协议
- mysql is running but_MySQL: mysql is not running but lock exists 的解决方法
- python微信聊天
- 跨境电商遭遇美国TRO,账户资金被冻结,以下几点您需要知道
- 《程序员的自我修养—链接、装载与库》pdf书签,目录分享