一、函数
a.Sobel
函数:
(1)函数原型:
CV_EXPORTS_W void Sobel( InputArray src, OutputArray dst, int ddepth, int dx,
int dy, int ksize = 3, double scale = 1, double delta = 0,
int borderType = BORDER_DEFAULT );
(2)函数作用:
计算图像的一阶、二阶、三阶或混合导数,使用扩展的Sobel算子。
(3)参数说明:
InputArray src
:输入图像。OutputArray dst
:输出图像,其大小和通道数与输入图像src
相同。int ddepth
:输出图像的深度,可以查看OpenCV文档了解不同的深度组合。对于8位输入图像,导数可能会被截断。int dx
:x方向上的导数阶数。int dy
:y方向上的导数阶数。int ksize
:扩展Sobel核的大小;必须是1、3、5或7。当ksize = 1
时,使用3x1或1x3核,不进行高斯平滑。ksize = FILTER_SCHARR (-1)
是一个特殊值,对应于3x3 Scharr滤波器,可能比3x3 Sobel滤波器给出更准确的结果。double scale
:可选的比例因子,用于计算得到的导数值;默认情况下,不应用缩放(见getDerivKernels
函数的详细信息)。double delta
:可选的delta值,在将结果存储到dst
之前加到结果上。int borderType
:像素外推方法,见BorderTypes
。不支持BORDER_WRAP
。
(4) 补充说明:
Sobel
函数通过将图像与适当的核卷积来计算图像导数。Sobel算子结合了高斯平滑和微分,因此结果对噪声有一定的抵抗力。通常,这个函数被调用时参数设置为(dx = 1, dy = 0, ksize = 3
)或(dx = 0, dy = 1, ksize = 3
),以计算图像的一阶x或y导数。
b.Canny
函数:
(1) 函数原型:
CV_EXPORTS_W void Canny( InputArray image, OutputArray edges, double threshold1,
double threshold2, int apertureSize = 3, bool L2gradient = false );
(2) 函数作用:
用于使用Canny边缘检测算法在图像中检测边缘。
(3)参数说明:
InputArray image
:函数的第一个参数,表示输入的8位图像,用于边缘检测。OutputArray edges
:函数的第二个参数,表示输出的边缘图,也是一个8位单通道图像,其大小与输入图像相同。double threshold1
和double threshold2
:这两个参数是Canny算法中的阈值,用于边缘连接和检测强边缘的初始段。int apertureSize
:Sobel算子的孔径大小,默认值为3。bool L2gradient
:一个标志,指示是否使用更准确的L2范数计算图像梯度的幅度(L2gradient=true
),或者使用默认的L1范数(L2gradient=false
)。
(4) 补充说明:
Canny算法是一种流行的边缘检测方法,由John F. Canny在1986年提出。canny函数的作用是接受一个输入图像,通过Canny算法检测图像中的边缘,并将检测到的边缘标记在输出的边缘图上。这个函数在图像处理和计算机视觉领域中非常有用,特别是在需要边缘信息进行进一步分析或处理的任务中。
c. Canny
函数(重载版本):
(1)函数原型:
CV_EXPORTS_W void Canny( InputArray dx, InputArray dy, OutputArray edges,
double threshold1, double threshold2, bool L2gradient = false );
(2)函数作用:
这个版本允许用户使用自定义的图像梯度来检测边缘。
(3)参数说明:
nputArray dx
:函数的第一个参数,表示输入图像的x方向导数(即水平方向的梯度),数据类型为16位有符号短整型(CV_16SC1或CV_16SC3)。InputArray dy
:函数的第二个参数,表示输入图像的y方向导数(即垂直方向的梯度),数据类型与dx
相同。OutputArray edges
:函数的第三个参数,表示输出的边缘图,是一个8位单通道图像,其大小与输入图像相同。double threshold1
和double threshold2
:这两个参数与之前相同,是Canny算法中的阈值。bool L2gradient
:这个参数也与之前相同,用于指示是否使用L2范数或L1范数来计算图像梯度的幅度。
(4)补充说明:
这个重载版本的Canny
函数允许用户在已知图像梯度的情况下进行边缘检测,这在某些情况下可以提高算法的效率或准确性。例如,如果用户已经计算了图像的梯度,那么他们可以使用这个版本的函数来避免重复计算。
二、示例代码:
#include <opencv2/core/utils/logger.hpp>
#include <opencv2/opencv.hpp>
#include <opencv2/videoio.hpp>
#include <opencv2/objdetect.hpp>
#include <opencv2/highgui/highgui_c.h>
#include <iostream>
using namespace cv;
using namespace std;
int main()
{
utils::logging::setLogLevel(utils::logging::LOG_LEVEL_SILENT);
Mat canny_image = imread("C:\\Users\\86173\\Desktop\\TI\\canny.jpg");
//判断图片是否打开
if (canny_image.empty())
{
cout << "Can't open picture" << endl;
return 0;
}
//定义图片容器
Mat image_dx;
Mat image_dy;
Mat image_canny1;
Mat image_canny2;
Mat scr_image;
Sobel(canny_image, image_dx, CV_16S, 1, 0, 3);//x方向上的梯度
Sobel(canny_image, image_dy, CV_16S, 0, 1, 3);//y方向上的梯度
Canny(image_dx, image_dy, image_canny1, 20, 60);
//转化为灰度图,在进行边缘提取
cvtColor(canny_image, scr_image, COLOR_BGR2GRAY);
Canny(scr_image, image_canny2, 20, 60);
imshow("image_canny1", image_canny1);
imshow("image_canny2", image_canny2);
waitKey(0);
destroyAllWindows();
return 0;
}