OpenCV学习笔记-Sobel()函数与Scharr()函数怎么用

文章目录

  • 目标
  • 原理
    • Sobel()函数讲解
    • Scharr()函数讲解
  • 源码
  • 程序说明

参考:https://docs.opencv.org/3.4.5/d2/d2c/tutorial_sobel_derivatives.html
若有表达不当或错误欢迎留言指正,互相交流学习,共同进步

目标

在本教程中,您将学习如何:

  • 使用OpenCV函数Sobel()计算图像的导数。
  • 使用OpenCV函数Scharr()计算内核大小为3x3的、更准确的导数

原理

参考官方文档:https://docs.opencv.org/3.4.5/d2/d2c/tutorial_sobel_derivatives.html

Sobel()函数讲解

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);

第一个参数:输入图像
第二个参数:输出图像(与输入图像有相同的的尺寸和通道数)
第三个参数:输出图像的深度(,取决于输入图像;输出图像深度若为-1,则输出图像深度和输入图像深度一样,详见下表)

Input depth (src.depth())/输入图像的深度 Output depth (ddepth)/输出图像的深度
CV_8U -1/CV_16S/CV_32F/CV_64F
CV_16U/CV_16S -1/CV_32F/CV_64F
CV_32F -1/CV_32F/CV_64F
CV_64F -1/CV_64F

第四个参数:x、dx方向上的差分阶数
第五个参数:y、dy方向上的差分阶数
第六个参数:Sobel()内核的大小,必须为1或3或5或7
第七个参数:可选的系数,用于乘到导数计算结果中
第八个参数:可选的量值,用于加到导数计算结果中
第九个参数:边界类型,默认值为BORDER_DEFAULT

    BORDER_CONSTANT    = 0, //!< `iiiiii|abcdefgh|iiiiiii`  with some specified `i`
    BORDER_REPLICATE   = 1, //!< `aaaaaa|abcdefgh|hhhhhhh`
    BORDER_REFLECT     = 2, //!< `fedcba|abcdefgh|hgfedcb`
    BORDER_WRAP        = 3, //!< `cdefgh|abcdefgh|abcdefg`
    BORDER_REFLECT_101 = 4, //!< `gfedcb|abcdefgh|gfedcba`
    BORDER_TRANSPARENT = 5, //!< `uvwxyz|abcdefgh|ijklmno`

    BORDER_REFLECT101  = BORDER_REFLECT_101, //!< same as BORDER_REFLECT_101
    BORDER_DEFAULT     = BORDER_REFLECT_101, //!< same as BORDER_REFLECT_101
    BORDER_ISOLATED    = 16 //!< do not look outside of ROI

Scharr()函数讲解

void Scharr(	InputArray src, 
				OutputArray dst, 
				int ddepth,
				int dx, 
				int dy, 
				double scale = 1, 
				double delta = 0,
				int borderType = BORDER_DEFAULT);

第一个参数:输入图像
第二个参数:输出图像(与输入图像有相同的的尺寸和通道数)
第三个参数:输出图像的深度(,取决于输入图像;输出图像深度若为-1,则输出图像深度和输入图像深度一样,详见下表)
第四个参数:x、dx方向上的差分阶数
第五个参数:y、dy方向上的差分阶数
第六个参数:可选的系数,用于乘到导数计算结果中
第七个参数:可选的量值,用于加到导数计算结果中
第八个参数:边界类型,默认值为BORDER_DEFAULT

源码

#include "opencv2/imgproc.hpp"
#include "opencv2/imgcodecs.hpp"
#include "opencv2/highgui.hpp"
using namespace cv;
int main()
{
	VideoCapture capture(0);									//
	//【2】循环显示每一帧											//
	while (1)													//
	{															//
		Mat image;  //定义一个Mat变量,用于存储每一帧的图像		//	
		capture >> image;  //读取当前帧							//
//////////////////////////////////////////////////////////////////
		Mat gray = image.clone();
		cvtColor(image, gray, CV_BGR2GRAY);//转换为灰度图像
		Mat gradx = gray.clone();
		Mat grady = gray.clone();
		Mat absgradx = gray.clone();
		Mat absgrady = gray.clone();
		Mat grad = gray.clone();
		
		int ddepth = -1;
		int ksize = 3;
		int scale = 1;
		int delta = 0;
		
		GaussianBlur(image, image, Size(3, 3), 0, 0, BORDER_DEFAULT);//高斯滤波
		Sobel(gray, gradx, ddepth, 1, 0, ksize, scale, delta, BORDER_DEFAULT);
		Sobel(gray, grady, ddepth, 0, 1, ksize, scale, delta, BORDER_DEFAULT);
		convertScaleAbs(gradx, absgradx); //转换回CV_8U
		convertScaleAbs(grady, absgrady); //转换回CV_8U
		addWeighted(absgradx, 0.5, absgrady, 0.5, 0, grad);//图像叠加
		imshow("out", grad);

//////////////////////////////////////////////////////////////////
																//
																//	
		waitKey(30);  //延时30ms								//
	}															//
	return 0;													//
}																//
#include "opencv2/imgproc.hpp"
#include "opencv2/imgcodecs.hpp"
#include "opencv2/highgui.hpp"
using namespace cv;
int main()
{
	VideoCapture capture(0);									//
	//【2】循环显示每一帧											//
	while (1)													//
	{															//
		Mat image;  //定义一个Mat变量,用于存储每一帧的图像		//	
		capture >> image;  //读取当前帧							//
//////////////////////////////////////////////////////////////////
		Mat gray = image.clone();
		cvtColor(image, gray, CV_BGR2GRAY);//转换为灰度图像
		Mat gradx = gray.clone();
		Mat grady = gray.clone();
		Mat absgradx = gray.clone();
		Mat absgrady = gray.clone();
		Mat grad = gray.clone();
		
		int ddepth = -1;
		int scale = 1;
		int delta = 0;
		
		GaussianBlur(image, image, Size(3, 3), 0, 0, BORDER_DEFAULT);//高斯滤波
		Scharr(gray, gradx, ddepth, 1, 0, scale, delta, BORDER_DEFAULT);
		Scharr(gray, grady, ddepth, 0, 1, scale, delta, BORDER_DEFAULT);
		convertScaleAbs(gradx, absgradx); //转换回CV_8U
		convertScaleAbs(grady, absgrady); //转换回CV_8U
		addWeighted(absgradx, 0.5, absgrady, 0.5, 0, grad);//图像叠加
		imshow("out", grad);

//////////////////////////////////////////////////////////////////
																//
																//	
		waitKey(30);  //延时30ms								//
	}															//
	return 0;													//
}																//

程序说明

  • 从默认或提供的捕获设备捕获视频流。
int main()
{
	VideoCapture capture(0);
	//【2】循环显示每一帧
	while (1)													//
	{															//
		Mat image;  //定义一个Mat变量,用于存储每一帧的图像		//	
		capture >> image;  //读取当前帧							//
//================================================================
  • 定义所需灰度图,梯度,x、y梯度绝对值,梯度和
Mat gray = image.clone();
cvtColor(image, gray, CV_BGR2GRAY);//转换为灰度图像
Mat gradx = gray.clone();
Mat grady = gray.clone();
Mat absgradx = gray.clone();
Mat absgrady = gray.clone();
Mat grad = gray.clone();
  • 定义所需参数
int ddepth = -1;
int ksize = 3;
int scale = 1;
int delta = 0;
		
  • 高斯滤波
GaussianBlur(image, image, Size(3, 3), 0, 0, BORDER_DEFAULT);//高斯滤波	
  • 边缘检测
Sobel(gray, gradx, ddepth, 1, 0, ksize, scale, delta, BORDER_DEFAULT);
Sobel(gray, grady, ddepth, 0, 1, ksize, scale, delta, BORDER_DEFAULT);
convertScaleAbs(gradx, absgradx); //转换回CV_8U
convertScaleAbs(grady, absgrady); //转换回CV_8U
  • 图像叠加并输出图像
addWeighted(absgradx, 0.5, absgrady, 0.5, 0, grad);//图像叠加
imshow("out", grad);

你可能感兴趣的:(OpenCV)