Canny边缘检测算法

news/2025/2/14 5:51:48/

文章目录

  • 前言
    • 1、Canny边缘检测算法
    • 2、代码1
      • 函数
    • 3、代码2
    • 4、基于tensor数据的代码


前言

最近在向卷积神经网络里的数据预处理和数据增强部分加这个函数,记录一下。


1、Canny边缘检测算法

Canny边缘检测算法是一种经典的边缘检测算法,其基本原理如下:

  1. 噪声去除:首先,使用高斯滤波器降噪,以平滑图像。

为了尽可能减少噪声对边缘检测结果的影响,所以必须滤除噪声以防止由噪声引起的错误检测。为了平滑图像,使用高斯滤波器与图像进行卷积,该步骤将平滑图像,以减少边缘检测器上明显的噪声影响。
在这里插入图片描述
其中Sigma为方差,k确定核矩阵的维数。高斯卷积核大小的选择将影响Canny检测器的性能。尺寸越大,检测器对噪声的敏感度越低,但是边缘检测的定位误差也将略有增加。一般选取5x5。

  1. 梯度计算:然后,使用Sobel算子计算图像的梯度强度和方向。梯度方向垂直于边缘,因此它可以用来定位边缘。
    在这里插入图片描述

  2. 非极大值抑制:在此步骤中,将梯度强度图像中的所有像素转换为它们在局部最大方向上的梯度强度,以消除边缘宽度。

非极大值抑制是一种边缘稀疏技术,非极大值抑制的作用在于“瘦”边。对图像进行梯度计算后,仅仅基于梯度值提取的边缘仍然很模糊。对于标准3,对边缘有且应当只有一个准确的响应。而非极大值抑制则可以帮助将局部最大值之外的所有梯度值抑制为0。
将当前像素的梯度强度与沿正负梯度方向上的两个像素进行比较。
如果当前像素的梯度强度与另外两个像素相比最大,则该像素点保留为边缘点,否则该像素点将被抑制。

  1. 双阈值检测:使用双阈值检测来确定哪些边缘是真实的边缘。如果像素的梯度强度大于高阈值,则将其视为边缘像素。如果像素的梯度强度小于低阈值,则其被排除在边缘之外。如果像素的梯度强度在两个阈值之间,则只有当该像素与高梯度强度像素相连时,才将其视为边缘像素。

  2. 边缘跟踪:最后,使用边缘跟踪算法来连接所有真实的边缘像素,以形成完整的边缘。

Canny算法多用于图像处理、计算机视觉和机器人等领域。

2、代码1

import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt'''canny边缘提取'''def canny_demo(image):# 1.高斯模糊:最后两个参数给定一个就可以自动求取另一个,所以只给其中一个赋值就可以blur=cv.GaussianBlur(image,(7,7),0)#2.灰度处理gray=cv.cvtColor(blur,cv.COLOR_BGR2GRAY)#3.求取梯度,也可以不用梯度,直接将灰度图传入cv.cannygrad_x=cv.Sobel(gray,cv.CV_16SC1,1,0)grad_y = cv.Sobel(gray, cv.CV_16SC1, 0, 1)#4.求边缘edge_output=cv.Canny(grad_x,grad_y,50,150)#参数:x梯度,y梯度 ,低阈值,高阈值#cv.imshow('canny-demo',edge_output)dst=cv.bitwise_and(image,image,mask=edge_output)#cv.imshow('color edge',dst)return dstimg=cv.imread(r"D:/code/data/319.jpg")
print(img.shape)
cv.imshow('origin',img)
dst = canny_demo(img)
cv.imshow('dst',dst)
cv.waitKey(0)print(dst.shape)

裂缝提取

函数

def Canny(image):# 1.高斯模糊:最后两个参数给定一个就可以自动求取另一个,所以只给其中一个赋值就可以blur = cv.GaussianBlur(image, (7, 7), 0)# 2.灰度处理gray = cv.cvtColor(blur, cv.COLOR_BGR2GRAY)# 3.求取梯度,也可以不用梯度,直接将灰度图传入cv.cannygrad_x = cv.Sobel(gray, cv.CV_16SC1, 1, 0)grad_y = cv.Sobel(gray, cv.CV_16SC1, 0, 1)# 4.求边缘edge_output = cv.Canny(grad_x, grad_y, 50, 150)  # 参数:x梯度,y梯度 ,低阈值,高阈值dst = cv.bitwise_and(image, image, mask=edge_output)return dst

3、代码2

import cv2
import numpy as npType = 0   # 阈值处理方式
Value = 0  # 使用的阈值
T = 0
V = 0
def onType(a):Type = cv2.getTrackbarPos(tType, windowName)Value = cv2.getTrackbarPos(tValue, windowName)ret, dst = cv2.threshold(o, Value, 255, Type)cv2.imshow(windowName, dst)global TT = Typedef onValue(a):Type = cv2.getTrackbarPos(tType, windowName)Value = cv2.getTrackbarPos(tValue, windowName)ret, dst = cv2.threshold(o, Value, 255, Type)cv2.imshow(windowName, dst)global VV = Valueo = cv2.imread(r"D:/code/data/319.jpg")
# 灰度转换
gray = cv2.cvtColor(o, cv2.COLOR_BGR2GRAY)
# cv2.imshow('gray', gray)
windowName = 'output'
cv2.namedWindow(windowName)
cv2.imshow(windowName, gray)
# 构建滚动条
tType = 'Type'
tValue = 'tValue'
cv2.createTrackbar(tType, windowName, 0, 4, onType)
cv2.createTrackbar(tValue, windowName, 0, 255, onValue)
while 1:k = 0xFF & cv2.waitKey(1)if k == 27:breakelif k == ord('s'):realType = TrealValue = Vretval, img = cv2.threshold(gray, realValue, 255, realType)cv2.imshow('output.jpg', img)cv2.imwrite("D:/code/data/output.jpg", img)output = cv2.imread("D:/code/data/output.jpg")print(output.shape)# 高斯滤波平滑处理gauss = cv2.GaussianBlur(output, (3, 3), 0, 0)# cv2.imshow('gauss',gauss)# 滤波除噪k = np.ones((5, 5), np.uint8)_open = cv2.morphologyEx(gauss, cv2.MORPH_OPEN, k)_close = cv2.morphologyEx(_open, cv2.MORPH_CLOSE, k)cv2.imshow('_close', _close)cv2.imwrite("D:/code/data/output2.jpg", _close)
cv2.destroyAllWindows()

4、基于tensor数据的代码

这个我还没找到。



http://www.ppmy.cn/news/59937.html

相关文章

git标准使用

git标准使用 首先远程仓库一般只维护两个分支,master和develop。develop在master上创建。master只有项目管理人员才有编辑权限,保存每个正式投入生产环境的版本。 有开发需求的任务时,在dev分支上开feat分支(本地)。在feat分支上完成功能开发…

4 斐波那契数列

4 斐波那契数列 作者: Turbo时间限制: 1S章节: 递归 问题描述 : 斐波那契数列的排列是:0,1,1,2,3,5,8,13,21,34,55,89,…

Kafka 消费者

一、消费者工作流程 1.1 总体工作流程 1.2 消费者组初始化流程 1.3 消费者组详细消费流程 二、消费者消费消息方式 ➢ pull(拉)模 式:consumer采用从broker中主动拉取数据。Kafka采用这种方式。 ➢ push(推)模式&am…

CommonJS规范

模块化 模块化解决的问题 代码的数量增多导致编写程序复杂度越来越高,此时如果依然将所有的代码编写到同一个文件中,代码就会变得非常难以维护,模块化就说解决这个问题的关键。什么是模块? 模块简单理解就是一个代码片段&#xf…

在一个真实的设备上调试Android应用

由于模拟器只包含很少的应用,可能只有一个处理某个动作的应用。为了更好地测试我们的应用,需要在一个真实的设备上运行这个应用。 可以按一下步骤在一个真实设备上运行你的应用。 1、启动设备上的USB调试选项 在你的安卓设备上,打开开发者选项…

JUC多并发编程 AQS

基础解释: 是用来实现锁或者其他同步器组件的公共基础部分的抽象实现,是重量级基础框架及整个JUC体系的基石,主要用于锁分配给“谁”的问题。整体就是一个抽象的 FIFO 队列来完成资源获取线程的排队工作,并通过一个 int 类变量表示持有锁的状…

【学习笔记】「JOISC 2022 Day4」复兴计划

先入为主给出结论:将 { X i } \{X_i\} {Xi​}离散化后,每条边的影响是一个区间。 然而我并没有想到可行的计算方法。 我真傻,真的。事实上 X i X_i Xi​变化的本质是边的加入顺序的变化。不妨考虑左端点的情形,首先将边按大小排…

Reinhart FoodService的EDI需求详解

Reinhart FoodService是一家成立于1972年的美国食品服务公司,隶属于上市公司Performance Food Group。Reinhart FoodService为餐馆、酒店、医院、学校等各类机构提供广泛的食品选择和相关服务,产品包括新鲜的肉类、禽类、海鲜、奶制品、烘焙用品、蔬菜和…