OpenCV函数

Sobel(src_gray,grad_x/grad_y,ddepth,x_order,y_order,scale,delta,BORDER_DEFAULT )

Scharr( )

边缘检测

为何要求导,如下图:

2.7 Sobel导数-LMLPHP

假设需要检测图中的边缘,可以看到在边缘像素值显著改变,灰度值跃升

2.7 Sobel导数-LMLPHP

利用一阶导数可以清晰喊道跃升(高峰值)

2.7 Sobel导数-LMLPHP

从以上推论,检测边缘可以通过定位梯度值大于邻域的像素的方法找到(或者推广到大于一个阈值)

Sobel算子

Sobel算子是一个邻域微分算子(discrete differentiation operator)。它用来计算图像灰度函数的近似梯度。

Sobel算子结合了高斯平滑和微分求导。

计算

假设源图像为I

在两个方向求导

水平变化:将I与一个奇数内核G进行卷积。比如,当内核大小为3时,G的计算结果为:

2.7 Sobel导数-LMLPHP

垂直变化:将I与一个奇数大小的内核Gy进行卷积:

2.7 Sobel导数-LMLPHP

在图像的每一点,结合以上两个结果求出近似梯度。

当内核大小为3时,Sobel内核可能产生比较明显的误差(毕竟Sobel算子只求取了倒数的近似值),为解决这一个问题,

OpenCV提供了另一个Scharr函数,该函数仅作用于大小为3的内核。该函数的运算与Sobel函数一样快,但结果更精确。

其内核为:2.7 Sobel导数-LMLPHP

#include <opencv2/opencv.hpp>
#include <iostream>
#include<windows.h>
#include<stdio.h>
#include<stdlib.h>
using namespace std;
using namespace cv; int main() {
Mat src, src_gray;
Mat grad;
char* window_name =(char*)"Sobel Demo-Simple Edge Detector";
int scale = ;
int delta = ;
int ddepth = CV_16S;
int c; //装载图像
src = imread("D:\\Pic\\4141.jpg");
if (!src.data) {
return -;
}
GaussianBlur(src, src, Size(, ), , , BORDER_DEFAULT); //转为灰度图
cvtColor(src, src_gray, CV_RGB2GRAY); //创建显示窗口
Mat grad_x, grad_y;
Mat abs_grad_x, abs_grad_y; //求x方向梯度
Sobel(src_gray, grad_x, ddepth, , , , scale, delta, BORDER_DEFAULT);
convertScaleAbs(grad_x, abs_grad_x); //求y方向梯度
Sobel(src_gray, grad_y, ddepth, , , , scale, delta, BORDER_DEFAULT);
convertScaleAbs(grad_y, abs_grad_y); //合并梯度
addWeighted(abs_grad_x, 0.5, abs_grad_y, 0.5, , grad); imshow(window_name, grad);
waitKey(); return ;
}
05-11 17:02