OpenCV-Python实现图像梯度与Sobel滤波器

图像梯度

图像梯度计算的是图像变化的速度。对于图像的边缘部分,其灰度值变化较大,梯度值也较大;相反,对于图像中比较平滑的部分,其灰度值变化较小,相应的梯度值也较小。一般情况下,图像的梯度计算是图像的边缘信息。

其实梯度就是导数,但是图像梯度一般通过计算像素值的差来得到梯度的近似值,也可以说是近似导数。该导数可以用微积分来表示。

在微积分中,一维函数的一阶微分的基本定义是这样的:

而图像是一个二维函数f(x,y),其微分当然就是偏微分。因此有:

因为图像是一个离散的二维函数,ϵ不能无限小,我们的图像是按照像素来离散的,最小的ϵ就是1像素。因此,上面的图像微分又变成了如下的形式(ϵ=1):

这分别是图像在(x, y)点处x方向和y方向上的梯度,从上面的表达式可以看出来,图像的梯度相当于2个相邻像素之间的差值。

那么,这个梯度(或者说灰度值的变化率)如何增强图像的清晰度呢?

我们先考虑下x方向,选取某个像素,假设其像素值是100,沿x方向的相邻像素分别是90,90,90,则根据上面的计算其x方向梯度分别是10,0,0。这里只取变化率的绝对值,表明变化的大小即可。

我们看到,100和90之间亮度相差10,并不是很明显,与一大群90的连续灰度值在一起,轮廓必然是模糊的。我们注意到,如果相邻像素灰度值有变化,那么梯度就有值,如果相邻像素灰度值没有变化,那么梯度就为0。如果我们把梯度值与对应的像素相加,那么灰度值没有变化的,像素值不变,而有梯度值的,灰度值变大了。

我们看到,相加后的新图像,原图像像素点100与90亮度只相差10,现在是110与90,亮度相差20了,对比度显然增强了,尤其是图像中物体的轮廓和边缘,与背景大大加强了区别,这就是用梯度来增强图像的原理。

上面只是说了x方向,y方向是一样的。那么能否将x方向和y方向的梯度结合起来呢?当然是可以的。x方向和y方向上的梯度可以用如下式子表示在一起:

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

原理了解后,我们来了解一些OpenCV提供了哪些梯度滤波器?

在OpenCV中,它给我们提供了三种不同的梯度滤波器,或者说高通滤波器:Sobel,Scharr 和Laplacian。什么叫高通呢?其实就是和图像模糊相反。图像模糊是让低频通过,阻挡高频,这样就可以去除噪点,让锐利的边缘变平滑。高通滤波器就是让高频通过,阻挡低频,可以让边缘更加明显,增强图像。

Sobel滤波器

Sobel滤波器是一种离散的微分算子,该算子结合了高斯平滑和微分求导运算。该算子利用局部差分寻找边缘,计算所得的是一个梯度的近似值。

具体的原理如下:

将Sobel滤波器与原始图像进行卷积计算,可以计算水平方向上的像素值变化情况。例如,当Sobel滤波器的大小为3*3时,水平方向偏导数的计算方式如下:

如果需要计算P5水平方向偏导数(梯度),则公式如下:

P5x=(P3-P1)+2*(P6-P4)+(P9-P7)

如果需要计算P5垂直方向偏导数(梯度),则公式如下:

P5y=(P7-P1)+2*(P8-P2)+(P9-P3)

在OpenCV中,它给我们提供cv2.Sobel()函数实现Sobel滤波器,其函数定义如下:

def Sobel(src, ddepth, dx, dy, dst=None, ksize=None, scale=None, delta=None, borderType=None):

src:原始图像

ddepth:输出图像的深度,详细取值如下表:

输入图像深度 输出图像深度
cv2.CV_8U -1/cv2.CV_16S/cv2.CV_32F/cv2/CV_64F
cv2.CV_16U/cv2.CV_16S -1/cv2.CV_32F/cv2.CV_64F
cv2.CV_32F -1/cv2.CV_32F/cv2.CV_64F
cv2.CV_64F -1/cv2.CV_64F

dx:代表X方向的求导阶数

dy:代表Y方向的求导阶数

ksize:Sobel核的大小,该值为-1时,则会使用Sobel滤波器进行运算

scale:计算导数值所采用的缩放因子,默认值为1,时没有缩放的

delta:加载目标图像上的值,该值可选,默认为0

borderType:边界样式,前面博文有详细介绍,这里不在赘述。

需要注意的是,如果将ddepth参数设置为-1,让处理结果与原图像保持一致,可以会得到错误的结果。实际上,这么做会导致梯度值可能出现负数。如果处理的是8位图像,意味着指定运算的结果也是8位图类型,那么所有的负数会自动截断为0,发生信息丢失。为了避免信息丢失,在计算时先使用更高的数据类型cv2.CV_64F,再通过取绝对值将其映射为cv2.CV_8U类型。所以,我们使用Sobel滤波器常常会将ddepth设置为cv2.CV_64F。

计算X方向梯度语法格式为:

cv2.Sobel(src,ddepth,1,0)

计算Y方向梯度语法格式为:

cv2.Sobel(src,ddepth,0,1)

计算XY方向梯度语法格式为:

cv2.Sobel(src,ddepth,1,1)

计算XY叠加梯度语法格式为:

dx=cv2.Sobel(src,ddepth,1,0)
dy=cv2.Sobel(src,ddepth,0,1)
dst=cv2.addWeighted(src1,alpha,src2,beta,gamma)

因为可能会出现负数,我们还需要使用另一个函数取绝对值,该函数为:cv2.convertScaleAbs(),其完整定义如下:

def convertScaleAbs(src, dst=None, alpha=None, beta=None):

alpha:调节系数,可选值,默认为1

beta:调节亮度值,默认为0

下面,我们来使用Sobel滤波器,获取图像水平方向的边缘信息,代码如下:

import cv2

img = cv2.imread("4.jpg", cv2.IMREAD_UNCHANGED)
sobel_x=cv2.Sobel(img,cv2.CV_64F,1,0)
result=cv2.convertScaleAbs(sobel_x)
cv2.imshow("img", img)
cv2.imshow("result", result)
cv2.waitKey()
cv2.destroyAllWindows()

运行之后,效果如下所示:

接着,我们来使用Sobel滤波器,获取图像垂直方向的边缘信息,代码如下:

import cv2

img = cv2.imread("4.jpg", cv2.IMREAD_UNCHANGED)
sobel_y=cv2.Sobel(img,cv2.CV_64F,0,1)#更改这一行就行
result=cv2.convertScaleAbs(sobel_y)
cv2.imshow("img", img)
cv2.imshow("result", result)
cv2.waitKey()
cv2.destroyAllWindows()

运行之后,效果如下:

接着,我们来计算XY方向梯度,代码如下:

import cv2

img = cv2.imread("4.jpg", cv2.IMREAD_UNCHANGED)
sobel_xy=cv2.Sobel(img,cv2.CV_64F,1,1)#都设置为1
result=cv2.convertScaleAbs(sobel_xy)
cv2.imshow("img", img)
cv2.imshow("result", result)
cv2.waitKey()
cv2.destroyAllWindows()

运行之后,效果如下:

最后,我们来计算其水平垂直两个方向的叠加边缘信息,代码如下:

import cv2

img = cv2.imread("4.jpg", cv2.IMREAD_UNCHANGED)
sobel_x=cv2.Sobel(img,cv2.CV_64F,1,0)
sobel_y=cv2.Sobel(img,cv2.CV_64F,0,1)
abx_x=cv2.convertScaleAbs(sobel_x)
abx_y=cv2.convertScaleAbs(sobel_y)
result=cv2.addWeighted(sobel_x,0.5,sobel_y,0.5,0)
cv2.imshow("img", img)
cv2.imshow("result", result)
cv2.waitKey()
cv2.destroyAllWindows()

运行之后,效果如下:

到此这篇关于OpenCV-Python实现图像梯度与Sobel滤波器的文章就介绍到这了,更多相关OpenCV 图像梯度与Sobel滤波器内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • opencv python图像梯度实例详解

    这篇文章主要介绍了opencv python图像梯度实例详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 一阶导数与Soble算子 二阶导数与拉普拉斯算子 图像边缘: Soble算子: 二阶导数: 拉普拉斯算子: import cv2 as cv import numpy as np # 图像梯度(由x,y方向上的偏导数和偏移构成),有一阶导数(sobel算子)和二阶导数(Laplace算子) # 用于求解图像边缘,一阶的极大值,二阶的零点

  • OpenCV-Python实现图像梯度与Sobel滤波器

    图像梯度 图像梯度计算的是图像变化的速度.对于图像的边缘部分,其灰度值变化较大,梯度值也较大:相反,对于图像中比较平滑的部分,其灰度值变化较小,相应的梯度值也较小.一般情况下,图像的梯度计算是图像的边缘信息. 其实梯度就是导数,但是图像梯度一般通过计算像素值的差来得到梯度的近似值,也可以说是近似导数.该导数可以用微积分来表示. 在微积分中,一维函数的一阶微分的基本定义是这样的: 而图像是一个二维函数f(x,y),其微分当然就是偏微分.因此有: 因为图像是一个离散的二维函数,ϵ不能无限小,我们的图

  • OpenCV学习之图像梯度算子详解

    目录 1.Sobel算子 2.Scharr算子 3.laplacian算子 本文是OpenCV图像视觉入门之路的第12篇文章,本文详细的介绍了图像梯度算子的各种操作,例如:Sobel算子Scharr算子laplacian算子等操作. 1.Sobel算子 Sobel算子是一种图像边缘检测算子,它是一种空间滤波器,可以检测图像中的边缘,而梯度运算是一种求导数的方法,可以用来检测图像中的局部变化. import cv2 import numpy as np from numpy import unic

  • Opencv+Python实现图像运动模糊和高斯模糊的示例

    运动模糊:由于相机和物体之间的相对运动造成的模糊,又称为动态模糊 Opencv+Python实现运动模糊,主要用到的函数是cv2.filter2D(): # coding: utf-8 import numpy as np import cv2 def motion_blur(image, degree=12, angle=45): image = np.array(image) # 这里生成任意角度的运动模糊kernel的矩阵, degree越大,模糊程度越高 M = cv2.getRotat

  • OpenCV Python实现图像指定区域裁剪

    在工作中.在做数据集时,需要对图片进行处理,照相的图片我们只需要特定的部分,所以就想到裁剪一种所需的部分.当然若是图片有规律可循则使用opencv对其进行膨胀腐蚀等操作.这样更精准一些. 一.指定图像位置的裁剪处理 import os import cv2 # 遍历指定目录,显示目录下的所有文件名 def CropImage4File(filepath,destpath): pathDir = os.listdir(filepath) # 列出文件路径中的所有路径或文件 for allDir i

  • python中的opencv 图像梯度

    目录 图像梯度 Sobel理论基础 计算水平方向偏导数的近似值 计算垂直方向偏导数的近似值 Sobel算子及函数使用 方向 计算x方向和y方向的边缘叠加 Scharr算子及函数使用 Sobel算子和Scharr算子的比较 Laplacian算子及函数使用 算子总结 图像梯度 图像梯度计算的是图像变化的速度.对于图像的边缘部分,其灰度值变化较大,梯度值也较大:相反,对于图像中比较平滑的部分,其灰度值变化较小,相应的梯度值也较小.图像梯度计算需要求导数,但是图像梯度一般通过计算像素值的差来得到梯度的

  • Python+OpenCV之图像梯度详解

    目录 1. Sobel算子 1.1 Sobel介绍 1.2 横向Sobel算子 1.3 纵向Sobel算子 1.4 合并横纵向的方法提取更好的边缘的结果 1.5 利用1.3方法绘制素描风格 2. Scharr算子 3. Laplacian算子 1. Sobel算子 OpenCV系列—本文底页有多个常用方法链接 1.1 Sobel介绍 cv2.Sobel(src, ddepth, dx, dy, ksize) ddepth:图像的深度 dx和dy分别表示水平和竖直方向 ksize是Sobel算子的

  • Python OpenCV学习之图像滤波详解

    目录 背景 一.卷积相关概念 二.卷积实战 三.均值滤波 四.高斯滤波 五.中值滤波 六.双边滤波 七.Sobel算子 八.Scharr算子 九.拉普拉斯算子 十.Canny算法 背景 图像滤波的作用简单来说就是将一副图像通过滤波器得到另一幅图像:明确一个概念,滤波器又被称为卷积核,滤波的过程又被称为卷积:实际上深度学习就是训练许多适应任务的滤波器,本质上就是得到最佳的参数:当然在深度学习之前,也有一些常见的滤波器,本篇主要介绍这些常见的滤波器: 一.卷积相关概念 卷积核大小一般为奇数的原因:

  • OpenCV 图像梯度的实现方法

    目录 概述 梯度运算 礼帽 黑帽 Sobel 算子 计算 x 计算 y 计算 x+y 融合 概述 OpenCV 是一个跨平台的计算机视觉库, 支持多语言, 功能强大. 今天小白就带大家一起携手走进 OpenCV 的世界. 梯度运算 梯度: 膨胀 (Dilating) - 腐蚀 (Eroding). 例子: # 读取图片 pie = cv2.imread("pie.png") # 核 kernel = np.ones((7, 7), np.uint8) # 计算梯度 gradient =

  • Python OpenCV学习之图像形态学

    目录 背景 一.图像二值化 二.自适应阈值 三.腐蚀 四.卷积核获取 五.膨胀 六.开运算 七.闭运算 八.形态学梯度 九.顶帽运算 十.黑帽运算 总结 背景 形态学处理方法是基于对二进制图像进行处理的,卷积核决定图像处理后的效果:形态学的处理哦本质上相当于对图像做前处理,提取出有用的特征,以便后续的目标识别等任务: 一.图像二值化 定义:将图像的每个像素变成两种值,如0和255: 全局二值化的函数原型: threshold(img,thresh,maxVal,type) img:最好是灰度图像

随机推荐