【C++】图像处理中的微分算子原理与实现(二)

简介: 一阶微分边缘算子:经典算子比如:Roberts(罗伯特)、Prewitt(普鲁伊特)、Sobel(索贝尔),Canny(坎尼)等。二阶微分边缘算子:Laplacian算子,LoG( Laplace of Gaussian function)边缘检测算子和DoG(Difference of Gaussian)高斯差分算子。

Sobel算子

1973年,Sobel边缘算子,当年作者并没有公开发表过论文,仅仅是在一次博士生课题讨论会(1968)上提出("A 3x3 Isotropic Gradient Operator for Image Processing"),后在1973年出版的一本专著("Pattern Classification and Scene Analysis")的脚注里作为注释出现和公开的。

Sobel算子是一种用于边缘检测的离散微分算子,它结合了高斯平滑和微分求导。该算子用于计算图像明暗程度近似值,根据图像边缘旁边明暗程度把该区域内超过某个数的特定点记为边缘。Sobel算子在Prewitt算子的基础上增加了权重的概念,认为相邻点的距离远近对当前像素点的影响是不同的,距离越近的像素点对应当前像素的影响越大,从而实现图像锐化并突出边缘轮廓。


Sobel算子根据像素点上下、左右邻点灰度加权差,在边缘处达到极值这一现象检测边缘。对噪声具有平滑作用,提供较为精确的边缘方向信息。因为Sobel算子结合了高斯平滑和微分求导(分化),因此结果会具有更多的抗噪性,当对精度要求不是很高时,Sobel算子是一种较为常用的边缘检测方法。


Sobel算子的边缘定位更准确,常用于噪声较多、灰度渐变的图像。其算法模板如下面的公式所示,其中  表示水平方向, 表示垂直方向。

d04bf08190154abe8468de416cb65b5f.gif

voidquick_opencv::sobel_Demo(Mat&img)
{
cvtColor(img, img, COLOR_BGR2GRAY);
MatimageX=Mat::zeros(img.size(), CV_16SC1);
MatimageY=Mat::zeros(img.size(), CV_16SC1);
MatimageXY=Mat::zeros(img.size(), CV_16SC1);
MatimageX8UC;
MatimageY8UC;
MatimageXY8UC;
GaussianBlur(img, img, Size(3, 3), 0); //高斯滤波器(模糊/平滑/近似)消除噪点uchar*P=img.data;
uchar*PX=imageX.data;  
uchar*PY=imageY.data;
intstep=img.step;
intstepXY=imageX.step;
for (inti=1;i<img.rows-1;i++)
    {
for (intj=1;j<img.cols-1;j++)
        {
// 通过指针遍历图像上每一个像素// 求出X,Y方向的导数(梯度) sobel算子加权的结果PX[i*imageX.step+j* (stepXY/step)] =abs(P[(i-1)*step+j+1] +P[i*step+j+1] *2+P[(i+1)*step+j+1] -P[(i-1)*step+j-1] -P[i*step+j-1] *2-P[(i+1)*step+j-1]);
PY[i*imageX.step+j* (stepXY/step)] =abs(P[(i+1)*step+j-1] +P[(i+1)*step+j] *2+P[(i+1)*step+j+1] -P[(i-1)*step+j-1] -P[(i-1)*step+j] *2-P[(i-1)*step+j+1]);
        }
    }
addWeighted(imageX, 0.5, imageY, 0.5, 0, imageXY);//融合X、Y方向的梯度  convertScaleAbs(imageX, imageX8UC);
convertScaleAbs(imageY, imageY8UC);
convertScaleAbs(imageXY, imageXY8UC);   //转换为8bit图像MatimageSobel;
Matx_grad, y_grad;
Sobel(img, x_grad, CV_16S, 1, 0, 3);
Sobel(img, y_grad, CV_16S, 0, 1, 3);
convertScaleAbs(x_grad, x_grad);
convertScaleAbs(y_grad, y_grad);
addWeighted(x_grad, 0.5, y_grad, 0.5, 0, imageSobel);
imshow("Source Image", img);
imshow("X Direction", imageX8UC);
imshow("Y Direction", imageY8UC);
imshow("XY Direction", imageXY8UC);
imshow("Opencv Soble", imageSobel);
}


目录
相关文章
|
2月前
|
C++
【C++】深入解析C/C++内存管理:new与delete的使用及原理(二)
【C++】深入解析C/C++内存管理:new与delete的使用及原理
|
2月前
|
编译器 C++ 开发者
【C++】深入解析C/C++内存管理:new与delete的使用及原理(三)
【C++】深入解析C/C++内存管理:new与delete的使用及原理
|
2月前
|
存储 C语言 C++
【C++】深入解析C/C++内存管理:new与delete的使用及原理(一)
【C++】深入解析C/C++内存管理:new与delete的使用及原理
|
2月前
|
C++
C++番外篇——虚拟继承解决数据冗余和二义性的原理
C++番外篇——虚拟继承解决数据冗余和二义性的原理
42 1
|
6月前
|
存储 自然语言处理 安全
C++ STL标准库 《string原理与实战分析》
C++ STL标准库 《string原理与实战分析》
95 0
|
7月前
|
小程序 编译器 Linux
C++ 异常原理:以一个小程序为例
作者在调查某个 bug 时涉及到 C++ 异常,借此机会以本文把 C++ 异常机制梳理清楚供大家参考。
|
7月前
|
设计模式 算法 C++
【C++】STL之迭代器介绍、原理、失效
【C++】STL之迭代器介绍、原理、失效
137 2
|
6月前
|
大数据 C++ 索引
C++ STL标准库 《vector向量原理与实战分析》
C++ STL标准库 《vector向量原理与实战分析》
57 0
|
6月前
|
C++ 容器
C++ STL标准库 《queue单向队列原理与实战分析》
C++ STL标准库 《queue单向队列原理与实战分析》
49 0
|
7月前
|
编译器 C++ 容器
C++模板的原理及使用
C++模板的原理及使用