OpenCV边沿检测(Python版)

devtools/2025/1/23 3:08:49/

        边缘检测是图像处理中的一项重要任务,用于找到图像中的边界或边缘。它在计算机视觉、图像处理和模式识别等领域中具有广泛的应用。

        边缘可以被定义为图像亮度、颜色或纹理的突变区域。边缘检测算法旨在识别这些变化并将其标记为边缘。边缘检测可以用于分割图像、检测物体边界、提取图像特征等任务。

        常用的边缘检测算法包括:

        1. Roberts算子:通过对每个像素点进行水平和垂直方向上的差分计算来检测边缘。

        2. Sobel算子:使用3x3的卷积核对图像进行卷积运算,分别计算水平和垂直方向上的梯度,然后通过这两个梯度来估计边缘。

        3. Prewitt算子:类似于Sobel算子,但使用不同的卷积核来计算水平和垂直方向上的梯度。

        4. Canny边缘检测:一种基于多步骤的算法,包括高斯滤波、计算梯度、非极大值抑制和双阈值处理等步骤。Canny边缘检测通常能够提供较好的边缘检测结果,并且对噪声具有较好的鲁棒性。

        5. Laplacian算子:通过对图像进行二阶微分操作来检测边缘。它可以提供边缘的强度和方向信息。

        这些算法各有优缺点,适用于不同的应用场景。选取合适的边缘检测算法需要考虑图像的特点、噪声水平、计算效率等因素。

一、Sobel算子

        Sobel算子是一种离散型的差分算子,用来运算图像灰度函数的梯度的近似值。Sobel算子是典型的基于一阶导数的边缘检测算子,由于该算子中引人了类似局部平均的运算,因此对噪声具有平滑作用,能很好地消除噪声的影响。

        Sobel算子是一种常用的图像边缘检测算法。它利用图像灰度变化的一阶导数来检测边缘。Sobel算子由两个3×3的模板组成,分别计算图像在水平和竖直方向的灰度变化。

        水平方向的模板如下:
                                        -1 0 1
                                        -2 0 2
                                        -1 0 1

        竖直方向的模板如下:
                                        -1 -2 -1
                                         0  0  0
                                         1  2  1

        在图像上运用Sobel算子时,首先将模板与图像的某个像素及其周围的8个像素进行卷积运算,得到该像素的梯度值(水平方向和竖直方向分别计算)。然后利用梯度值计算该像素的边缘强度,一般采用以下公式:
                EdgeMagnitude = sqrt((horizontalGradient)^2 + (verticalGradient)^2)

        最后,可以对边缘强度进行二值化处理,将高于某个阈值的像素标记为边缘像素,低于阈值的像素标记为非边缘像素。

        Sobel算子是一种简单而有效的边缘检测方法,可以帮助我们找到图像中的边缘信息,常用于计算机视觉、图像处理等领域。

1、API 

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

dst:表示计算得到目标函数图像。
src: 表示原始图像。
ddepth :表示输出图像的深度
dx:表示x方向上求导的阶数。
dy: 表示y方向上求导的阶数。
ksize:表示 Sobel核的大小。
scale :表示计算导数时的缩放因子,默认值是1。
delta: 表示在目标函数上所附加的值,默认为0。
borderType: 表示边界样式。

2、代码示例

import cv2#读取该图片的灰度图
image = cv2.imread('../photo_Input/lyy.jpg', cv2.IMREAD_GRAYSCALE)
#设置参数dx=1,dy=0.得到图像水平方向上的边缘信息
SobelX = cv2.Sobel(image, cv2.CV_64F, 1, 0)
#对结果取绝对值
SobelX = cv2.convertScaleAbs(SobelX)
#设置参数dx=0,dy=1.得到图像竖直方向上的边缘信息
SobelY = cv2.Sobel(image, cv2.CV_64F, 0, 1)
#对结果取绝对值
SobelY = cv2.convertScaleAbs(SobelY)
#加权实现完整的边沿信息
SobelXY = cv2.addWeighted(SobelX, 0.5, SobelY, 0.5, 0)cv2.imshow("image", image)
cv2.imshow("SobelXY", SobelXY)
cv2.waitKey(0)
cv2.destroyAllWindows()

二、schaar算子

        

        Schaar算子是一种用于边缘检测的图像处理算子,常用于图像边缘的定位和提取。它通过计算图像中每个像素点的梯度值来识别出图像中的边缘。

        Schaar算子使用了两个不同的模板进行计算,分别针对水平和垂直方向的梯度。对于一个像素点(x, y),水平方向的梯度计算公式为:

        Gx = (P(x+1, y-1) + 2P(x+1, y) + P(x+1, y+1)) - (P(x-1, y-1) + 2P(x-1, y) + P(x-1, y+1))

        其中,P(x, y)表示图像在位置(x, y)处的像素值。

        垂直方向的梯度计算公式为:

        Gy = (P(x-1, y+1) + 2P(x, y+1) + P(x+1, y+1)) - (P(x-1, y-1) + 2P(x, y-1) + P(x+1, y-1))

        最后,将水平和垂直方向的梯度合并,得到像素点的边缘强度:

                                        G = sqrt(Gx^2 + Gy^2)

        根据边缘强度可以判断该像素点是否为边缘点,通常会设定一个阈值来进行判断。

        Schaar算子的优点是能够在水平和垂直方向上同时检测边缘,相比其他算子,它的计算复杂度较低,能够快速得到边缘位置。然而,它也存在一些缺点,如对噪声比较敏感,容易产生虚假的边缘,以及在某些情况下可能会漏检边缘。因此,一般会将Schaar算子与其他算子相结合使用,以提高边缘检测的准确性。

1、API

def Scharr(src, ddepth, dx, dy, dst, scale, delta, borderType)

dst:表示计算得到目标函数图像
src: 表示原始图像。
ddepth :表示输出图像的深度
dx:表示x方向上求导的阶数
dy:表示y方向上求导的阶数
scale: 表示计算导数时的缩放因子,默认值是1。
delta:表示在目标函数上所附加的值,默认为0。
borderType: 表示边界样式

2、代码示例

import cv2#读取该图片的灰度图
image = cv2.imread('../photo_Input/lyy.jpg', cv2.IMREAD_GRAYSCALE)
#设置参数dx=1,dy=0.得到图像水平方向上的边缘信息
SchaarX = cv2.Scharr(image, cv2.CV_64F, 1, 0)
#对结果取绝对值
SchaarX = cv2.convertScaleAbs(SchaarX)
#设置参数dx=0,dy=1.得到图像竖直方向上的边缘信
SchaarY = cv2.Scharr(image, cv2.CV_64F, 0, 1)
#对结果取绝对值
SchaarY = cv2.convertScaleAbs(SchaarY)
#加权实现完整的边沿信息
SchaarXY = cv2.addWeighted(SchaarX, 0.5, SchaarY, 0.5, 0)cv2.imshow("image", image)
cv2.imshow('SchaarXY', SchaarXY)
cv2.waitKey(0)

三、Canny边缘检测

        Canny边缘检测是一种经典的边缘检测算法,被广泛应用于计算机视觉和图像处理领域。该算法能够有效地检测图像中的边缘,并具有较低的误检率和高的检测率。

        Canny边缘检测算法的步骤如下:

                1. 噪声抑制:使用高斯滤波器对图像进行平滑,以减少噪声的影响。高斯滤波器可以模糊图像,使得图像中的噪声细节被平滑掉。

                2. 计算梯度:利用Sobel算子计算图像的梯度,找到图像中的边缘。对平滑后的图像进行水平和竖直方向的梯度计算,得到梯度幅值和梯度方向。

                3. 非极大值抑制:在梯度图像上进行非极大值抑制,保留局部梯度最大的像素点,抑制其他像素点。这一步骤可以细化边缘线,使其更加细长和清晰。

                4. 双阈值检测:设置高阈值和低阈值。若梯度幅值大于高阈值,则被标记为强边缘像素;若梯度幅值介于高阈值和低阈值之间,则被标记为弱边缘像素;若梯度幅值低于低阈值,则被标记为非边缘像素。一般情况下,高阈值是低阈值的两倍。

                5. 边缘连接:通过强边缘像素和与之相邻的弱边缘像素进行连接,形成完整的边缘线。如果一个像素点与至少一个强边缘像素点相邻,则该像素点被标记为边缘像素。

        Canny边缘检测算法通过多个步骤的处理,能够准确地检测图像中的边缘,并能够提供较好的边缘连续性和边缘定位信息。这使得它在许多计算机视觉任务中得到了广泛应用,如目标检测、图像分割、图像识别等。

1、API

Canny(image, threshold1, threshold2, edges, apertureSize, L2gradient) 

edgs: 表示计算得到的边缘信息
src :表示输人的8位图像。
threshould1:表示第一个阈值
threshould2: 表示第二个阈值。
apertureSize :表示 Sobel算子的大小。
L2gradient:表示计算图像梯度幅度的标识,默认为False

2、代码示例

import cv2image = cv2.imread('../photo_Input/lyy.jpg', cv2.IMREAD_GRAYSCALE)
#设置不同的阈值信息对图像进行边沿检测
edg1 = cv2.Canny(image, 30, 100)
edg2 = cv2.Canny(image, 100, 200)
edg3 = cv2.Canny(image, 200, 255)cv2.imshow('image', image)
cv2.imshow('edg1', edg1)
cv2.imshow('edg2', edg2)
cv2.imshow('edg3', edg3)
cv2.waitKey(0)
cv2.destroyAllWindows()

四、Laplacian算子

        Laplacian算子是一种常见的数学算子,通常表示为∇^2 (读作“del squared”)或Δ。它在数学、物理学和工程学的许多领域中发挥重要作用。

        Laplacian算子可以用于描述场(如温度、电场、重力场等)的二阶空间变化。对于一个二维场,Laplacian算子可以用以下形式表示:

                                ∇^2f = (∂^2f/∂x^2) + (∂^2f/∂y^2)

        其中,∇^2f表示场f的Laplacian,∂^2f/∂x^2表示f对x的二阶偏导数,∂^2f/∂y^2表示f对y的二阶偏导数。

        对于一个三维场,Laplacian算子可以用以下形式表示:

                        ∇^2f = (∂^2f/∂x^2) + (∂^2f/∂y^2) + (∂^2f/∂z^2)

        Laplacian算子可以用来描述场的平均曲率和变化率,以及场中的不稳定点、最小值和最大值。它在物理学中特别常见,例如在描述流体流动、电场分布和热传导等方面。

        Laplacian算子也可以用于求解微分方程和优化问题。在微分方程中,Laplacian算子常常与其他项一起出现,用来描述场的演化和平衡条件。在优化问题中,Laplacian算子可以用来衡量目标函数的曲率和变化率,从而帮助寻找最优解。

        总之,Laplacian算子是一种重要的数学算子,具有广泛的应用。

1、API

Laplacian(src, ddepth, dst, ksize, scale, delta, borderType)

dst:表示计算得到的目标函数图像
src :表示原始图像。
ddepth:表示输出图像的深度
ksize :表示二阶导数核的大小,必须是正奇数                                                                        scale: 表示计算导数时的缩放因子,默认值是1。                                                                      delta:表示在目标函数上所附加的值,默认为0。
borderType:表示边界样式。

2、代码示例

import cv2image = cv2.imread('../photo_Input/wawa.jpg', cv2.IMREAD_GRAYSCALE)cv2.imshow("image", image)Laplacian = cv2.Laplacian(image, cv2.CV_64F)
Laplacian = cv2.convertScaleAbs(Laplacian)cv2.imshow("Laplacian", Laplacian)
cv2.waitKey(0)

五、高斯拉普拉斯边缘检测

        高斯拉普拉斯边缘检测是一种常用的图像边缘检测方法,它结合了高斯平滑和拉普拉斯算子。

        首先,将原始图像进行高斯平滑处理,目的是减少噪声的影响,并模糊图像。这可以通过应用高斯滤波器来实现。

        然后,对平滑后的图像应用拉普拉斯算子,以突出图像中的边缘。拉普拉斯算子是一个二阶微分算子,它可以对图像进行边缘检测。

        拉普拉斯算子的离散形式可以通过对图像的像素进行加权求和来计算。常用的离散拉普拉斯算子有以下几种形式:
        1. 4邻域拉普拉斯算子:对于像素点(x, y),其边缘值可以通过以下计算得到:4 * f(x, y) - f(x-1, y) - f(x+1, y) - f(x, y-1) - f(x, y+1)
        2. 8邻域拉普拉斯算子:对于像素点(x, y),其边缘值可以通过以下计算得到:8 * f(x, y) - f(x-1, y) - f(x+1, y) - f(x, y-1) - f(x, y+1) - f(x-1, y-1) - f(x-1, y+1) - f(x+1, y-1) - f(x+1, y+1)

        最后,根据计算得到的边缘值,可以通过设置一个阈值来判断是否为边缘。通常,较大的边缘值被认为是图像中的边缘。

        高斯拉普拉斯边缘检测可以有效地检测出图像中的边缘,并且对于不同大小的边缘都具有较好的响应。然而,由于高斯平滑的模糊效果,可能会导致一些边缘细节的丢失。因此,在应用高斯拉普拉斯边缘检测时,需要根据具体应用场景进行参数调整和结果分析。

import numpy as np
import cv2
import math
from scipy import signal# 创建拉普拉斯高斯(LoG)卷积核
def CreateLoGKernel(sigma, KSize):winH, winW = KSize# 初始化卷积核为全零数组logkernel = np.zeros(KSize, dtype=np.float32)sigmaSquare = pow(sigma, 2.0)centerH = (winH - 1) / 2centerW = (winW - 1) / 2for r in range(winH):for c in range(winW):# 计算到中心的距离的平方norm2 = pow(r - centerH, 2.0) + pow(c - centerW, 2.0)# 根据LoG公式计算卷积核的值logkernel[r][c] = 1.0 / sigmaSquare * (norm2 / sigmaSquare - 2) * math.exp(-norm2 / (2.0 * sigmaSquare))return logkernel# 使用LoG卷积核对图像进行卷积操作
def LoG(image, sigma, kSize, _boundary='fill', _fillValue=0):LOGKernel = CreateLoGKernel(sigma, kSize)# 使用scipy的signal库进行二维卷积img_conv_log = signal.convolve2d(image, LOGKernel,'same', boundary=_boundary)return img_conv_log# 将图像进行二值化处理,用于边缘检测
def edge_binary(image):edge = np.copy(image)# 将大于等于0的值设置为0edge[edge >= 0] = 0# 将小于0的值设置为255edge[edge < 0] = 255edge = edge.astype(np.uint8)return edgeif __name__ == '__main__':# 读取灰度图像image = cv2.imread('../photo_Input/lyy.jpg', cv2.IMREAD_GRAYSCALE)cv2.imshow('image', image)# 使用不同大小的卷积核进行LoG操作image1 = LoG(image, 2, (7, 7),'symm')image2 = LoG(image, 2, (11, 11),'symm')image3 = LoG(image, 2, (13, 13),'symm')# 对LoG操作后的结果进行二值化处理L1 = edge_binary(image1)L2 = edge_binary(image2)L3 = edge_binary(image3)# 显示二值化后的结果cv2.imshow('L1', L1)cv2.imshow('L2', L2)cv2.imshow('L3', L3)cv2.waitKey(0)cv2.destroyAllWindows()

 


http://www.ppmy.cn/devtools/152761.html

相关文章

GitLab配置免密登录和常用命令

SSH 免密登录 Windows免密登录 删除现有Key 访问目录&#xff1a;C:\Users\Administrator\ .ssh&#xff0c;删除公钥&#xff1a;id_rsa.pub &#xff0c;私钥&#xff1a;id_rsa 2.生成.ssh 秘钥 运行命令生成.ssh 秘钥目录&#xff08; ssh-keygen -t rsa -C xxxxxx126.…

kafka 学习笔记3-传统部署Kraft模式集群——筑梦之路

部署kafka 集群规划 一般模式下&#xff0c;元数据在 zookeeper 中&#xff0c;运行时动态选举 controller&#xff0c;由controller 进行 Kafka 集群管理。kraft 模式架构下&#xff0c;不再依赖 zookeeper 集群&#xff0c;而是用三台 controller 节点代替 zookeeper&#…

1. 基于图像的三维重建

1. 基于图像的三维重建 核心概念三维重建中深度图、点云的区别&#xff1f;深度图点云总结 深度图到点云还需要什么步骤&#xff1f;1. **获取相机内参**2. **生成相应的像素坐标**3. **计算三维坐标**4. **构建点云**5. **处理颜色信息&#xff08;可选&#xff09;**6. **去除…

MCU中的LSB、MSB和大端模式、小端模式

第一章 LSB和MSB 1.1 最低有效位(Least Significant Bit, LSB) 红外接收器接收了0x45&#xff08;0100 0101&#xff09;之后&#xff0c;怎么将这个数据发送给MCU; LSB&#xff08;least significant bit&#xff09;&#xff1a;最低有效位优先&#xff0c;例如红外通信是以…

启效云低代码:从物联网到数联网的应用延伸

随着物联网&#xff08;IOT&#xff09;技术的飞速发展&#xff0c;数据采集与处理成为企业数字化转型的重要一环。物联网平台通过传感器、RFID标签等设备实时采集数据&#xff0c;并利用各种通信协议和存储技术确保数据的准确性和实时性&#xff0c;数据采集和处理为产品的升级…

DM8 SQL 错误 [22000]: 锁超时

问题描述 DM管理工具删除会卡死DBeaver删除会一直加载中使用truncate语句会显示SQL 错误 [22000]: 锁超时使用如下语句也没有用 select a.*,b.NAME,c.SESS_ID, sp_close_session( || c.SESS_ID || ); AS CLOSE_SESSION_COMMAND from v$lock a left join sysobjects b on b.IDa…

Android实战经验篇-AndroidScrcpyClient投屏一

系列文章转如下链接&#xff1a; Android Display Graphics系列文章-汇总 Android实战经验篇-系列文章汇总 本文主要包括部分&#xff1a; 一、方案说明 1.1 适用场景 1.2 方案框架 二、功能演示 2.1 环境准备 2.2 演示 一、方案说明 1.1 适用场景 优秀的开源的scrc…

吴恩达深度学习——建立逻辑回归分类器识别猫

本文来自吴恩达《深度学习》L1W2作业2&#xff0c;仅为个人学习所用。 理论来自吴恩达深度学习——神经网络编程的基础知识 在理论中说明了一些函数的形式&#xff0c;本文不再累述。 文章目录 数据下载相关包lr_utils文件解读 数据预处理加载数据数据预处理 构建过程选用函数计…