opencv3.1学习笔记(17) Sobel算子


演示代码:

#include <opencv2/opencv.hpp>
#include <iostream>
#include <math.h>

using namespace cv;

int main(int argc, char** argv) {
	Mat src, dst,dst2,dst3,dst4,dst5,dst6,dst7;
	src = imread("e:/girl.png");
	if (!src.data) {
		printf("could not load image...\n");
		return -1;
	}
	
	Mat gray;
	GaussianBlur(src, dst, Size(3, 3), 0, 0);
	cvtColor(dst, gray, CV_BGR2GRAY);
	imshow("gray", gray);
	
	//测试Sobel
	Mat xgrad, ygrad;
	Sobel(gray, xgrad, CV_16S, 1, 0,3);
	Sobel(gray, ygrad, CV_16S, 0, 1,3);
	//如果没有下面两句,则Sobel的结果太暗,看不到效果
	convertScaleAbs(xgrad, xgrad);
	convertScaleAbs(ygrad, ygrad);
	Mat xygrad = Mat(xgrad.size(), xgrad.type());
	//合并出xygrad
	addWeighted(xgrad, 0.5, ygrad, 0.5, 0, xygrad);
	imshow("xgrad", xgrad);
	imshow("ygrad", ygrad);
	imshow("xygrad", xygrad);

	//手工实现xgrad,ygrad混合
	Mat xygrad3 = Mat(xgrad.size(), xgrad.type());
	for (int x = 0; x < xgrad.rows; x++) {
		for (int y = 0; y < xgrad.cols; y++) {
			int xg = xgrad.at<uchar>(x, y);
			int yg = xgrad.at<uchar>(x, y);
			int xy = xg + yg;
			xygrad3.at<uchar>(x, y) = saturate_cast<uchar>(xy);
		}
	}
	imshow("手工实现addWeighted", xygrad3);

	//测试Scharr,OpenCV中增强版的Sobel
	Mat xgrad2, ygrad2, xygrad2;
	Scharr(gray, xgrad2, CV_16S, 1, 0);
	Scharr(gray, ygrad2, CV_16S, 0, 1);
	convertScaleAbs(xgrad2, xgrad2);
	convertScaleAbs(ygrad2, ygrad2);
	addWeighted(xgrad2, 0.5, ygrad2, 0.5, 0, xygrad2);
	imshow("xgrad2", xgrad2);
	imshow("ygrad2", ygrad2);
	imshow("xygrad2", xygrad2);



	waitKey(0);
	return 0;
}


image.png

(高斯滤波后的灰度图)

image.png

(Sobel算子求出的, x梯度、y梯度、 addWeighted函数混合后的xy梯度)

image.png

(手工实现的x,y梯度混合)


image.png

(算子Scharr实现的增强Sobel效果:x梯度、y梯度、xy混合梯度)


代码解释:


卷积应用-图像边缘提取

image.png


  • 边缘是什么 – 是像素值发生跃迁的地方,是图像的显著特征之一,在图像特征提取、对象检测、模式识别等方面都有重要的作用。

  • 如何捕捉/提取边缘 – 对图像求它的一阶导数

  delta =  f(x) – f(x-1), delta越大,说明像素在X方向变化越大,边缘信号越强,


Sobel算子

  • 是离散微分算子(discrete differentiation operator),用来计算图像灰度的近似梯度

  • Soble算子功能集合高斯平滑和微分求导

  • 又被称为一阶微分算子,求导算子,在水平和垂直两个方向上求导,得到图像X方法与Y方向梯度图像


水平梯度

image.png

垂直梯度

image.png

最终图像梯度

两个公式都可以用,最下面绝对值相加是为了加快执行速度的选择。

image.png

  • 求取导数的近似值,kernel=3时不是很准确,OpenCV使用改进版本Scharr函数,算子如下:

image.png

API说明

cv::Sobel (
InputArray Src // 输入图像
OutputArray dst// 输出图像,大小与输入图像一致
int depth // 输出图像深度. 
Int dx.  // X方向,几阶导数
int dy // Y方向,几阶导数. 
int ksize, SOBEL算子kernel大小,必须是1、3、5、7、
double scale  = 1
double delta = 0
int borderType = BORDER_DEFAULT
)
cv::Scharr (
InputArray Src // 输入图像
OutputArray dst// 输出图像,大小与输入图像一致
int depth // 输出图像深度. 
Int dx.  // X方向,几阶导数
int dy // Y方向,几阶导数. 
double scale  = 1
double delta = 0
int borderType = BORDER_DEFAULT
)


其它API

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

cvtColor( src,  gray, COLOR_RGB2GRAY );

addWeighted( A, 0.5,B, 0.5, 0, AB);

convertScaleAbs(A, B)// 计算图像A的像素绝对值,输出到图像B


--------------------- 

作者:hackpig

来源:www.skcircle.com

版权声明:本文章代码及资料部分或全部来自贾志刚老师的视频,勇哥只是在个人理解的基础上做学习笔记,转载请附上博文链接!

本文出自勇哥的网站《少有人走的路》wwww.skcircle.com,转载请注明出处!讨论可扫码加群:

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

会员中心
搜索
«    2025年4月    »
123456
78910111213
14151617181920
21222324252627
282930
网站分类
标签列表
最新留言
    热门文章 | 热评文章 | 随机文章
文章归档
友情链接
  • 订阅本站的 RSS 2.0 新闻聚合
  • 扫描加本站机器视觉QQ群,验证答案为:halcon勇哥的机器视觉
  • 点击查阅微信群二维码
  • 扫描加勇哥的非标自动化群,验证答案:C#/C++/VB勇哥的非标自动化群
  • 扫描加站长微信:站长微信:abc496103864
  • 扫描加站长QQ:
  • 扫描赞赏本站:
  • 留言板:

Powered By Z-BlogPHP 1.7.2

Copyright Your skcircle.com Rights Reserved.

鄂ICP备18008319号


站长QQ:496103864 微信:abc496103864