图像边缘检测
边缘检测可以提取图像重要轮廓信息,减少图像内容,可以用于分割图像、做特征提取等
边缘检测的一般步骤:
滤波----(滤出噪声対检测边缘的影响)
增强----(可以将像素邻域强度变化凸显出来---梯度算子)
检测----(阈值方法确定边缘)
常用边缘检测算子:
Canny算子
Sobel算子
Scharr算子
Laplacian算子
Roberts 算子、Prewitt算子… …
1)Canny边缘检测
Canny边缘检测步骤:
p1
消除噪声: 一般情况使用高斯平滑滤波器卷积降噪
p2
计算梯度幅值和方向: 安装Sobel滤波器的步骤操作
p3
非极大值抑制: 排除非边缘像素
p4
滞后阈值: 滞后阈值需要两个阈值(高阈值和低阈值):
Canny边缘检测函数---Canny()
src: 输入原图像(一般为单通道8位图像)
dst: 输出边缘图像要求和src一样的尺寸和类型(单通道)
threshold1: 滞后阈值低阈值(用于边缘连接)
threshold2: 滞后阈值高阈值(控制边缘初始段)
推荐高低阈值比值在2:1到3:1之间
apertureSize:表示Sobel算子孔径大小,默认值3
L2gradient: 计算图像梯度幅值的标识
实例:
2)Sobel算子
Sobel算子是一个主要用于边缘检测的离散微分算子,它结合了高斯平滑和微分求导,
用来计算图像灰度函数的近似梯度。
Sobel算子计算过程:
分别在
x
和
y
两个方向求导
:
Sobel边缘检测函数---Sobel()
src:输入原图像
dst:输出图像要求和src一样的尺寸和类型
ddepth:输出图像的深度,支持如下组合:
dx:X方向上的差分阶数
dy:Y方向上的差分阶数
ksize:默认值3,表示Sobel核大小,1,3,5,7
scale:计算导数值时的缩放因子,默认值1,表示不缩放
delta(δ):表示在结果存入目标图之前可选的delta值,默认值0
borderType:边界模式,一般采用默认
效果:
3)Laplacian算子
Laplacian算子的定义:
Laplacian边缘检测函数---Laplacian()
src:输入原图像(单通道8位图像)
dst:输出边缘图像要求和src一样的尺寸和通道数
ddepth:目标图像的深度
Ksize:用于计算二阶导数的滤波器孔径大小,须为正奇数,默认值1
scale:可选比例因子,默认值1
delta:可选参数δ,默认值0
borderType:边界模式,一般采用默认值
实例:
效果:
Canny:
#include"opencv2/opencv.hpp"
using namespace cv;
void main()
{
Mat src = imread("1.jpg");
Mat dst1;
Mat dst2;
blur(src, dst1, Size(5, 5));
Canny(src, dst2, 30, 100);
imshow("原图", src);
imshow("blur后图像", dst1);
imshow("Canny后图像", dst2);
waitKey(0);
}
Sobel:
#include"opencv2/opencv.hpp"
using namespace cv;
void main()
{
Mat src = imread("1.jpg");
Mat sobel;
Mat grad_x, grad_y;
Mat abs_grad_x, abs_grad_y, dst;
Sobel(src, grad_x, -1, 1, 0, 3, 1, 1, BORDER_DEFAULT);
convertScaleAbs(grad_x, abs_grad_x);//取X方向偏导的绝对值
Sobel(src, grad_y, -1, 0, 1, 3, 1, 1, BORDER_DEFAULT);
convertScaleAbs(grad_y, abs_grad_y);
imshow("原图",src);
imshow("grad_x",abs_grad_x);
imshow("grad_y", abs_grad_y);
waitKey(0);
}
Laplacian:
#include"opencv2/opencv.hpp"
using namespace cv;
void main()
{
Mat grad_x, grad_y;
Mat abs_grad_x, abs_grad_y, dst;
Mat abs_dst;
Mat src = imread("1.jpg", 0);
imshow("src", src);
Laplacian(src, dst, CV_16S, 3, 1, 0, BORDER_DEFAULT);
convertScaleAbs(dst, abs_dst);
imshow("Laplacian", abs_dst);
waitKey(0);
destroyAllWindows();
}