概述
1.边缘提取概念
(1)像素值发生跃迁的地方,是图像的显著特征之一,在图像特征提取、对象检测、模式识别等方面都有重要的作用。
(2)对图像求它的一阶导数delta = f(x) – f(x-1), delta越大,说明像素在X方向变化越大,边缘信号越强,有可能为正,有可能为负数,导数(即斜率)。
(还有一种像素从高到低跃迁,个人理解)
2.Sobel算子
(1)水平梯度:
(2)垂直梯度:
(3)最终梯度
由于平方和开根号与取绝对值相加近似,为提升计算速度,使用下面的方法。
3.Sobel改进后的Scharr函数算子
4.相关API和操作步骤
(1)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:输入图像
参数2:输出图像
参数3:输出图像的深度,针对不同的输入图像,输出目标图像有不同的深度,搭配如下:
参数4,5:X,Y方向的几阶导数
参数6:内核大小,为正奇数
其余参数一般默认。
(2)cv::Scharr (InputArray Src ,OutputArray dst,int depth,Int dx,int dy,double scale = 1,double delta = 0,int borderType = BORDER_DEFAULT)
由于内核大小为3*3,其余参数与Sobel一致
(3)操作步骤
GaussianBlur(src, dst, Size(3, 3), 0, 0.0);//第一步降噪先用高斯模糊
cvtColor(dst, srcGray, CV_BGR2GRAY);//第二步转化为灰度图像
addWeighted(xgrad, 0.5, ygrad, 0.5, 0.0, xygrad);//合成
convertScaleAbs(A, B)// 计算图像A的像素绝对值,输出到图像B
5.代码实现
#include "stdafx.h"
#include <opencv2/opencv.hpp>
#include <iostream>
#include <math.h>
using namespace std;
using namespace cv;
char inputName[] = "input name";
char outputName[] = "output name";
int main()
{
Mat src, dst;
src = imread("D:/demo.jpg");
if (src.empty())
{
cout << "找不到图像" << endl;
return -1;
}
namedWindow(inputName, CV_WINDOW_AUTOSIZE);
imshow(inputName, src);
namedWindow(outputName, CV_WINDOW_AUTOSIZE);
//第一步降噪先用高斯模糊
GaussianBlur(src, dst, Size(3, 3), 0, 0.0);
imshow(outputName, dst);
//第二步转化为灰度图像
Mat srcGray;
cvtColor(dst, srcGray, CV_BGR2GRAY);
//第三步X,Y方向分别进行Sobel求导
Mat xgrad, ygrad;
Sobel(srcGray, xgrad, CV_32F,1, 0, 3);
Sobel(srcGray, ygrad, CV_32F,0, 1, 3);
convertScaleAbs(xgrad, xgrad);//所有像素值取正数,显出跃迁为负数的差值
convertScaleAbs(ygrad, ygrad);
imshow("xgrad", xgrad);
imshow("ygrad", ygrad);
Mat xygrad;
addWeighted(xgrad, 0.5, ygrad, 0.5, 0.0, xygrad);//合成图
imshow("xygrad", xygrad);
第三步使用改进方法Scharr
//Mat xgrad, ygrad;
//Scharr(srcGray, xgrad, CV_16S, 1, 0);
//Scharr(srcGray, ygrad, CV_16S, 0, 1);
//convertScaleAbs(xgrad, xgrad);//所有像素值取正数,显出跃迁为负数的差值
//convertScaleAbs(ygrad, ygrad);
//imshow("xgrad", xgrad);
//imshow("ygrad", ygrad);
//Mat xygrad;
//addWeighted(xgrad, 0.5, ygrad, 0.5, 0.0, xygrad);//合成图
//imshow("xygrad", xygrad);
waitKey(0);
return 0;
}
6.运行结果
最后
以上就是机灵星星为你收集整理的opencv学习笔记(十八)图像边缘提取-Sobel算子的全部内容,希望文章能够帮你解决opencv学习笔记(十八)图像边缘提取-Sobel算子所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复