本文将介绍图像梯度的应用以及一些相关梯度算子的实现

一、什么是梯度?

梯度不是一个实数,它是一个有大小有方向的向量。现在以一个二元函数举例,假设一个二元函数f(x,y),在某点的梯度有:

整理后得到:

其实就是它的方向导数。梯度的方向是函数变化最快的方向,沿着梯度的方向容易找到最大值。

二、图像梯度

在一副模糊图像中的物体的轮廓不明显,轮廓边缘灰度变化不强烈,从而导致层次感不强,而在清晰图像中的物体轮廓边缘灰度变化明显,层次感强。那么这种灰度变化明显不明显怎么去定义呢?

可以使用导数(梯度),衡量图像灰度的变化率,因为图像就是函数。正因如此,我们引入的图像梯度可以把图像看成二维离散函数,图像梯度其实就是这个二维离散函数的求导。

在上边这幅图中可以看出,如果一副图像的相邻灰度值有变化,那么梯度就存在,如果图像相邻的像素没有变化,那么梯度就是0.

把梯度值和相应的像素相加,那么灰度值没有变化的,像素就没有变化,灰度值变了,像素值也就变了。我们看到,相加后的新图像,原图像像素点100与90亮度只相差10,现在是110与90,亮度相差20了,对比度显然增强了,尤其是图像中物体的轮廓和边缘,与背景大大加强了区别,这就是用梯度来增强图像的原理。将图像函数f(x,y)梯度表达式表示出来:

幅度

ps:mag函数可以将向量转化为浮点数

方向角

对于数字图像来说,相当于是二维离散函数求梯度,使用差分来近似导数

因此,像素点(x,y)处的梯度值梯度方向分别是:

这里的平方+开方的,计算量太大,于是一般用绝对值来近似平方和平方根的操作,来降低计算量:

在上述的推论中我们得到,梯度的方向是函数变化最快的方向,所以当函数中存在边缘时,一定有较大的梯度值,相反,当图像中有比较平滑的部分时,灰度值变化较小,则相应的梯度也较小。图像处理中把梯度的模简称为梯度,由图像梯度构成的图像成为梯度图像。

一些经典的图像梯度算法是考虑图像的每个像素的某个邻域内的灰度变化,利用边缘临近的一阶或二阶导数变化规律,对原始图像中像素某个邻域设置梯度算子,通常我们用小区域模板进行卷积来计算,有Sobel算子、Robinson算子、Laplace算子等。

三、经典算子介绍

本文暂且先介绍sobel算子

sobel算子,主要用作边缘检测,是离散差分算子,用来运算图像梯度函数的灰度近似值。在图像的任何一点使用此算子,将会产生对应的梯度矢量或者法矢量。

书上的sobel模板不是卷积模板,而是协相关模板,卷积的话要先将模板旋转180度以后再与图像做相关操作。

Gx方向的相关模板:

Gy方向的相关模板:

Sobel的卷积模板Gx:

sobel卷积模板Gy:

具体计算为,每个像素(灰度值)与模板对应位置元素相乘求和(类似于CNN中的卷积,其实是协相关运算),来计算该点灰度的大小:

通常,为了提高效率使用不开平方的近似值:

然后可用以下公式计算梯度方向:

四、算法的实现

1:soble算子

代码:

import cv2 as cv
# sobel算子
def sobel_demo(image):grad_x = cv.Sobel(image, cv.CV_32F, 1, 0) #对x求一阶导,CV_32F输出图像深度grad_y = cv.Sobel(image, cv.CV_32F, 0, 1) #对y求一阶导gradx = cv.convertScaleAbs(grad_x)  # 用convertScaleAbs()函数将其转回原来的uint8形式grady = cv.convertScaleAbs(grad_y)cv.imshow("gradient_x", gradx) #x方向上的梯度cv.imshow("gradient_y", grady)  #y方向上的梯度gradxy = cv.addWeighted(gradx, 0.5, grady, 0.5, 0)  # 图片融合cv.imshow("gradient", gradxy)src = cv.imread('Butterfly.png')
cv.namedWindow('input_image', cv.WINDOW_NORMAL) #设置为WINDOW_NORMAL可以任意缩放
cv.imshow('input_image',src)
sobel_demo(src)
cv.waitKey(0)
cv.destroyAllWindows()

效果图:

2: Scharr算子

Scharr算子是sobel算子的增强版,效果更突出

import cv2 as cv
#Scharr算子(Sobel算子的增强版,效果更突出)
def Scharr_demo(image):grad_x = cv.Scharr(image, cv.CV_32F, 1, 0)   #对x求一阶导grad_y = cv.Scharr(image, cv.CV_32F, 0, 1)   #对y求一阶导gradx = cv.convertScaleAbs(grad_x)  #用convertScaleAbs()函数将其转回原来的uint8形式grady = cv.convertScaleAbs(grad_y)cv.imshow("gradient_x", gradx)  #x方向上的梯度cv.imshow("gradient_y", grady)  #y方向上的梯度gradxy = cv.addWeighted(gradx, 0.5, grady, 0.5, 0)cv.imshow("gradient", gradxy)
src = cv.imread('Butterfly.png')
cv.namedWindow('input_image', cv.WINDOW_NORMAL) #设置为WINDOW_NORMAL可以任意缩放
cv.imshow('input_image', src)
Scharr_demo(src)
cv.waitKey(0)
cv.destroyAllWindows()

效果图:

3:拉普拉斯算子

Laplacian使用了图像梯度,它内部的代码其实是调用了 Sobel 算子的。

Laplacian( )函数其实主要是利用sobel算子的运算。它通过加上sobel算子运算出的图像x方向和y方向上的导数,来得到我们输入图像的拉普拉斯变换结果。

代码如下:

import cv2 as cv
#拉普拉斯算子
def Laplace_demo(image):dst = cv.Laplacian(image, cv.CV_32F)lpls = cv.convertScaleAbs(dst)cv.imshow("Laplace_demo", lpls)
src = cv.imread('1.png')
cv.namedWindow('input_image', cv.WINDOW_NORMAL) #设置为WINDOW_NORMAL可以任意缩放
cv.imshow('input_image', src)
Laplace_demo(src)
cv.waitKey(0)
cv.destroyAllWindows()

效果图:

图像梯度的解释及相关梯度算子的实现相关推荐

  1. python-opencv之图像梯度Sobel、Scharr、Laplacian算子边缘检测

    Sobel算子 是离散微分算子(discrete differentiation operator),用来计算图像灰度的近似梯度,梯度越大越有可能是边缘. Soble算子的功能集合了高斯平滑和微分求导 ...

  2. (四)图像的空域锐化_一阶梯度算子

    一,实验原理 图像锐化:增强图像的边缘或轮廓. 图像平滑通过积分过程使得图像边缘模糊,图像锐化则通过微分而使图像边缘突出.清晰. 梯度锐化法: 图像处理中应用微分最常用的方法是计算梯度.对于图像f(x ...

  3. RNN梯度爆炸原因和LSTM解决梯度消失解释

    RNN梯度爆炸原因: 经典的RNN结构如下图所示: 假设我们的时间序列只有三段, 为给定值,神经元没有激活函数,则RNN最简单的前向传播过程如下: 假设在t=3时刻,损失函数为 . 则对于一次训练任务 ...

  4. 图像学习之如何理解方向梯度直方图HOG(Histogram Of Gradient)

    本文转自:雷锋网,作者:思颖.连接:https://yq.aliyun.com/articles/176607,https://www.leiphone.com/news/201708/ZKsGd2J ...

  5. 图像学习之如何理解方向梯度直方图(Histogram Of Gradient)

    特征描述子(Feature Descriptor) 特征描述子就是图像的表示,抽取了有用的信息,丢掉了不相关的信息.通常特征描述子会把一个w*h*3(宽高3,3个channel)的图像转换成一个长度为 ...

  6. 解释为什么用梯度下降而不是直接求导数为0的解

    问题: 在计算线性回归最大似然估计的解的时候,最后的推导结果是 为什么不直接求出θ?而是一步步迭代求出θ? 原因 因此,梯度下降可以节省大量的计算时间.此外,它的完成方式允许一个简单的并行化,即在多个 ...

  7. 获取图像的梯度,方向和方向梯度图像

    %获取图像的梯度,方向和方向梯度图像 clc,clear,close all; Image = rgb2gray(imread('pic01.bmp')); [Gx,Gy] = imgradientx ...

  8. ng机器学习视频笔记(二) ——梯度下降算法解释以及求解θ

    ng机器学习视频笔记(二) --梯度下降算法解释以及求解θ (转载请附上本文链接--linhxx)   一.解释梯度算法 梯度算法公式以及简化的代价函数图,如上图所示. 1)偏导数 由上图可知,在a点 ...

  9. 图像处理中的梯度、导数如何求?(Robert算子,Sobel算子,Prewitt算子,Laplace算子)

    梯度的求法是多种多样的,根据不同的处理需要选择合适的算子(模版). 1.水平垂直差分法 2.Robert 梯度算子 3.Sobel算子               垂直方向               ...

最新文章

  1. node.js是开源的吗_为开源做贡献并不难:我为Node.js项目做贡献的旅程
  2. java jdbc连接数据库的设计
  3. SAP用户信息查询的几张表
  4. html5行级标签,8、html5哪些标签时块级、行内、行内块?2021-01-30
  5. .Net Core Swagger:Actions require an explicit HttpMethod binding for Swagger 2.0
  6. 再送一波干货,测试2000线程并发下同时查询1000万条数据库表及索引优化
  7. MHA manage节点安装报错解决
  8. Ubuntu16.04 sudo apt-get install lib***-dev安装失败,无法锁定文件,sudo apt-get update 更新失败也无法解决
  9. HDX RealTime 避免回音
  10. PageHelper分页插件踩坑--最后一页查询效率低下
  11. 动手学树莓派第1章:先唠叨两句
  12. ftp误删服务器文件恢复,ftp服务器文件误删
  13. 毕业论文的奋斗记(一)
  14. windows server 2008 enterprise r2 x64 激活小记
  15. 深度揭秘腾讯云新一代企业级HTAP数据库TBase核心概念
  16. [已解决] c#签名时出错
  17. 中心极限与大数定理律的关系_中心极限定理(CLT)?2个例子帮你轻松理解CLT...
  18. 做bs开发需要学习哪些技术
  19. 关于微信分享接口,手机分享时候描述变链接的解决方法以及图片logo不显示问题解决方法
  20. 第十四届蓝桥杯三月真题刷题训练——第 7 天

热门文章

  1. 解决maven引入swagger2markup 包报错问题
  2. Android 添加、移除桌面快捷方式图标
  3. Android Studio之——问题集合及解决方法(对号入座)
  4. vue——keepAlive使用详解
  5. [蓝桥杯][2014年第五届真题]地宫取宝
  6. STM32 CAN通信理解(是半双工还是全双工?)
  7. P1026 统计单词个数
  8. java drawimage 本地,java drawimage()方法
  9. 淘宝商品数据分析怎么操作?从哪些方面下手?
  10. 写一篇哈利波特的同人文