Scharr函数和Sobel函数的混合使用

代码如下:

#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"
#include <stdlib.h>
#include <stdio.h>

using namespace cv;

/** @function main */
int main( int argc, char** argv )
{

  Mat src, src_gray;
  Mat grad;

  char* window_name = "Sobel例子";
  int scale = 1;
  int delta = 0;
  int ddepth = CV_16S;

  int c;

  /// 装载图像
  src = imread( "C://1.jpg" );

  if( !src.data )
  { 
	  return -1;
  }
  imshow("原始图像",src);

  GaussianBlur( src, src, Size(3,3), 0, 0, BORDER_DEFAULT );  //Blur降噪

  /// 转换为灰度图
  cvtColor( src, src_gray, CV_RGB2GRAY );

  /// 创建显示窗口
  namedWindow( window_name, CV_WINDOW_AUTOSIZE );

  /// 创建 grad_x 和 grad_y 矩阵
  Mat grad_x, grad_y;
  Mat abs_grad_x, abs_grad_y;

  //Scharr函数与Sobel函数一样快,但结果更加的精确 
  /// 求 X方向梯度     Scharr( src_gray, grad_x, ddepth, 1, 0, scale, delta, BORDER_DEFAULT );  ksize默认为3 相等于 1,0,3 scale和delta默认 1,0,
  Scharr( src_gray, grad_x, ddepth, 1, 0, scale, delta, BORDER_DEFAULT );
 // Sobel( src_gray, grad_x, ddepth, 1, 0, 3, scale, delta, BORDER_DEFAULT );
  convertScaleAbs( grad_x, abs_grad_x );
  imshow("x方向Sobel",abs_grad_x );
  /// 求Y方向梯度
  Scharr( src_gray, grad_y, ddepth, 0, 1, scale, delta, BORDER_DEFAULT );
 // Sobel( src_gray, grad_y, ddepth, 0, 1, 3, scale, delta, BORDER_DEFAULT );
  convertScaleAbs( grad_y, abs_grad_y );
  imshow("y方向Sobel", abs_grad_y);
  /// 合并梯度(近似)
  addWeighted( abs_grad_x, 0.5, abs_grad_y, 0.5, 0, grad );
  imshow("整体方向Sobel", grad);

  waitKey(0);

  return 0;
  }

1.首先申明变量:

Mat src, src_gray;
Mat grad;
char* window_name = “Sobel Demo - Simple Edge Detector”;
int scale = 1;
int delta = 0;
int ddepth = CV_16S;

2.装载原图像 src:

src = imread( argv[1] );
if( !src.data )
{
turn -1;
}

3.第一步对原图像使用 GaussianBlur 降噪 ( 内核大小 = 3 )

GaussianBlur( src, src, Size(3,3), 0, 0, BORDER_DEFAULT );

4.将降噪后的图像转换为灰度图:

cvtColor( src, src_gray, CV_RGB2GRAY );

5.第二步,在 x 和 y 方向分别”求导“。 为此,我们使用函数 Sobel :

Mat grad_x, grad_y;
Mat abs_grad_x, abs_grad_y;

扫描二维码关注公众号,回复: 3374114 查看本文章

/// 求 X方向梯度
Sobel( src_gray, grad_x, ddepth, 1, 0, 3, scale, delta, BORDER_DEFAULT );
/// 求 Y方向梯度
Sobel( src_gray, grad_y, ddepth, 0, 1, 3, scale, delta, BORDER_DEFAULT );
该函数接受了以下参数:

src_gray: 在本例中为输入图像,元素类型 CV_8U
grad_x/grad_y: 输出图像.
ddepth: 输出图像的深度,设定为 CV_16S 避免外溢。
x_order: x 方向求导的阶数。
y_order: y 方向求导的阶数。
scale, delta 和 BORDER_DEFAULT: 使用默认值
注意为了在 x 方向求导我们使用: x_{order}= 1 , y_{order} = 0. 采用同样方法在 y 方向求导。

6.将中间结果转换到 CV_8U:

convertScaleAbs( grad_x, abs_grad_x );
convertScaleAbs( grad_y, abs_grad_y );

7.将两个方向的梯度相加来求取近似 梯度 (注意这里没有准确的计算,但是对我们来讲已经足够了)。

addWeighted( abs_grad_x, 0.5, abs_grad_y, 0.5, 0, grad );

最后,显示结果:

imshow( window_name, grad );

测试结果如下
1.Sobel算子的使用 x y 整体方向上的sobel
在这里插入图片描述
2.使用Scharr函数 x,y,整体方向上类似Sobel
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/zqx951102/article/details/82817862