【医学图像处理】3 图像梯度及边缘提取

1 图像边缘

  什么是图像边缘:
  图像中存在大量边缘线,边缘线的产生是因为图像中存在不同的区域,当整个图像的区域发生灰度值变换的过程中产生边缘。两个区域的交界处所形成的边缘上的点,所组成的线就是边缘线
  边缘是一个矢量,不仅有位置还有朝向;穿过边缘的灰度级是不连续的;
  边缘产生的原因:
  (1)不同颜色的变化;亮度变化;纹理变化、材质变化…
  (2)曲面不同的法向量:两个相邻平面的法向量不一致,形成不平整平面产生边缘
  (3)不同光照

在这里插入图片描述
在这里插入图片描述
  边缘的分类:
  (1)step edge:一阶导数有急剧的峰值

在这里插入图片描述

  (2)Ramp edge:二阶导数在两个变化区域产生抖动变化(峰值)
在这里插入图片描述

  (3)Peak edge:一阶导数的变化变会产生两个峰值
在这里插入图片描述
在这里插入图片描述

2 图像梯度

  图像梯度: 用于表达边缘的属性,用梯度表现边缘是什么类型的边缘
  图像梯度计算: 对二维图像求二维一阶导数(或更高阶导数)得到一些峰值,当峰值超过一个特定的阈值的时候,则认为该峰值为边缘。
  数字图像f(x,y)的梯度被定义为一个向量,对x方向和y方向分别求梯度,整个图像的梯度为两个方向梯度的表达式:
在这里插入图片描述
  图像的梯度为矢量,包含值和方向,梯度的值为:
在这里插入图片描述
  梯度的方向为:

在这里插入图片描述
  对图像求偏导,其实就是求变化率

3 边缘检测算法

3.1 Robert算子

  x方向的梯度、y方向的梯度计算方式为:
在这里插入图片描述

3.2 Prewitt算法

  x方向的梯度、y方向的梯度计算方式为:
在这里插入图片描述

3.3 Soble算子

  x方向的梯度、y方向的梯度计算方式为:
在这里插入图片描述
  Sobel算子原理:
  (1)假设要处理的图像为I,要在水平方向和垂直方向分别求一阶导数
在这里插入图片描述
  (2)在图像的每一个点,结合以上两个结果求出:
在这里插入图片描述
  (3)统计G中极大值所在的位置,就是图像的边缘
  Sobel边缘检测流程:
  (1)API: Sobel_x_or_y=cv2.Sobel(src,ddepth,dx,dy,dst=None, ksize=None, scale=None, delta=None, borderType=None)
  参数:
    src:传入图像
    ddepth:图像深度
    dx和dy:代表是否在这个方向上求导,0代表不求导,1代表求导
    ksize:是Sobel算子的大小,既卷积核的大小,必须为奇数。如果ksize=-1,就演变成为3×3的Scharr算子。
    scale:缩放导数的比例常数,默认情况为没有伸缩系数
    BorderType:图像边界的模式。默认值为cv2.BORDER_DEFAULT
  (2) Sobel函数在某方向上求导,求导后可能会有负值,还可能会有大于255的值。而原图像是uint8,既8位无符号数,所以Sobel建立的图像位数不够,会有阶段。因此要使用16位有符号的数据类型,既cv2.CV_16S,处理完图像后,再利用CV2.convertScaleAbs()函数将其转换为uint8格式,否者图像无法显示。
  (3) Sobel算子是在两个方向上计算的,最后还需要用cv2.addWeighted()函数将其组合起来。

import cv2
import matplotlib.pyplot as plt
import numpy as np
#1. 读取图像,灰度形式
img=cv2.imread('suanzi.png',1)#灰度值的方式读取图像

#2.计算x方向和y方向的梯度
x=cv2.Sobel(img,cv2.CV_16S,1,0)
y=cv2.Sobel(img,cv2.CV_16S,0,1)

#3.格式转换
abax=cv2.convertScaleAbs(x)
abay=cv2.convertScaleAbs(y)

#4.xy方向加权
res=cv2.addWeighted(abax,0.5,abay,0.5,0)


cv2.imshow('origin',img)
cv2.imshow('sobel',res)
cv2.waitKey(0)

在这里插入图片描述
  Sobel算子缺点:
  当内核大小为3时,Sobel算子内核可能产生比较明显的误差。为解决这一个问题,使用Scharr函数

3.4 Scharr算子

  特点:
  Scharr函数仅作用于大小为3的内核,该函数的运算与Sobel函数一样快,但是结果却更加准确
  Scharr算子原理:
  (1)假设要处理的图像为I,要在水平方向和垂直方向分别求一阶导数
在这里插入图片描述
  (2)在图像的每一个点,结合以上两个结果求出:
在这里插入图片描述
  (3)统计G中极大值所在的位置,就是图像的边缘。

import cv2
import matplotlib.pyplot as plt
import numpy as np
#1. 读取图像,灰度形式
img=cv2.imread('suanzi.png',1)#灰度值的方式读取图像

#2.计算x方向和y方向的梯度(scharr算子)
x=cv2.Sobel(img,cv2.CV_16S,1,0,ksize=-1)
y=cv2.Sobel(img,cv2.CV_16S,0,1,ksize=-1)

#3.格式转换格式
abax=cv2.convertScaleAbs(x)#转换为uint
abay=cv2.convertScaleAbs(y)

#4.xy方向加权
res=cv2.addWeighted(abax,0.5,abay,0.5,0)


cv2.imshow('origin',img)
cv2.imshow('scharr',res)
cv2.waitKey(0)

在这里插入图片描述

3.5 Laplacian算子

  原理:
  利用二阶导数来检测边缘,因为图像是2维,我们需要在两个方向上进行求导:
在这里插入图片描述

  不连续函数(图像)的二阶导数:f’’(x)=f(x+1)-f(x)=f(x+1)-f(x)-f(x)+f(x-1)=f(x+1)=f(x-1)-2f(x)
  使用的卷积核为:
在这里插入图片描述
  API: cv2.Laplacian(src,ddepth,ksize)
  参数:
    src:需要处理的图像
    Ddepth:图像的深度,-1表示采用的是原图像相同的深度,目标图像的深度必须大于等于源图像的深度
    ksize:算子的大小,即卷积核的大小,必须为奇数。

import cv2
import matplotlib.pyplot as plt
import numpy as np
#1. 读取图像,灰度形式
img=cv2.imread('suanzi.png',1)#灰度值的方式读取图像

#2.laplacian边缘检测(算子)
res=cv2.Laplacian(img,cv2.CV_16S)

#3.格式转换格式
res=cv2.convertScaleAbs(res)#转换为uint8

cv2.imshow('origin',img)
cv2.imshow('laplacian',res)
cv2.waitKey(0)

在这里插入图片描述

3.6 canny算子

  被认为是最优的边缘检测算法
  边缘检测流程:
  (1)噪声去除——高斯滤波
  由于边缘检测很容易受到噪声的影响,所以首先使用5×5的高斯滤波去除噪声。
  (2)计算图像梯度
  2.1 平滑后的图像使用Sobel算子计算水平和垂直方向的一阶导数(Gx和Gy)
  2.2 根据梯度图计算边界的梯度值和梯度方向,公式如下:
在这里插入图片描述
  如果某个像素点是边缘,则其梯度方向总是垂直于边缘。梯度方向被归为4类:垂直、水平和两个对角线方向。
  (3)非极大值抑制
  在获得梯度的方向和大小后,对整幅图像进行扫描,去除那些非边界的点。对每一个像素进行检查,看该点梯度值是不是周围具有相同梯度方向的点中是最大的,如果是最大的则保留该点,否则该点被抑制。扫描完整个图像后,结果为具有‘细边’的二进制图像。
在这里插入图片描述
  (4)滞后阈值
  确定真正的边界,设定两个阈值:minVal和maxVal。当图像的灰度梯度高于maxVal时被认为是真正的边界,低于minVal的边界被抛弃;如果灰度梯度值介于两者之间,就要看这个点是否与某个被确定为真正的边界点的点相连,如果是就认为该点是边界点,保留该点,否者抛弃该点。
在这里插入图片描述
  边缘检测流程:
  (1)API
  canny=cv2.Canny(image,threshold1,threshold2)
  (2)参数:
    image:灰度图
    threshold1:minVal,较小的阈值,将间断的边缘连接起来
    threshold2:maxVal较大的阈值检测图像中明显的边缘。

import cv2
import matplotlib.pyplot as plt
import numpy as np
#1. 读取图像,灰度形式
img=cv2.imread('suanzi.png',1)#灰度值的方式读取图像

#2.canny边缘检测
canny=cv2.Canny(img,0,100)

cv2.imshow('origin',img)
cv2.imshow('laplacian',canny)
cv2.waitKey(0)

在这里插入图片描述
  
  
  
  
  
  
  
  
  
  
  
  
  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值