美文网首页游戏王的故事
openCV:图像的梯度

openCV:图像的梯度

作者: SwiftBirds | 来源:发表于2019-09-25 08:01 被阅读0次

sobel算子

定义

Sobel 算子是一个主要用作边缘检测的离散微分算子 (discrete differentiation operator)。 它Sobel算子结合了高斯平滑和微分求导,用来计算图像灰度函数的近似梯度。在图像的任何一点使用此算子,将会产生对应的梯度矢量或是其法矢量。

步骤

我们假设被作用图像为 I.然后进行如下的操作:

  1. 分别在x和y两个方向求导。
    • 水平变化: 将 I 与一个奇数大小的内核进行卷积。
    • 垂直变化: 将: I 与一个奇数大小的内核进行卷积。
sobel_1.png
  1. 在图像的每一点,结合以上两个结果求出近似梯度
sobel算子公式1.PNG sobel算子公式2.PNG

API

dst = cv2.Sobel(src, ddepth, dx, dy, ksize)

  • ddepth:图像的深度
  • dx和dy分别表示水平和竖直方向
  • ksize是Sobel算子的大小

实例

import cv2 #opencv读取的格式是BGR
import numpy as np
import matplotlib.pyplot as plt#Matplotlib是RGB
%matplotlib inline 

def cv_showimg(name,img):
    cv2.imshow(name, img)
    cv2.waitKey(0)
    cv2.destroyAllWindows()

原图

img = cv2.imread('pie.png',cv2.IMREAD_GRAYSCALE)
cv_showimg('img',img)
原图.PNG

水平方向

由sobel算子的卷积核可知,它是固定右减左的,白到黑是正数,黑到白就是负数了,所有的负数会被截断成0,所以实战时通常要做绝对值处理

# 不做绝对值处理
obelx = cv2.Sobel(img,cv2.CV_64F,1,0,ksize=3)
cv_showimg('sobelx',sobelx)
sobel水平方向-不取绝对值.PNG
# 绝对值处理
sobelx = cv2.Sobel(img,cv2.CV_64F,1,0,ksize=3)
sobelx = cv2.convertScaleAbs(sobelx)
cv_showimg('sobelx',sobelx)
水平方向-绝对值处理.PNG

垂直方向

与水平方向同理

sobely = cv2.Sobel(img,cv2.CV_64F,0,1,ksize=3)
sobely = cv2.convertScaleAbs(sobely)  
cv_showimg('sobely',sobely)
垂直方向.PNG

结果相加

将两个方向的结果整合到一起,有两种方法:

  • 分别计算x和y,再求和。
  • 直接计算,结果不好,不建议这么做。
# 方法一:分开计算
sobelxy = cv2.addWeighted(sobelx,0.5,sobely,0.5,0)
cv_showimg('sobelxy',sobelxy)
分开计算效果图.PNG
# 方法二:直接计算
sobelxy=cv2.Sobel(img,cv2.CV_64F,1,1,ksize=3)
sobelxy = cv2.convertScaleAbs(sobelxy) 
cv_showimg('sobelxy',sobelxy)
直接计算.PNG

Scharr算子

概念

当内核大小为 3 时, 我们的Sobel内核可能产生比较明显的误差(毕竟,Sobel算子只是求取了导数的近似值而已)。 为解决这一问题,OpenCV提供了Scharr 函数,但该函数仅作用于大小为3的内核。该函数的运算与Sobel函数一样快,但结果却更加精确,其内核是这样的:

Scharr算子

因为Sobel算子结合了高斯平滑和分化(differentiation),因此结果会具有更多的抗噪性。大多数情况下,我们使用sobel函数

API

dst = cv2.Scharr(src, ddepth, dx, dy)

  • ddepth:图像的深度
  • dx和dy分别表示水平和竖直方向
  • 没有ksize,因为它的内核大小固定为3

实例

scharrx = cv2.Scharr(img,cv2.CV_64F,1,0)
scharry = cv2.Scharr(img,cv2.CV_64F,0,1)
scharrx = cv2.convertScaleAbs(scharrx)   
scharry = cv2.convertScaleAbs(scharry)  
scharrxy =  cv2.addWeighted(scharrx,0.5,scharry,0.5,0) 
cv_showimg('scharrxy',scharrxy)
scharr算子结果.PNG

laplacian算子

概念

Laplacian 算子是n维欧几里德空间中的一个二阶微分算子,定义为梯度grad()的散度div()。因此如果f是二阶可微的实函数,则f的拉普拉斯算子定义为:

  1. f的拉普拉斯算子也是笛卡儿坐标系xi中的所有非混合二阶偏导数求和:

  2. 作为一个二阶微分算子,拉普拉斯算子把C函数映射到C函数,对于k ≥ 2。表达式(1)(或(2))定义了一个算子Δ :C(R) → C(R),或更一般地,定义了一个算子Δ : C(Ω) → C(Ω),对于任何开集Ω。

根据图像处理的原理我们知道,二阶导数可以用来进行检测边缘 。 因为图像是 “二维”, 我们需要在两个方向进行求导。使用Laplacian算子将会使求导过程变得简单。

Laplacian 算子的定义:


拉普拉斯算子

API

dst = cv2.Laplacian(src, ddepth)

  • ddepth:图像的深度

实例

laplacian = cv2.Laplacian(img,cv2.CV_64F)
laplacian = cv2.convertScaleAbs(laplacian)  
cv_showimg('laplacian',laplacian)
拉普拉斯算子结果图.PNG

三种算子在实际图中的比较

scharr算子比sobel算子更关注细节,边界信息更细致。
laplacian算子单独使用效果并不是很好,要结合其它的算法一起使用。

img = cv2.imread('lena.jpg',cv2.IMREAD_GRAYSCALE)
sobelx = cv2.Sobel(img,cv2.CV_64F,1,0,ksize=3)
sobely = cv2.Sobel(img,cv2.CV_64F,0,1,ksize=3)
sobelx = cv2.convertScaleAbs(sobelx)   
sobely = cv2.convertScaleAbs(sobely)  
sobelxy =  cv2.addWeighted(sobelx,0.5,sobely,0.5,0)  

scharrx = cv2.Scharr(img,cv2.CV_64F,1,0)
scharry = cv2.Scharr(img,cv2.CV_64F,0,1)
scharrx = cv2.convertScaleAbs(scharrx)   
scharry = cv2.convertScaleAbs(scharry)  
scharrxy =  cv2.addWeighted(scharrx,0.5,scharry,0.5,0) 

laplacian = cv2.Laplacian(img,cv2.CV_64F)
laplacian = cv2.convertScaleAbs(laplacian)   

res = np.hstack((sobelxy,scharrxy,laplacian))
cv_showimg('res',res)
三种算子的比较图.PNG

相关文章

  • 1.12 openCV-python 图像梯度

    图像梯度 梯度简单来说就是求导,openCV提供了三种不同的梯度滤波器;Sobel/Scharr/Laplacian

  • opencv图像梯度

    原理 梯度简单来说就是求导。OpenCV 提供了三种不同的梯度滤波器,或者说高通滤波器:Sobel,Scharr ...

  • openCV:图像的梯度

    sobel算子 定义 Sobel 算子是一个主要用作边缘检测的离散微分算子 (discrete different...

  • 图像梯度

    图像梯度 梯度简单来说就是求导。OpenCV 提供了三种不同的梯度滤波器,或者说高通滤波器:Sobel,Schar...

  • OpenCV--图像梯度处理

    图像梯度-Sobel(索贝尔)算子[https://img2018.cnblogs.com/i-beta/1617...

  • opencv+python -- 图像梯度

    图像梯度可以把图像看成二维离散函数,图像梯度其实就是这个二维离散函数的求导。 Sobel算子是普通一阶差分,是基于...

  • Python+OpenCV教程番外篇8:图像梯度

    主站:http://ex2tron.wang原文:Python+OpenCV教程番外篇8:图像梯度 (数学公式显示...

  • 图像梯度与Sobel滤波器---OpenCV-Python开发指

    图像梯度 图像梯度计算的是图像变化的速度。对于图像的边缘部分,其灰度值变化较大,梯度值也较大;相反,对于图像中比较...

  • opencv+python求图像梯度

    由于对图像求导后,结果有正有负,且有可能超出255,所以求梯度时要注意像素的数值类型,这里给出两种解决方法: 求梯...

  • openCV

    Opencv2图像裁剪(子图像提取) opencv之读取图像 #######opencv读取图像的灰度值并显示出来...

网友评论

    本文标题:openCV:图像的梯度

    本文链接:https://www.haomeiwen.com/subject/pdlpuctx.html