首页 > 其他分享 >计算机视觉7:图像边缘检测

计算机视觉7:图像边缘检测

时间:2024-08-18 22:23:57浏览次数:6  
标签:plt 检测 图像 边缘 算子 视觉 cv

1. 概述

1.1 边缘检测的目的

边缘检测是图像处理与计算机视觉中的重要技术之一,目的是检测识别出数字图像中亮度变化剧烈的像素点构成的集合。

1.2 锐度

锐度的提高会使图像像素在不增加的基础上造成提高清晰度的假象。

提高锐度(也就是锐化)就是把边缘的对比度提高。

图像锐化处理的目的是为了使图像的边缘、轮廓以及图像的细节变得清晰。

图像锐化的方法分为高通滤波和空域微分法。

1.3 边缘检测分类

边缘检测算子是利用图像边缘的突变性质来检测边缘的,通常情况下将边缘检测分为以下三个类型:

  • 一阶微分为基础的边缘检测,通过计算图像的梯度值来检测图像边缘,如Sobel算子、Prewitt算子、Roberts算子及差分边缘检测;
  • 二阶微分为基础的边缘检测,通过寻求二阶导数中的过零点来检测边缘,如拉普拉斯算子、高斯拉普拉斯算子、Canny算子边缘检测;
  • 混合一阶与二阶微分为基础的边缘检测,综合利用一阶微分与二阶微分特征,如Mar_Hildreth边缘检测算子。

2. 边缘检测研究的历史现状

目前仍然存在的问题:一是没有一种普遍使用的检测算法;二是没有一个好的通用的检测评价标准。

边缘检测的研究有几个明显的趋势:

  1. 对原有算法的不断改进;
  2. 新方法、新概念的引入和多种方法的有效综合利用;
  3. 交互式检测研究的深入。如对医学图像的分析。
  4. 对特殊图像的边缘检测的研究越来越得到重视。对计算机断层扫描(CT)、核磁共振、共聚焦激光扫描显微镜图像等特殊图像的边缘检测技术的研究;
  5. 对图像边缘检测评价的研究和对评价系数的研究越来越得到关注。

3. 边缘定义及类型概念

边缘是指图像周围像素灰度有阶跃变化或屋顶状变化的像素集合。

边缘具有方向和幅度两个特征,沿边缘走向,像素值变化比较平缓,垂直于边缘走向,像素值变化比较剧烈,可能呈现阶跃状,也可能呈现斜坡状。

边缘可以分为两种,一种是阶跃性边缘,两边的像素灰度值有着明显的不同;另一种为屋顶状边缘,位于灰度值从增加到减少的变化转折点。对于阶跃性边缘,二阶方向导数在边缘处成零交叉,对于屋顶状边缘,二阶方向导数在边缘处取极值。

在图(a)中,对灰度值剖面的一阶导数在图像由暗变明的位置处有一个向上的阶跃,在其他位置为零。这表明可用一阶导数的幅度值来检测边缘的存在,幅度峰值一般对应边缘位置。对灰度值剖面的二阶导数在一阶导数的阶跃上升区有一个向上的脉冲,在一阶导数阶跃下降区有一个向下的脉冲。在这两个阶跃之间有一个过零点,它的位置正对应原始图像中边缘的位置,所以可用二阶导数过零点检测边缘位置,而二阶导数在过零点附近的符号确定边缘像素在图像边缘的暗区或明区。

4. 梯度的概念

梯度是函数变化的一种度量,一幅图像可以看作是图像强度连续函数的取样点序列。

梯度是一阶导数的二维等效式,定义为矢量:

有两个重要的性质与梯度有关:

  • 矢量 的方向就是函数
  • 增大时的最大变化率方向; 梯度的幅值由下面公式给出:

对于数字图像,最简单的梯度近似表达式为:

5. 图像边缘检测的应用

生物医学工程方面的应用:

CT技术;医用显微图像的处理分析,比如红细胞/白细胞分类检测、染色体边缘分析、癌细胞特征识别等都要用到边缘的判别。

此外,在X光肺部图像增强、超声波图像边缘检测、心电图分析、立体定向仿射治疗等医学诊断方面,都广泛地应用了图像边缘分析处理技术。

6. 边缘检测方法的不足

Roberts算子:简单直观,对具有陡峭的低噪声图像的响应最好,但边缘检测图里有伪边缘;

Sobel算子和Prewitt算子:能检测更多的边缘,但也存在伪边缘且检测出来的边缘线比较粗,放大了噪声;

拉普拉斯算子和改进的拉普拉斯算子:利用二阶差分来进行检测,但是受噪声的影响比较大,且会丢失一些边缘,有一些边缘不够连续,对噪声敏感且不能获得边缘方向等信息。

7. 边缘检测的基本思想

边缘检测的基本思想就是利用边缘增强算子对边缘检测突出的边缘进行检测,然后定义图像中的边缘强度,通过设置阈值强度来提取边缘点。

最理想的边缘检测应该就是能够正确解决边缘有无真假和定位的。

介绍一些术语:

  • 边缘点:图像中灰度显著变化的点。
  • 边缘段:边缘点坐标及方向的总和,边缘的方向可以是梯度角。
  • 轮廓:边缘列表,或者是一条边缘列表的曲线模型。
  • 边缘检测器:从图像抽取边缘(边缘点或边线段)集合的算法。
  • 边缘连接:从无序边缘形成有序边缘表的过程。
  • 边缘跟踪:一个用来确定轮廓图像(滤波后的图像)的搜索过程。

要做好边缘检测,初步准备条件如下:

  • 清楚待检测的图像特性变化的形式,使用适应这种变化的检测方法。
  • 当需要提取更多空间范围内的变化特征时,需要考虑多种算子的综合应用。
  • 要考虑噪声的影响,通过滤波器将噪声进行滤除。
  • 可以考虑各种方法的结合。
  • 在正确的图像边缘检测的基础上,要考虑定位精确的问题。

8. 图像边缘检测的步骤

边缘检测检测分为彩色图像边缘检测和灰度图像边缘检测两种。如果输入的是彩色图像p(x , y),就可以利用公式对彩色图像进行灰度图像处理:p(x , y) = 0.3R + 0.59G + 0.11B。

图像边缘检测主要包括以下五个步骤:

        (1)  图像获取:先进行图像的获取,再根据相应的条件转化为灰度图像,进而进行分析。

        (2) 图像滤波:必须使用滤波器来改善与噪声有关的边缘检测器的性能。

        (3) 图像增强:增强边缘的基础是确定图像各点邻域强度的变化值。

        (4) 图像检测:最简单的边缘检测判据是梯度幅值阈值判据。

        (5) 图像定位:图像边缘定位是对边缘图像处理后得到单像素的二值边缘图像,常使用的技术是阈值法和零交叉法。 

一般来说对检测出的边缘有以下几个要求:

  • 边缘的定位精度要高;
  • 检测的响应最最好是单像素的;
  • 对不同尺度的边缘都能够较好地响应并尽可能减少漏检;
  • 边缘检测对噪声不敏感;
  • 检测灵敏度受边缘的方向影响小。

9. 经典图像边缘检测算法

边缘检测的实质是采用某种算法来提取出图像中对象与背景间的交界线。

经典的边缘检测方法是对原始图像中像素的某个邻域来构造边缘检测算子,其过程如下图所示:

9.1 Roberts算子

Roberts算子又称为交叉微分算法,是基于交叉差分的梯度算法,通过局部差分计算检测边缘线条。

常用来处理具有陡峭的低噪声图像,当图像边缘接近于正45度或负45度时,该算法处理效果更理想。

其缺点是对边缘的定位不太准确,提取的边缘线条较粗。

Roberts算子的模板分为水平方向和垂直方向,如下如:

                                 

实现Roberts算子主要通过OpenCV中的filter2D函数来完成。这个函数的主要功能是通过卷积核实现对图像的卷积运算,声明如下:

def  filter2D(src, ddepth, kernel, dst = None, anchor = None, delta = None, borderType = None)

  • src:输入图像;
  • ddepth:表示目标图像所需的深度;
  • kernel:表示卷积核。

代码实例:Roberts算子边缘检测

import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt 
 
# 读取图像
img = cv.imread('test.jpg', cv.COLOR_BGR2GRAY)
# cv.COLOR_BGR2GRAY将BGR图像转换为灰度图像
rgb_img = cv.cvtColor(img, cv.COLOR_BGR2RGB)

# 灰度化处理图像
grayImage = cv.cvtColor(img, cv.COLOR_BGR2GRAY)

# Roberts算子的两个卷积核kernelx和kernely,分别用于检测水平和垂直方向的边缘。
kernelx = np.array([[-1, 0], [0, 1]], dtype=int)
kernely = np.array([[0, -1], [1, 0]], dtype=int)

# 使用cv.filter2D函数对灰度图像进行卷积操作,得到水平和垂直方向的梯度图像。
x = cv.filter2D(grayImage, cv.CV_16S, kernelx)
y = cv.filter2D(grayImage, cv.CV_16S, kernely)

# 将卷积后的图像数据转换为绝对值,并转换为uint8类型,以便于显示。
absX = cv.convertScaleAbs(x)
absY = cv.convertScaleAbs(y)
# 将两个方向的梯度图像融合,得到最终的Roberts算子边缘检测图像。
Roberts = cv.addWeighted(absX, 0.5, absY, 0.5, 0)

# 显示图形
titles = ['src', 'Roberts operator']
images = [rgb_img, Roberts]

for i in range(2):
    # 使用matplotlib的subplot和imshow函数显示原始图像和Roberts算子处理后的图像
    plt.subplot(1, 2, i + 1), plt.imshow(images[i], 'gray')
    plt.title(titles[i])
    plt.xticks([]), plt.yticks([])
plt.show()


代码效果图:

9.2 Sobel算子边缘检测

Sobel算子(索贝尔算子)利用像素上、下、左、右邻域的灰度加权算法,根据在边缘点处达到极值这一原理进行边缘检测。

该方法不但产生较好的检测效果,而且对噪声具有平滑作用,可以提供较为精确的边缘方向信息。缺点是Sobel算子并没有将图像的主题和背景严格区分开。

使用Sobel边缘检测算子提取图像边缘的过程大致可以分为以下三个步骤:

  1. 提取x方向的边缘,x方向一阶Sobel边缘检测算子如下图1所示;
  2. 提取y方向的边缘,y方向一阶Sobel边缘检测算子如下图2所示;
  3. 综合两个方向的边缘信息得到整幅图像的边缘。

\begin{bmatrix} -1 & 0 & 1\\ -2& 0 &2 \\ -1 &0 & 1 \end{bmatrix}           \begin{bmatrix} -1 & -2&-1 \\ 0& 0 &0 \\ 1& 2&1 \end{bmatrix}

                                                      图1                           图2

由两个方向的边缘得到整体的边缘由两种计算方式:一种是求取两幅图像对应像素的像素值的绝对值之和;另一种是求取两幅图像对应像素的像素值的平方和的二次方根。如下:

总梯度:           G = \sqrt{G_{x}^{2} + G_{y}^{2} }

简化梯度:       G = \left |G_{x} \right | + \left |G_{y} \right |

OpenCV提供了对图像提取Sobel边缘的Sobel函数,该函数声明如下:

Sobel(src, ddepth, dx, dy[, dst[, ksize[, scale[, delta[, borderType]]]]]) → dst

  • src:表示待提取边缘的图像;
  • dst:表示输出图像,与输入图像src具有相同的尺寸和通道数,数据类型由第三个参数ddepth表示输出图像的数量类型;
  • dx:表示x方向的差分阶数;
  • dy:表示y方向的差分阶数;
  • ksize:表示Sobel边缘算子的尺寸,必须是1、3、5、或者7;
  • scale:表示对导数计算结果进行缩放的缩放因子,默认系数为1,不进行缩放;
  • dekta:表示偏值,在计算结果中加上偏值;
  • borderType:表示像素外推法选择标志,默认参数为BORDER_DEFAULT,表示不包含边界值倒序填充。

当对精度要求不是很高时,Sobel算子是一种常用的边缘检测方法。

代码实例:Sobel算子边缘检测

import cv2 as cv
import matplotlib.pyplot as plt

# 读取图像
img = cv.imread('test.jpg', cv.COLOR_BGR2GRAY)
rgb_img = cv.cvtColor(img, cv.COLOR_BGR2RGB)

# 灰度化处理图像
grayImage = cv.cvtColor(img, cv.COLOR_BGR2GRAY)

# 使用cv.Sobel函数计算图像的水平和垂直方向的梯度
# cv.CV_16S指定数据类型为16位有符号整数。
x = cv.Sobel(grayImage, cv.CV_16S, 1, 0)
y = cv.Sobel(grayImage, cv.CV_16S, 0, 1)

# 将计算得到的梯度图像转换为绝对值,并转换为uint8类型,以便显示。
absX = cv.convertScaleAbs(x)
absY = cv.convertScaleAbs(y)
# 将水平和垂直方向的梯度图像融合,得到最终的Sobel算子边缘检测图像。
Sobel = cv.addWeighted(absX, 0.5, absY, 0.5, 0)

# 用来正常显示中文标签
plt.rcParams['font.sans-serif'] = ['SimHei']

# 显示图形
titles = ['原始图像', 'Sobel 算子']
images = [rgb_img, Sobel]

for i in range(2):
    plt.subplot(1, 2, i + 1), plt.imshow(images[i], 'gray')
    plt.title(titles[i])
    plt.xticks([]), plt.yticks([])
plt.show()

代码效果图:

9.3 Prewitt算子边缘检测

Prewitt边缘算子是一种边缘样板算子。由理想的边缘算子图像构成,依次用边缘样板去检测图像,与被检测区域最为相似的样板给出最大值,用这个最大值作为算子的输出。

Prewitt算子和Sobel差不多,利用像素点上下、左右邻点灰度差,在边缘处达到极值检测边缘。其对噪声具有平滑作用,定位精度不够高。

相比Roberts算子,Prewitt算子对噪声有抑制作用,卷积核如下图所示。

  

Prewitt抑制噪声的原理是通过像素平均,因此噪声较多的图像处理得比较好。但是像素平均相当于对图像得低通滤波,所以Prewitt算子对边缘得定位不如Roberts算子。

代码实例:Prewitt算子边缘检测

import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt

# 读取图像
img = cv.imread('test.jpg', cv.COLOR_BGR2GRAY)
rgb_img = cv.cvtColor(img, cv.COLOR_BGR2RGB)

# 灰度化处理图像
grayImage = cv.cvtColor(img, cv.COLOR_BGR2GRAY)

# Prewitt 算子
kernelx = np.array([[1,1,1],[0,0,0],[-1,-1,-1]],dtype=int)
kernely = np.array([[-1,0,1],[-1,0,1],[-1,0,1]],dtype=int)

# 使用cv.filter2D函数对灰度图像进行卷积操作,得到水平和垂直方向的梯度图像。
x = cv.filter2D(grayImage, cv.CV_16S, kernelx)
y = cv.filter2D(grayImage, cv.CV_16S, kernely)

# 转 uint8 ,图像融合
absX = cv.convertScaleAbs(x)
absY = cv.convertScaleAbs(y)
# 将两个方向的梯度图像融合
Prewitt = cv.addWeighted(absX, 0.5, absY, 0.5, 0)

# 用来正常显示中文标签
plt.rcParams['font.sans-serif'] = ['SimHei']

# 显示图形
titles = ['原始图像', 'Prewitt 算子']
images = [rgb_img, Prewitt]

for i in range(2):
    plt.subplot(1, 2, i + 1), plt.imshow(images[i], 'gray')
    plt.title(titles[i])
    plt.xticks([]), plt.yticks([])
plt.show()

代码效果图:

9.4 LoG边缘检测算子

该算法首先对图像做高斯滤波,然后求其拉普拉斯(Laplacian)二阶导数,即图像与Laplacian of the Gaussian function 进行滤波运算。

LoG算子也就是高斯拉普拉斯函数,常用于数字图像的边缘提取和二值化。首先对原始图像进行最佳平滑处理,最大限度地抑制噪声,再对平滑后的图像求取边缘。

该算法的主要思路和步骤:滤波、增强、检测。

具体的内容我拍照上传一下:

代码实例图:LoG算子边缘检测

import cv2 as cv
import matplotlib.pyplot as plt

# 读取图像
img = cv.imread("test.jpg")
rgb_img = cv.cvtColor(img, cv.COLOR_BGR2RGB)

gray_img = cv.cvtColor(img, cv.COLOR_BGR2GRAY)

# 先通过高斯滤波降噪
gaussian = cv.GaussianBlur(gray_img, (3, 3), 0)

# 再通过拉普拉斯算子做边缘检测,cv.Laplacian函数计算图像的二阶导数
dst = cv.Laplacian(gaussian, cv.CV_16S, ksize=3)
LOG = cv.convertScaleAbs(dst)

# 用来正常显示中文标签
plt.rcParams['font.sans-serif'] = ['SimHei']

# 显示图形
titles = ['原始图像', 'LOG 算子']
images = [rgb_img, LOG]

for i in range(2):
    plt.subplot(1, 2, i + 1), plt.imshow(images[i], 'gray')
    plt.title(titles[i])
    plt.xticks([]), plt.yticks([])
plt.show()
 

代码效果图:

9.5 边缘检测的最新技术与方法

  • 基于小波与分形理论边缘检测技术
  • 基于数学形态学的边缘检测技术
  • 基于模糊学的边缘检测技术
  • 基于遗传算法的边缘检测技术
  • 基于神经网络的边缘检测技术

参考学习书总结:OpenCv4.5 计算机视觉开发实战(基于python)

代码来自书本,供自己学习复习使用,继续学习ing...

标签:plt,检测,图像,边缘,算子,视觉,cv
From: https://blog.csdn.net/KingGodZ/article/details/141277471

相关文章

  • 基于微信小程序的外卖点餐系统的设计与实现22 毕业论文+开题报告+答辩PPT+论文检测查
    !!!有需要的小伙伴可以通过文章末尾名片咨询我哦!!! ......
  • 基于YOLOv8的通用的滑动验证码滑块缺口检测模型
    文章目录前言滑块缺口验证码验证码示例训练步骤总结前言首先放张图片表达此时的心情,同志们节日快乐!!!滑块缺口验证码滑动验证码滑块缺口的位置识别是破解滑块验证码的关键,这里我们尝试使用YOLOV8训练目标检测模型,识别出滑块图片的缺口验证码示例模型通过大批量......
  • 每天五分钟计算机视觉:搭建人脸识别的Siamese深度神经网络模型
    本文重点前面的一篇文章中介绍了关于一次学习的问题,解决一次学习问题的关键在于学习到一个函数d,这个d可以计算出两张图片中的人脸是不是同一个人。那么我们需要搭建什么样的神经网络才可以让模型学习出这样的函数d呢?本文我们介绍一下Siamese神经网络结构,它可以帮助我们解决这......
  • 2024年图像配准最新算法EfficientLoFTR(cvpr2024) 【补丁For 双鱼眼全景视频拼接】
    前言对于双鱼眼全景拼接这个项目来说,单应性矩阵是最重要的一环。单应性矩阵中它既包含了相机的内参,也包含了相机的外参。因此就算你的相机没有特别好的定位,也能通过好的单应性矩阵救回来。2024最新DNN配准算法在双鱼眼相机拼接中,特征点检测与匹配是影响单应性矩阵最......
  • 专业图像处理与编辑软件Adobe Photoshop PS2024 win/mac软件安装下载
    一、软件概述1.1Photoshop简介AdobePhotoshop,简称PS,是全球领先的专业图像处理与编辑软件,由AdobeSystems开发和发行。自1990年问世以来,Photoshop凭借其强大的图像编辑、修复、合成及色彩管理能力,成为了图形设计师、摄影师、艺术家及数字内容创作者不可或缺的工具。1.2应......
  • fpga图像处理实战-对数变换
    对数变换        图像对数变换(LogarithmicTransformation)是一种非线性灰度变换方法,常用于增强图像中的细节,特别是在图像中存在较大的亮度范围时。对数变换通过压缩亮度范围,使得较暗区域的细节更加明显,同时抑制过亮区域的影响。它在图像处理中的应用非常广泛,特别是在......
  • fpga图像处理实战-图像缓存(FIFO)
    FPGA实现`timescale1ns/1ps////Company://Engineer:////CreateDate:2024/08/1813:47:22//DesignName://ModuleName:line_buffer//ProjectName://TargetDevices://ToolVersions://Description:////Dependencies:////Revision......
  • YOLOv8单目标检测
    文章目录1.数据集2.模型训练3.转onnx并推理(1)输出结果解释(2)推理4.YOLOv8参数说明用于个人记录,好记性不如烂笔头其实整体训练的流程和V5差不多,只是V8不需要下载工程文件了,而是可以通过安装ultralytics,然后进行调用pipinstallultralytics1.数据集​数据集的制......
  • TPAMI 2024 | 自适应区域特定损失:提高图像分割性能
    前言 本文引入了一个区域特定的损失来提升隐含的均匀加权假设,以实现更好的学习,将整个体积划分为多个子区域,每个子区域都构建了一个针对最佳局部性能的个性化损失。有效地,这个方案对更难分割的子区域施加了更高的权重,反之亦然。此外,在训练步骤中为每个输入图像计算了区域的假阳性......
  • 【Android驱动12】Modem编译和sim卡配置检测过程
    一,Modem编译1.1查看ReleseNote发现需要查看"Build_Configure_Modem_MOLY"这张表,解压MT67xx_(xxx)_MOLY.LR9.W1444.MD.LWTG.MP.Vx.tar.gz到某文件,并在make目录下查看支持的配置信息1.2执行的命令,开始编译modem,则是./make.sh"SM67xx(Lxx_xxx).mak"new1.3执行perl......