首先感谢@浅墨_毛星云,本篇博文是小武通过学习@浅墨_毛星云的博客以及书籍《opencv3.0编程入门》整理的笔记及疑问心得,小武水平有限,欢迎交流。
@浅墨_毛星云博文:https://blog.csdn.net/poem_qianmo/article/category/1923021
一、Canny算子
详情介绍:https://zh.wikipedia.org/wiki/Canny%E7%AE%97%E5%AD%90
基本原理:https://blog.csdn.net/likezhaobin/article/details/6892176
函数详情:
C++: void Canny(InputArray image,OutputArray edges,
double threshold1, double threshold2, int apertureSize=3,bool L2gradient=false )
参数解释:
需要注意的是,这个函数阈值1和阈值2两者的小者用于边缘连接,而大者用来控制强边缘的初始段,推荐的高低阈值比在2:1到3:1之间。
二、Sobel算子
详情介绍:https://zh.wikipedia.org/wiki/索貝爾算子
基本原理:http://www.cnblogs.com/lancidie/archive/2011/07/17/2108885.html
函数详情:
C++: 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 );
参数解释:
三、Laplace算子
详情介绍:https://zh.wikipedia.org/wiki/%E6%8B%89%E6%99%AE%E6%8B%89%E6%96%AF%E7%AE%97%E5%AD%90
基本原理:http://www.cnblogs.com/xfzhang/archive/2011/01/19/1939020.html
函数详解:
C++: void Laplacian(InputArray src,OutputArray dst,
int ddepth,
int ksize=1,
double scale=1,
double delta=0, intborderType=BORDER_DEFAULT );
参数解释:
Laplacian( )函数其实主要是利用sobel算子的运算。它通过加上sobel算子运算出的图像x方向和y方向上的导数,来得到我们载入图像的拉普拉斯变换结果。
四、scharr滤波器
scharr一般我就直接称它为滤波器,而不是算子。
函数详情:https://docs.opencv.org/2.4/modules/ocl/doc/image_filtering.html?highlight=scharr#ocl-scharr
C++: void Scharr(
InputArray src, //源图
OutputArray dst, //目标图
int ddepth,//图像深度
int dx,// x方向上的差分阶数
int dy,//y方向上的差分阶数
double scale=1,//缩放因子
double delta=0,// delta值
intborderType=BORDER_DEFAULT )// 边界模式
参数详解:
综合代码实现:
跟踪条: 0——Canny算子
1——Sobel算子
2——Laplace算子
3——Scharr滤波
//添加头文件
#include
#include
#include
#include
using namespace std;
using namespace cv;
//参数预定义
int Way_num=0;
int struct_size=1;
Mat Img_in , Img_out,Img_gray;
Mat Img_out_x , Img_out_y;
//函数声明
void callback_Way_num(int ,void*);
void callback_struct_size(int ,void*);
void process();
//主函数
int main ()
{
Img_in=imread("home.jpg");
cvtColor(Img_in,Img_gray,CV_BGR2GRAY);
imshow("【原图】",Img_gray);
//添加跟踪条
namedWindow("【效果图】");
createTrackbar("Canny/Sobel/Laplace/scharr","【效果图】",&Way_num, 3 , callback_Way_num);
callback_Way_num(Way_num,0);
//添加跟踪条
createTrackbar("参数值","【效果图】",&struct_size, 45 , callback_struct_size);
callback_struct_size(struct_size,0);
waitKey(0);
return 0;
}
//进行自定义的各功能操作
void process()
{
//Way_num=0,Canny算子
if (Way_num==0)
Canny(Img_gray,Img_out,struct_size , struct_size*5 , 3);
//Way_num=1,Sobel算子
else if(Way_num==1)
{
//计算x方向梯度
Sobel(Img_in , Img_out_x,CV_16U, 1 , 0 , struct_size*2+1 , 1 , 1 , BORDER_DEFAULT);
convertScaleAbs(Img_out_x,Img_out_x);
//计算y方向的梯度
Sobel(Img_in , Img_out_y,CV_16U, 0 , 1 , struct_size*2+1 , 1 , 1 , BORDER_DEFAULT);
convertScaleAbs(Img_out_y,Img_out_y);
//合并
addWeighted( Img_out_x,0.5, Img_out_y , 0.5,0, Img_out);
}
//Way_num=2,Laplace算子
else if(Way_num==2)
{
Laplacian(Img_gray,Img_out, CV_16U , struct_size*2+1, 1 , 0 , BORDER_DEFAULT);
convertScaleAbs(Img_out ,Img_out);
}
//Way_num=3,scharr滤波
else if(Way_num==3)
{
//计算x方向梯度
Scharr(Img_in , Img_out_x,CV_16U, 1 , 0 , 1 , 0 , BORDER_DEFAULT);
convertScaleAbs(Img_out_x,Img_out_x);
//计算y方向的梯度
Scharr(Img_in , Img_out_y,CV_16U, 0 , 1 , 1 , 0 , BORDER_DEFAULT);
convertScaleAbs(Img_out_y,Img_out_y);
//合并
addWeighted( Img_out_x , 0.5 , Img_out_y , 0.5 , 0 , Img_out);
}
//显示
imshow("【效果图】",Img_out);
}
//更能切换开关的回调函数
void callback_Way_num(int ,void*)
{
process();
}
//改变各个功能操作内核时的回调函数
void callback_struct_size(int ,void*)
{
process();
}
效果: