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

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

Canny算子

1986年,Canny边缘检测算子是John F. Canny开发出来的一个多级边缘检测算法。更为重要的是Canny创立了“边缘检测计算理论”(computational theory of edge detection)解释这项技术如何工作。到今天已经30多年过去了,但Canny算法仍然是图像边缘检测算法中最经典、先进的算法之一。

1、高斯平滑

2、计算梯度幅度和方向

可选用的模板:soble算子、Prewitt算子、Roberts模板等等;

一般采用soble算子,OpenCV也是如此,利用soble水平和垂直算子与输入图像卷积计算dx、dy

3、根据角度对幅值进行非极大值抑制

沿着梯度方向对幅值进行非极大值抑制,而非边缘方向


42e3eba7ab95446c9fe007207b5034cc.png

在每一点上,领域中心 x 与沿着其对应的梯度方向的两个像素相比,若中心像素为最大值,则保留,否则中心置0,这样可以抑制非极大值,保留局部梯度最大的点,以得到细化的边缘。

4、用双阈值算法检测和连接边缘

选取系数TH和TL,比率为2:1或3:1。(一般取TH=0.3或0.2,TL=0.1);

将小于低阈值的点抛弃,赋0;将大于高阈值的点立即标记(这些点为确定边缘点),赋1或255;

将小于高阈值,大于低阈值的点使用8连通区域确定(即:只有与TH像素连接时才会被接受,成为边缘点,赋 1或255)

voidquick_opencv::canny_Demo(Mat&img)
{
ConvertRGB2GRAY(img, imageGray); //RGB转换为灰度图  imshow("Gray Image", imageGray);
intsize=5; //定义卷积核大小  double**gaus=newdouble*[size];  //卷积核数组  for (inti=0;i<size;i++)
    {
gaus[i] =newdouble[size];  //动态生成矩阵      }
GetGaussianKernel(gaus, 5, 1); //生成5*5 大小高斯卷积核,Sigma=1;  imageGaussian=Mat::zeros(imageGray.size(), CV_8UC1);
GaussianFilter(imageGray, imageGaussian, gaus, 5);  //高斯滤波  imshow("Gaussian Image", imageGaussian);
MatimageSobelY;
MatimageSobelX;
double*pointDirection=newdouble[(imageSobelX.cols-1)*(imageSobelX.rows-1)];  //定义梯度方向角数组  SobelGradDirction(imageGaussian, imageSobelX, imageSobelY, pointDirection);  //计算X、Y方向梯度和方向角  imshow("Sobel Y", imageSobelY);
imshow("Sobel X", imageSobelX);
MatSobelGradAmpl;
SobelAmplitude(imageSobelX, imageSobelY, SobelGradAmpl);   //计算X、Y方向梯度融合幅值  imshow("Soble XYRange", SobelGradAmpl);
MatimageLocalMax;
LocalMaxValue(SobelGradAmpl, imageLocalMax, pointDirection);  //局部非极大值抑制  imshow("Non-Maximum Image", imageLocalMax);
MatcannyImage;
cannyImage=Mat::zeros(imageLocalMax.size(), CV_8UC1);
DoubleThreshold(imageLocalMax, 90, 160);        //双阈值处理  imshow("Double Threshold Image", imageLocalMax);
DoubleThresholdLink(imageLocalMax, 90, 160);   //双阈值中间阈值滤除及连接  imshow("Canny Image", imageLocalMax);
}



目录
相关文章
|
16天前
|
存储 自然语言处理 安全
C++ STL标准库 《string原理与实战分析》
C++ STL标准库 《string原理与实战分析》
19 0
|
1月前
|
小程序 编译器 Linux
C++ 异常原理:以一个小程序为例
作者在调查某个 bug 时涉及到 C++ 异常,借此机会以本文把 C++ 异常机制梳理清楚供大家参考。
|
15天前
|
大数据 C++ 索引
C++ STL标准库 《vector向量原理与实战分析》
C++ STL标准库 《vector向量原理与实战分析》
18 0
|
16天前
|
C++ 容器
C++ STL标准库 《queue单向队列原理与实战分析》
C++ STL标准库 《queue单向队列原理与实战分析》
18 0
|
1月前
|
设计模式 算法 C++
【C++】STL之迭代器介绍、原理、失效
【C++】STL之迭代器介绍、原理、失效
48 2
|
1月前
|
编解码 JavaScript 前端开发
【专栏】介绍了字符串Base64编解码的基本原理和在Java、Python、C++、JavaScript及Go等编程语言中的实现示例
【4月更文挑战第29天】本文介绍了字符串Base64编解码的基本原理和在Java、Python、C++、JavaScript及Go等编程语言中的实现示例。Base64编码将24位二进制数据转换为32位可打印字符,用“=”作填充。文中展示了各语言的编码解码代码,帮助开发者理解并应用于实际项目。
|
1月前
|
编译器 C++ 容器
C++模板的原理及使用
C++模板的原理及使用
|
1月前
|
设计模式 C语言 C++
【C++进阶(六)】STL大法--栈和队列深度剖析&优先级队列&适配器原理
【C++进阶(六)】STL大法--栈和队列深度剖析&优先级队列&适配器原理
|
1月前
|
存储 C++
C++底层原理
C++底层原理
74 0
|
1月前
|
C++
关于C++多态 的基本知识 与 底层原理
关于C++多态 的基本知识 与 底层原理