OpenCV中边缘检测四种常用算子:
(1)Sobel算子
Sobel算子是一种基于梯度的边缘检测算法。它通过对图像进行卷积操作来计算图像的梯度,并将梯度的大小作为边缘的强度。它使用两个3x3的卷积核,分别用于计算水平方向(Gx)和垂直方向(Gy)的梯度,通过对两个方向的梯度进行合并来得到最终的边缘图像。
python
import cv2
image0 = cv2.imread('output.png') # 读入图像
cv2.imshow('wino',image0) # 展示原图像
# 对x方向进行边缘检测,dx=1表示对x方向,dy=0表示不对y轴方向,参数-1表示输出图像将使用与输入图像相同的数据类型来存储像素值
# x方向的边缘
sobelx = cv2.Sobel(image0,-1,dx=1,dy=0)
cv2.imshow("win1",sobelx)
# x方向的边缘,包括负数信息,因为图像的灰度值范围为0~255,负数展示不出来
# cv2.CV_64F表示将默认的uint8数据类型改为float64
sobelx64 = cv2.Sobel(image0,cv2.CV_64F,dx=1,dy=0)
cv2.imshow("win2",sobelx64)
# x方向的边缘,包括负数信息, 使用convertScaleAbs将灰度值进行绝对值处理,负值信息即可显示
sobelxfull = cv2.convertScaleAbs(sobelx64)
cv2.imshow('win3',sobelxfull)
# x方向不检测,y轴方向检测
sobely = cv2.Sobel(image0,-1,dx=0,dy=1)
cv2.imshow("win4",sobely)
# y方向的边缘,包括负数信息
sobely64 = cv2.Sobel(image0,cv2.CV_64F,dx=0,dy=1)
sobelyfull = cv2.convertScaleAbs(sobely64)
cv2.imshow("win5",sobelyfull)
# x和y方向进行加权处理
yuan_xy_full = cv2.addWeighted(sobelxfull,1,sobelyfull,1,0)
cv2.imshow('sobely',yuan_xy_full)
cv2.waitKey(0)
(2)Scharr 算子
Scharr算子是一种改进的Sobel算子,它使用更复杂的权重来提高梯度计算的精确度,尤其是在低对比度边缘上。与 Soble 的速度相同,且精度更高。Scharr 算子与 Sobel 算子的不同点是在平滑部分,其中心元素占的权重更重,相当于使用较小标准差的高斯函数,也就是更瘦高的模板。ksize参数表示卷积核的大小。它是一个正奇数,用于指定卷积核的尺寸。
python
import cv2
image0 = cv2.imread('output.png',cv2.IMREAD_GRAYSCALE) # 导入图像灰度图形式
cv2.imshow('image0',image0)
x64 = cv2.Scharr(image0,cv2.CV_64F,dx=1,dy=0) # 对x方向进行处理,将数据类型保存并转换成浮点型
xfull = cv2.convertScaleAbs(x64) # 转换为绝对值,负数转换为正数
y64 = cv2.Scharr(image0,cv2.CV_64F,dx=0,dy=1) # 对y轴方向进行处理
yfull = cv2.convertScaleAbs(y64) # 绝对值处理
xysobel = cv2.addWeighted(xfull,1,yfull,1,0) # 加权处理
cv2.imshow('xy_Scharr',xysobel)
cv2.waitKey(0)
(3)Canny边缘检测算法
Canny算法是一种多阶段的边缘检测技术,以其高效性和准确度而受到广泛应用。它通过噪声滤波、梯度计算、非极大值抑制和双阈值等步骤来识别边缘。Canny算法能够提取高质量的边缘,并且对噪声有一定的抵抗能力。
-
步骤:
- 高斯滤波:使用高斯滤波器平滑图像以减少噪声。
- 梯度计算:使用Sobel算子计算梯度的强度和方向。
- 非极大值抑制:抑制非边缘的像素,仅保留局部最大值。
- 双阈值检测:应用高、低两个阈值以确定边缘。
- 边缘连接:通过连接在高阈值附近的低阈值像素来形成最终边缘。
-
输出:生成清晰的边缘图。
python
import cv2
import numpy as np
image1 = cv2.imread('output.png',cv2.IMREAD_GRAYSCALE)
cv2.imshow('image1',image1)
# 高斯平滑
blurred = cv2.GaussianBlur(image1, (5, 5), 1.5)
# 参数:其后表示边缘检测的像素值低于100像素的被丢弃,高于150像素的被丢弃
image1_canny = cv2.Canny(image1,100,150)
cv2.imshow('canny',image1_canny)
cv2.waitKey(0)
(4)Laplacian算子
Laplacian算子是一种基于二阶导数的边缘检测算法。它通过计算图像的二阶导数来查找图像中的边缘。Laplacian算子对于边缘的宽度和方向不敏感,因此可以检测出比较粗的边缘。它对噪声相对敏感,通常需要在使用前进行平滑处理。
使用拉普拉斯算子实现彩色浮雕效果
python
import cv2
import numpy as np
'''
使用拉普拉斯算子实现彩色浮雕效果原理
1灰度转换:首先,将彩色图像转换为灰度图像。范围通常为0到255。
2灰度差异计算:
对于灰度图像中的每个像素,计算其与相邻像素的灰度差异。
这通常是通过将当前像素的灰度值与其相邻像素(如水平相邻、垂直相邻或对角线相邻)的灰度值进行相减来实现的。
这种差异反映了图像中的边缘和轮廓信息。
3偏移调整:
将计算得到的灰度差异加上一个偏移值。这个偏移值用于控制浮雕效果的强度和方向。
通过调整偏移值,可以使浮雕效果更加明显或柔和。选择一个适当的偏移值(如128),这样可以使处理后的图像灰度值保持在合理的范围内。
4灰度范围映射:
将计算得到的灰度值映射到合适的灰度范围(通常是0到255)。归一化。
这确保了浮雕效果的结果是一个合法的灰度图像。如果灰度值超出了这个范围,则需要进行裁剪或归一化处理。
'''
def emboss_effect_laplacian(image):
if image is None:
print("Error: Unable to read image.")
return
# 消除小噪声
denoise = cv2.medianBlur(image, 3)
# 使用拉普拉斯算子计算二阶导数
laplacian = cv2.Laplacian(denoise, cv2.CV_64F)
# 将拉普拉斯的值放大来模拟光照效果
emboss = cv2.convertScaleAbs(laplacian * 2 + 128) # 偏移量128是为了使值分布更均匀
return emboss
if __name__ == '__main__':
original = cv2.imread("f:/apple.jpg", cv2.IMREAD_COLOR)
emboss = emboss_effect_laplacian(original)
result = np.concatenate((original, emboss), axis=1)
# 显示原始图像和浮雕效果图像
cv2.imshow('Original Image', original)
cv2.imshow('Emboss Effect (Laplacian)', emboss)
cv2.imwrite("emboss-result.jpg", result)
cv2.waitKey(0)
cv2.destroyAllWindows()