图像梯度处理

图像梯度——Sobel算子

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

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

import cv2 as cv
import numpy as np


img = cv.imread('pie.png', cv.IMREAD_GRAYSCALE) # 可以转换成灰度图
sobelx = cv.Sobel(img, cv.CV_64F, 1, 0, ksize = 3) # 先计算水平方向

res = np.hstack((img, sobelx))
cv.imshow('res', res)
cv.waitKey(0)
cv.destroyAllWindows()
不取绝对值,计算水平方向梯度

 左边原图,右边是计算过水平方向梯度后的图。

根据Gx可以分析图片,先看左边,白色减去黑色的值还是白色,而黑色减去白色的值是小于零的,所有的负数会被自动截断成0,所以还是黑色。这就造成上上图只有左边一半的情况。


import cv2 as cv
import numpy as np


img = cv.imread('pie.png', cv.IMREAD_GRAYSCALE) # 可以转换成灰度图
sobelx = cv.Sobel(img, cv.CV_64F, 1, 0, ksize = 3) # 先计算水平方向
sobelx = cv.convertScaleAbs(sobelx)

res = np.hstack((img, sobelx))
cv.imshow('res', res)
cv.waitKey(0)
cv.destroyAllWindows()
取绝对值,计算水平方向梯度

 针对上面的情况,我们对计算后的值取绝对值 sobelx = cv.convertScaleAbs(sobelx) 。就可以解决上述问题。


import cv2 as cv
import numpy as np


img = cv.imread('pie.png', cv.IMREAD_GRAYSCALE) # 可以转换成灰度图
sobely = cv.Sobel(img, cv.CV_64F, 0, 1, ksize = 3) # 计算竖直方向
sobely = cv.convertScaleAbs(sobely) # 取绝对值

res = np.hstack((img, sobely))
cv.imshow('res', res)
cv.waitKey(0)
cv.destroyAllWindows()
计算竖直方向梯度


import cv2 as cv
import numpy as np


img = cv.imread('pie.png', cv.IMREAD_GRAYSCALE) # 可以转换成灰度图
sobelx = cv.Sobel(img, cv.CV_64F, 1, 0, ksize = 3) # 先计算水平方向
sobelx = cv.convertScaleAbs(sobelx)
sobely = cv.Sobel(img, cv.CV_64F, 0, 1, ksize = 3)
sobely = cv.convertScaleAbs(sobely)
sobelxy = cv.addWeighted(sobelx, 0.5, sobely, 0.5, 0) # 将二者结合

res = np.hstack((img, sobelxy))
cv.imshow('res', res)
cv.waitKey(0)
cv.destroyAllWindows()
先计算两个方向的,再结合

 我们必须先分别计算两个方向的,最后再结合,否则看下图。


import cv2 as cv
import numpy as np


img = cv.imread('lena.jpg', cv.IMREAD_GRAYSCALE) # 可以转换成灰度图

# 1、先分别计算水平和竖直方向,再结合
sobelx = cv.Sobel(img, cv.CV_64F, 1, 0, ksize = 3) # 先计算水平方向
sobelx = cv.convertScaleAbs(sobelx)
sobely = cv.Sobel(img, cv.CV_64F, 0, 1, ksize = 3)
sobely = cv.convertScaleAbs(sobely)
sobelxy = cv.addWeighted(sobelx, 0.5, sobely, 0.5, 0) # 将二者结合

# 2、直接计算
sobelxy_1 = cv.Sobel(img, cv.CV_64F, 1, 1, ksize = 3)
sobelxy_1 = cv.convertScaleAbs(sobelxy_1)

res = np.hstack((img, sobelxy, sobelxy_1))
cv.imshow('res', res)
cv.waitKey(0)
cv.destroyAllWindows()
View Code

 

  左边是原图,中间是正确的计算方式,右边的是错误的计算方式。

图像梯度-Scharr算子和Laplacian算子

import cv2 as cv
import numpy as np


img = cv.imread('lena.jpg', cv.IMREAD_GRAYSCALE) # 可以转换成灰度图

# Sobel算子
sobelx = cv.Sobel(img, cv.CV_64F, 1, 0, ksize = 3)
sobely = cv.Sobel(img, cv.CV_64F, 0, 1, ksize = 3)
sobelx = cv.convertScaleAbs(sobelx)
sobely = cv.convertScaleAbs(sobely)
sobelxy = cv.addWeighted(sobelx, 0.5, sobely, 0.5, 0)

# Scharr算子
scharrx = cv.Scharr(img, cv.CV_64F, 1, 0)
scharry = cv.Scharr(img, cv.CV_64F, 0 ,1)
scharrx = cv.convertScaleAbs(scharrx)
scharry = cv.convertScaleAbs(scharry)
scharrxy = cv.addWeighted(scharrx, 0.5, scharry, 0.5, 0)

# laplacian算子
laplacian = cv.Laplacian(img, cv.CV_64F)
laplacian = cv.convertScaleAbs(laplacian)

res = np.hstack((img, sobelxy, scharrxy, laplacian))
cv.imshow('算子', res)
cv.waitKey(0)
cv.destroyAllWindows()
三种算子的比较

原文地址:https://www.cnblogs.com/missdx/p/12361248.html