【OpenCV3经典编程100例】(10)边缘检测:用Sobel()函数求取灰度图的梯度算子

前10话是opencv里面常用函数的介绍,完成了《数字图像处理》/第三章/灰度变换和空间滤波的c++代码实现!

第10示例,首先,用Sobel()函数求取灰度图的梯度算子。

然后用一阶微分算子——梯度算子来进行灰度图像的边缘检测,效果比拉普拉斯算子好很多。

	//Sobel函数,可计算一阶、二阶、三阶或混合图像差分
	void Sobel(InputArray src,//输入图像 
		OutputArray dst,//输出图像 
		int ddepth,//输出图像的深度
		int dx,//x方向上的差分阶数 
		int dy,//y方向上的差分阶数 
		int ksize = 3,//默认为3,Sobel核的大小,必须取1、3、5、7
		double scale = 1,//默认为1,计算导数值时可选的缩放因子 
		double delta = 0,//默认
		int borderType = BORDER_DEFAULT);//默认
	//常见的用法:
	//取dx=1, dy=0, ksize=3来计算图像X方向的导数
	//取dx=0, dy=1, ksize=3来计算图像Y方向的导数

一、c++示例代码

//包含头文件
#include <opencv2/opencv.hpp>
//命名空间
using namespace cv;
using namespace std;
//全局函数声明部分

//主函数
int main()
{
	//【1】载入图像,灰度化
	Mat image = imread("F:\\opencvtest\\testImage\\beauty.png", 0);
	//【2】检查是否载入成功
	if (image.empty())
	{
		printf("读取图片错误,请确认目录下是否有imread函数指定图片存在! \n ");
		return 0;
	}
	//【3】求X方向梯度算子
	Mat grad_x;
	Sobel(image, grad_x, CV_16S, 1, 0);
	//【4】求Y方向梯度算子
	Mat grad_y;
	Sobel(image, grad_y, CV_16S, 0, 1);
	//【5】梯度合成,计算L1范式,也称街区距离
	Mat gradImage;//梯度图
	gradImage = abs(grad_x) + abs(grad_y);
	//【6】在缩放的情况下转化为8位无符号整数类型图像
	double minGrad, maxGrad;
	minMaxLoc(gradImage, &minGrad, &maxGrad);
	Mat gradImage_8U;
	gradImage.convertTo(gradImage_8U, CV_8U, 255./maxGrad);
	//【7】阈值化,加以反转增加可视化效果
	Mat thresholdedImage;//阈值化后的二值图
	threshold(gradImage_8U, thresholdedImage, 20, 255, THRESH_BINARY_INV);
	//【8】显示图像
	imshow("10-梯度算子边缘图", gradImage_8U);
	imshow("10-阈值化后的二值图", thresholdedImage);
	//【9】保持窗口显示
	waitKey(0);
	return 0;
}

二、运行截图

1.用梯度算子求取图像的边缘检测图


2.阈值化处理,生成二值图像,增强可视化效果


三、数字图像处理知识

Sobel梯度算子——3x3的梯度模板

1. 作用:边缘增强效果,边缘检测

2. 用于卷积的(Kernel)




猜你喜欢

转载自blog.csdn.net/misterjiajia/article/details/80300961
今日推荐