当前位置: 代码迷 >> 综合 >> openCV (四) 梯度计算 Sobel、Scharr、Laplacian 学习回顾记录
  详细解决方案

openCV (四) 梯度计算 Sobel、Scharr、Laplacian 学习回顾记录

热度:112   发布时间:2023-11-11 09:38:13.0

文章目录

  • 一、Sobel算子
    • (1)程序演示
    • (2)相加融合
  • 二、Scharr算子
    • (1)程序演示(相加融合和上边一样)
  • 三、Laplacian 算子
    • (1)程序演示
  • 四、三种方法的结果比较
    • (1)原图
    • (2)三种方法对比

一、Sobel算子

dst = cv2.Sobel(src,ddepth,dx,dy,ksize)
- ddepth:图像的深度
- dx和dy 分别表示水平和竖直方向
- ksize是Sobel算子的大小 (1、3、5、7)

在这里插入图片描述 在这里插入图片描述
简单理解,Sobel算子可以在两个方向上进行梯度计算,对应的 GxG_{x}Gx? 左右方向和 GyG_{y}Gy? 上下方向。

左右方向: 右减左(从卷积算子可以看出)
上下方向:下减上(从卷积算子可以看出)

(1)程序演示

# 先显示原始的圆图片import cv2img = cv2.imread("yuan.jpg",cv2.IMREAD_GRAYSCALE)
print(img.shape)
img = cv2.resize(img,(700,700))
cv2.imshow("img",img)
cv2.waitKey(0)
cv2.destroyAllWindows()def cv_show(img):cv2.imshow('name',img)cv2.waitKey(0)cv2.destroyAllWindows()

在这里插入图片描述

# 负数被截断成0,所以显示半边
sobelx = cv2.Sobel(img,cv2.CV_64F,1,0,ksize = 3) # 左右方向
cv_show(sobelx)

在这里插入图片描述

因为是右边减去左边,白减去黑是正数,黑减去白是负数,负数会被截断成0,所以要取绝对值。
#取绝对值之后,能够显示出来全部的边界 ,dx=1,dy=0, 左右,右减左
sobelx = cv2.Sobel(img,cv2.CV_64F,1,0,ksize = 3)  #左右方向
sobelx = cv2.convertScaleAbs(sobelx)
cv_show(sobelx)

在这里插入图片描述

# 负数被截断成0,所以显示半边
sobely = cv2.Sobel(img,cv2.CV_64F,0,1,ksize=3)cv_show(sobely)

在这里插入图片描述

#取绝对值之后,能够显示出来全部的边界 ,dx=0,dy=1, 上下,下减上
sobely = cv2.Sobel(img,cv2.CV_64F,0,1,ksize=3)
sobely = cv2.convertScaleAbs(sobely)
cv_show(sobely)

在这里插入图片描述

(2)相加融合

可以观察到融合之后的白色的边界更加凝实,相比于单独的 x 和 y 来说。
sobelxy = cv2.addWeighted(sobelx,0.5,sobely,0.5,0) # k1*x+k2*y+b
cv_show(sobelxy)

在这里插入图片描述

如果在程序里边同时设置 dx=1,dy=1,也是同样的达到了 上下左右的融合,但是效果不如单独计算再相加。
sobely = cv2.Sobel(img,cv2.CV_64F,1,1,ksize=3)
sobely = cv2.convertScaleAbs(sobely)
cv_show(sobely)

在这里插入图片描述

Sobel 算子,对lena 的解析效果。
img = cv2.imread("lena1.jpg",cv2.IMREAD_GRAYSCALE)sobelx = cv2.Sobel(img,cv2.CV_64F,1,0,ksize=3)
sobelx = cv2.convertScaleAbs(sobelx)sobely = cv2.Sobel(img,cv2.CV_64F,0,1,ksize=3)
sobely = cv2.convertScaleAbs(sobely)sobelxy = cv2.addWeighted(sobelx,0.5,sobely,0.5,0)
cv_show(sobelxy)

在这里插入图片描述

二、Scharr算子

dst = cv2.Scharr(src,ddepth,dx,dy)
- ddepth:图像的深度
- dx和dy 分别表示水平和竖直方向通过卷积算子可以看出,Scharr 和 Sobel 基本上是一样的,但是对于中心点周边的权重大小不一样。相比于Sobel ,对于噪声更加敏感,
显示也相应的更加细致。

在这里插入图片描述

(1)程序演示(相加融合和上边一样)

# 读取lina图片, 分别进行 左右和上下 方向上的计算,然后再相加融合
img =cv2.imread('lena1.jpg',cv2.IMREAD_GRAYSCALE)scharrx = cv2.Scharr(img,cv2.CV_64F,1,0)
scharrx = cv2.convertScaleAbs(scharrx)scharry = cv2.Scharr(img,cv2.CV_64F,0,1)
scharry = cv2.convertScaleAbs(scharry)scharrxy = cv2.addWeighted(scharrx,0.5,scharry,0.5,0)cv_show(scharrxy)

在这里插入图片描述

三、Laplacian 算子

dst = cv2.Laplacian(src,ddepth)
- ddepth:图像的深度

(1)程序演示

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

在这里插入图片描述

四、三种方法的结果比较

(1)原图

img = cv2.imread("lena1.jpg",cv2.IMREAD_GRAYSCALE)
cv_show(img)

在这里插入图片描述

(2)三种方法对比

import numpy as npimg = cv2.imread("lena1.jpg",cv2.IMREAD_GRAYSCALE)sobelx = cv2.Sobel(img,cv2.CV_64F,1,0,ksize=3)
sobelx = cv2.convertScaleAbs(sobelx)sobely = cv2.Sobel(img,cv2.CV_64F,0,1,ksize=3)
sobely = cv2.convertScaleAbs(sobely)sobelxy = cv2.addWeighted(sobelx,0.5,sobely,0.5,0)img =cv2.imread('lena1.jpg',cv2.IMREAD_GRAYSCALE)scharrx = cv2.Scharr(img,cv2.CV_64F,1,0)
scharrx = cv2.convertScaleAbs(scharrx)scharry = cv2.Scharr(img,cv2.CV_64F,0,1)
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)vs_slbel_scharr_laplacian = np.hstack((sobelxy,scharrxy,laplacian))
cv_show(vs_slbel_scharr_laplacian )

在这里插入图片描述