OpenCV边沿检测(Python版)

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

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

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

        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 cv2

image = 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 cv2

image = 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) / 2
    centerW = (winW - 1) / 2
    for 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的值设置为0
    edge[edge >= 0] = 0
    # 将小于0的值设置为255
    edge[edge < 0] = 255
    edge = edge.astype(np.uint8)
    return edge

if __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()

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/961445.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

推荐七节来自NVIDIA、Google、斯坦福的AI课程

英伟达 &#xff08;1&#xff09;在 10 分钟内构建大脑 • 探索神经网络如何使用数据进行学习。 • 了解神经元背后的数学原理。 链接&#xff1a;https://learn.nvidia.com/courses/course-detail?course_idcourse-v1:DLIT-FX-01V1 &#xff08;2&#xff09;构建视频 A…

《从因果关系的角度学习失真不变表示以用于图像恢复》学习笔记

paper&#xff1a;2303.06859 GitHub&#xff1a;lixinustc/Causal-IR-DIL: Distortion invariant feature learning for image restoration from a causality perspective 2023 CVPR 摘要 近年来&#xff0c;我们见证了深度神经网络&#xff08;DNNs&#xff09;在图像恢复…

亚博microros小车-原生ubuntu支持系列:16 机器人状态估计

本来想测试下gmapping建图&#xff0c;但是底层依赖了yahboomcar_bringup做底层的数据处理&#xff0c;所以先把依赖的工程导入。 程序启动后&#xff0c;会订阅imu和odom数据&#xff0c;过滤掉一部分的imu数据后&#xff0c;然后与odom数据进行融合&#xff0c;最后输出一个…

不背单词快捷键(不背单词键盘快捷键)

文章目录 不背单词快捷键 不背单词快捷键 ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ    …

VPR概述、资源

SOTA网站&#xff1a; Visual Place Recognition | Papers With Code VPR&#xff08;Visual Place Recognition&#xff09; 是计算机视觉领域的一项关键任务&#xff0c;旨在通过图像匹配和分析来识别场景或位置。它的目标是根据视觉信息判断某个场景是否与数据库中的场景匹…

MYSQL 商城系统设计 商品数据表的设计 商品 商品类别 商品选项卡 多表查询

介绍 在开发商品模块时&#xff0c;通常使用分表的方式进行查询以及关联。在通过表连接的方式进行查询。每个商品都有不同的分类&#xff0c;每个不同分类下面都有商品规格可以选择&#xff0c;每个商品分类对应商品规格都有自己的价格和库存。在实际的开发中应该给这些表进行…

代理模式 -- 学习笔记

代理模式学习笔记 什么是代理&#xff1f; 代理是一种设计模式&#xff0c;用户可以通过代理操作&#xff0c;而真正去进行处理的是我们的目标对象&#xff0c;代理可以在方法增强&#xff08;如&#xff1a;记录日志&#xff0c;添加事务&#xff0c;监控等&#xff09; 拿一…

Flutter使用Flavor实现切换环境和多渠道打包

在Android开发中通常我们使用flavor进行多渠道打包&#xff0c;flutter开发中同样有这种方式&#xff0c;不过需要在原生中配置 具体方案其实flutter官网个了相关示例&#xff08;https://docs.flutter.dev/deployment/flavors&#xff09;,我这里记录一下自己的操作 Android …

WinDBG查找C++句柄泄露

C代码&#xff08;频繁点击About按钮导致Mutex句柄泄露&#xff09; HANDLE _mutexHandle;LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {switch (message){case WM_COMMAND:{int wmId LOWORD(wParam);// 分析菜单选择:switch (wmId){c…

Web3 如何赋能元宇宙,实现虚实融合的无缝对接

随着技术的飞速发展&#xff0c;元宇宙作为一个未来数字世界的概念&#xff0c;正在吸引全球范围内的关注。而 Web3 技术的兴起&#xff0c;为元宇宙的实现提供了强大的支撑。Web3 是基于区块链技术的去中心化网络&#xff0c;它在改变互联网的同时&#xff0c;也推动着虚拟世界…

可以称之为“yyds”的物联网开源框架有哪几个?

有了物联网的发展&#xff0c;我们的生活似乎也变得更加“鲜活”、有趣、便捷&#xff0c;包具有科技感的。在物联网&#xff08;IoT&#xff09;领域中&#xff0c;也有许多优秀的开源框架支持设备连接、数据处理、云服务等&#xff0c;成为被用户们广泛认可的存在。以下给大家…

FreeRTOS从入门到精通 第十四章(队列集)

参考教程&#xff1a;【正点原子】手把手教你学FreeRTOS实时系统_哔哩哔哩_bilibili 一、队列集简介 1、队列集概述 &#xff08;1&#xff09;一个队列只允许任务间传递的消息为同一种数据类型&#xff0c;如果需要在任务间传递不同数据类型的消息时&#xff0c;那么就可以…

Python Matplotlib库:从入门到精通

Python Matplotlib库&#xff1a;从入门到精通 在数据分析和科学计算领域&#xff0c;可视化是一项至关重要的技能。Matplotlib作为Python中最流行的绘图库之一&#xff0c;为我们提供了强大的绘图功能。本文将带你从Matplotlib的基础开始&#xff0c;逐步掌握其高级用法&…

xclode版本

直接搜xcode https://developer.apple.com/download/all/?qCommand%20Line%20Tools https://developer.apple.com/download/all/?qXcode https://xcodereleases.com/?q10.15 下载可能慢 catalina 支持 11.3.1xcode

Formality:时序变换(二)(不可读寄存器移除)

相关阅读 Formalityhttps://blog.csdn.net/weixin_45791458/category_12841971.html?spm1001.2014.3001.5482 一、引言 时序变换在Design Compiler的首次综合和增量综合中都可能发生&#xff0c;它们包括&#xff1a;时钟门控(Clock Gating)、寄存器合并(Register Merging)、…

AI作画提示词:Prompts工程技巧与最佳实践

成长路上不孤单&#x1f60a;&#x1f60a;&#x1f60a;&#x1f60a;&#x1f60a;&#x1f60a; 【14后&#x1f60a;///计算机爱好者&#x1f60a;///持续分享所学&#x1f60a;///如有需要欢迎收藏转发///&#x1f60a;】 今日分享关于物联网智能项目之——智能家居项目…

Python动量策略实战:大幅跑赢市场的底层逻辑

作者&#xff1a;老余捞鱼 原创不易&#xff0c;转载请标明出处及原作者。 写在前面的话&#xff1a;最近我深入研究了一种基于动量策略的量化投资方法&#xff0c;并用Python实现了它。动量策略的核心是“追涨杀跌”&#xff0c;通过历史数据预测未来趋势。在这篇文章中&#…

【Proteus仿真】【51单片机】多功能计算器系统设计

目录 一、主要功能 二、使用步骤 三、硬件资源 四、软件设计 五、实验现象 联系作者 一、主要功能 1、LCD1602液晶显示 2、矩阵按键​ 3、加减乘除&#xff0c;开方运算 4、带符号运算 5、最大 999*999 二、使用步骤 基于51单片机多功能计算器 包含&#xff1a;程序&…

链表的介绍

目录 引言优缺点与链表相似的数据结构注意事项单向链表的实现基础实现创建类创建成员变量创建特殊方法 增加数据push_back方法insert方法 删除数据del_back方法del_index方法 clear方法查询数据at方法与重载的中括号运算符toArray方法indexOf方法 修改数据获取链表大小测试方法…

【AIGC学习笔记】扣子平台——精选有趣应用,探索无限可能

背景介绍&#xff1a; 由于近期业务发展的需求&#xff0c;我开始接触并深入了解了扣子平台的相关知识&#xff0c;并且通过官方教程自学了简易PE工作流搭建的技巧。恰逢周会需要准备与工作相关的分享主题&#xff0c;而我作为一个扣子平台的初学者&#xff0c;也想探索一下这…