Laplace(拉普拉斯)算子
【摘要】
Laplace算子作为边缘检测之一,和Sobel算子一样也是工程数学中常用的一种积分变换,属于空间锐化滤波操作。拉普拉斯算子(Laplace Operator)是n维欧几里德空间中的一个二阶微分算子,定义为梯度(▽f)的散度(▽·f)。拉普拉斯算子也可以推广为定义在黎曼流形上的椭圆型算子,称为拉普拉斯-贝尔特拉米算子。(百度百科)
【原理】
拉普拉斯算子是二阶微分线性算子,在图像边缘处理中,二阶微分的边缘定位能力更强,锐化效果更好,因此在进行图像边缘处理时,直接采用二阶微分算子而不使用一阶微分。
图1 一阶微分和二阶微分计算图
离散函数的导数退化成了差分,一维一阶差分公式和二阶差分公式分别为:如图2所示
图2 一阶微分和二阶微分计算
分别对Laplace算子x,y两个方向的二阶导数进行差分就得到了离散函数的Laplace算子。在一个二维函数f(x,y)中,x,y两个方向的二阶差分分别为:如图3所示
图3 x,y两个方向的二阶差分
所以Laplace算子的差分形式为:
写成filter mask的形式如下:
该mask的特点,mask在上下左右四个90度的方向上结果相同,也就是说在90度方向上无方向性。为了让该mask在45度的方向上也具有该性质,对该filter mask进行扩展定义为
将Laplace算子写成filter mask后,其操作大同小异于其他的空间滤波操作。将filter mask在原图上逐行移动,然后mask中数值与其重合的像素相乘后求和,赋给与mask中心重合的像素,对图像的第一,和最后的行和列无法做上述操作的像素赋值零,就得到了拉普拉斯操作结果。因为Laplace算子是二阶导数操作,其在强调图像素中灰度不连续的部分的同时也不在强调灰度值连续的部分。这样会产生一个具有很明显的灰度边界,但是没有足够特征的黑色背景。背景特征可以通过原图像与Laplace算子操作后的图像混合恢复。用公式。
【C++代码】

// MyLaplace.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" #include <opencv2/opencv.hpp> #include <opencv2/core.hpp> using namespace std; using namespace cv; //**********************// //Laplacian mask operation //**********************// void Lmaskoperation(int* table, int* arr, int l) { int tmp[9] = { -1,-1,-1,-1,8,-1,-1,-1,-1 }; for (int i = 0; i<9; i++) { table[l] = table[l] + tmp[i] * arr[i]; } } //*****************************// //scale the pixels to [0 255] //*****************************// void table_scale(int* table, uchar* result, int n) { int min = table[0]; int max = table[0]; for (int i = 0; i<n; i++) { if (min>table[i]) { min = table[i]; } if (max<table[i]) { max = table[i]; } } for (int i = 0; i<n; i++) { result[i] = (uchar)(255 * (table[i] - min) / (max - min)); } } int main() { Mat src = imread("D:/10.jpg"); //get some informations of original image int nr = src.rows; int nc = src.cols*3; int n = nr*nc; int arr[9] = { 0 }; //scan the whole pixels of original image //and do Laplacian Operation int* table_lap = new int[n]; int* table_orig = new int[n]; int l; for (int i = 0; i<n; i++) { table_lap[i] = 0; table_orig[i] = 0; } for (int i = 1; i<nr - 1; i++) { const uchar* previous = src.ptr<uchar>(i - 1); const uchar* current = src.ptr<uchar>(i); const uchar* next = src.ptr<uchar>(i + 1); for (int j = 1; j<nc - 1; j++) { for (int k = 0; k<3; k++) { arr[k] = previous[j + k - 1]; arr[k + 3] = current[j + k - 1]; arr[k + 6] = next[j + k - 1]; } l = nc*i + j; //calculate the location in the table of current pixel Lmaskoperation(table_lap, arr, l); table_orig[l] = arr[4]; } } //pixels scale uchar* La_scaled = new uchar[n]; table_scale(table_lap, La_scaled, n); //padding values Mat LaResult_own; LaResult_own.create(src.size(), src.type()); uchar* p = NULL; for (int i = 0; i<nr; i++) { p = LaResult_own.ptr<uchar>(i); for (int j = 0; j<nc; j++) { l = nc*i + j; p[j] = La_scaled[l]; } } //show results imshow("结果", LaResult_own); waitKey(0); }
【参考文献】
http://www.cnblogs.com/german-iris/p/4840647.html
https://baike.baidu.com/item/%E6%8B%89%E6%99%AE%E6%8B%89%E6%96%AF%E7%AE%97%E5%AD%90/7261323?fr=aladdin
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix