前言
边缘检测的一般步骤:
滤波——消除噪声增强——使边界轮廓更加明显检测——选出边缘点
一、Canny算法
Canny边缘检测算法被很多人推崇为当今最优秀的边缘检测算法,所以我们第一个就介绍他。
opencv中提供了Canny函数。
#include<opencv2\opencv.hpp> #include<opencv2\highgui\highgui.hpp>using namespace std;using namespace cv;//边缘检测int main(){Mat img = imread("lol3.jpg");imshow("原始图", img);Mat DstPic, edge, grayImage;//创建与src同类型和同大小的矩阵DstPic.create(img.size(), img.type());//将原始图转化为灰度图cvtColor(img, grayImage, COLOR_BGR2GRAY);//先使用3*3内核来降噪blur(grayImage, edge, Size(3, 3));//运行canny算子Canny(edge, edge, 3, 9, 3);imshow("边缘提取效果", edge);waitKey(0);}
看了canny算法提取的轮廓图,感觉真是厉害,居然把那么细致的额轮廓都提取出来了!
二、Sobel算法
#include<opencv2\opencv.hpp> #include<opencv2\highgui\highgui.hpp>using namespace std;using namespace cv;//边缘检测int main(){Mat img = imread("lol3.jpg");imshow("原始图", img);Mat grad_x, grad_y;Mat abs_grad_x, abs_grad_y, dst;//求x方向梯度Sobel(img, grad_x, CV_16S, 1, 0, 3, 1, 1,BORDER_DEFAULT);convertScaleAbs(grad_x, abs_grad_x);imshow("x方向soble", abs_grad_x);//求y方向梯度Sobel(img, grad_y,CV_16S,0, 1,3, 1, 1, BORDER_DEFAULT);convertScaleAbs(grad_y,abs_grad_y);imshow("y向soble", abs_grad_y);//合并梯度addWeighted(abs_grad_x, 0.5, abs_grad_y, 0.5, 0, dst);imshow("整体方向soble", dst);waitKey(0);}
通过下图可以看出,sobel的轮廓提取明显有没cnany的那么细致,只是把一些明显轮廓的边缘提取出来了,看起来会更舒服一点。
灰度图的效果
三、Laplacian算法
#include<opencv2\opencv.hpp> #include<opencv2\highgui\highgui.hpp>using namespace std;using namespace cv;//边缘检测int main(){Mat img = imread("lol3.jpg");imshow("原始图", img);Mat gray, dst,abs_dst;//高斯滤波消除噪声GaussianBlur(img, img, Size(3, 3), 0, 0, BORDER_DEFAULT);//转换为灰度图cvtColor(img, gray, COLOR_RGB2GRAY);//使用Laplace函数//第三个参数:目标图像深度;第四个参数:滤波器孔径尺寸;第五个参数:比例因子;第六个参数:表示结果存入目标图Laplacian(gray, dst, CV_16S, 3, 1, 0, BORDER_DEFAULT);//计算绝对值,并将结果转为8位convertScaleAbs(dst, abs_dst);imshow("laplace效果图", abs_dst);waitKey(0);}
但是感觉效果一般,图像变得模糊了。