图像Sobel算子边缘检测-《医学图像处理》小作业八-Python代码/Matlab代码

天津中医药大学-20级医学信息工程   教师:王翌   学生:邓集亲

声明:本文章中所涉及的代码并非我个人独立完成的成果。

        在撰写的过程中,我广泛地吸取了前一辈人,尤其是学长学姐们的宝贵学习经验。通过深入研究他们的学习轨迹,以及查阅和分析了众多相关的理论文献与资料,并在王老师的悉心指导下,经过反复的实验、调试与优化,最终得以总结完成本文所展现的代码。

        建议各位学弟学妹们,先根据王老师的授课内容,独立思考一下应该如何完成。如果实在是有理解上的困难,不知道从何下手,再来学习和参考本文。

        学长我是用Python写的,如果你使用MATLAB,同样可以参考此代码进行翻译。我在代码中加入了许多注释和测试环节,以便于理解。由于学长能力有限,代码中或许存在一些疏漏或错误,请批判性地参考。

实验八:边缘检测

作业要求:

  1. 参考“图像分割”课的内容,用Sobel算子提取输入的图像x方向上的梯度分量、y方向上的梯度分量以及梯度图像。

例子:

实验图片:

building.tif,再自选其它至少20张图片(包括灰度图片和彩色图片)。

   边缘检测是图像处理和计算机视觉中的基本问题,边缘检测的目的是标识数字图像中亮度变化明显的点。图像属性中的显著变化通常反映了属性的重要事件和变化。

  在之前的作业中,我们已经知道,图像中的振幅(即灰度值曲线)在边缘点或噪声会有急剧变化。因此,我们可以通过计算图像中每个像素点处的梯度值,进而来确定该像素点是否位于边缘。

  Sobel算子是一种常用的基于卷积运算实现的边缘检测算法。它通过对原始图像进行卷积运算来计算每个像素点处的梯度,并根据梯度大小和方向来确定该点是否为边缘。

  具体而言,Sobel算子使用一个3x35x5的卷积核对原始图像进行卷积运算,得到每个像素点处的梯度值。然后,通过对梯度值进行阈值处理来确定哪些像素点是边缘。一般来说,如果梯度值超过了一个阈值,则将该像素点判定为边缘;否则将其判定为非边缘。

Windows图片文件目录:

ImageSet文件目录下储存其他待处理图片

Python代码:

#导入库
import cv2
import numpy as np
from matplotlib import pyplot

#定义函数提取x上分量,剩下y
def sobel_x(img):
    # 定义Sobel算子
    sobel_x = [[-1, 0, 1], 
               [-2, 0, 2], 
               [-1, 0, 1]]
    # 获取图像尺寸
    height, width = img.shape
    # 初始化结果数组
    result = np.zeros((height - 2, width - 2))
    
    # 遍历图像像素
    for i in range(1, height - 1):
        for j in range(1, width - 1):
            # 计算Sobel算子卷积结果,为了更直观,用\连接
            pixel = (sobel_x[0][0] * img[i-1][j-1]) + (sobel_x[0][1] * img[i-1][j]) + \
                    (sobel_x[0][2] * img[i-1][j+1]) + (sobel_x[1][0] * img[i][j-1]) + \
                    (sobel_x[1][1] * img[i][j]) + (sobel_x[1][2] * img[i][j+1]) + \
                    (sobel_x[2][0] * img[i+1][j-1]) + (sobel_x[2][1] * img[i+1][j]) + \
                    (sobel_x[2][2] * img[i+1][j+1])
            # 将卷积结果存入结果数组中
            if pixel>=0 and pixel<=255:
                result[i-1][j-1] = pixel
            
    return result

#定义函数提取y上分量,剩下x
def sobel_y(img):
    # 定义Sobel算子
    sobel_y = [[-1, -2, -1], 
               [0, 0, 0], 
               [1, 2, 1]]
    # 获取图像尺寸
    height, width = img.shape
    # 初始化结果数组
    result = np.zeros((height - 2, width - 2))
    
    # 遍历图像像素
    for i in range(1, height - 1):
        for j in range(1, width - 1):
            # 计算Sobel算子卷积结果,为了更直观,用\连接
            pixel = (sobel_y[0][0] * img[i-1][j-1]) + (sobel_y[0][1] * img[i-1][j]) + \
                    (sobel_y[0][2] * img[i-1][j+1]) + (sobel_y[1][0] * img[i][j-1]) + \
                    (sobel_y[1][1] * img[i][j]) + (sobel_y[1][2] * img[i][j+1]) + \
                    (sobel_y[2][0] * img[i+1][j-1]) + (sobel_y[2][1] * img[i+1][j]) + \
                    (sobel_y[2][2] * img[i+1][j+1])
            # 将卷积结果存入结果数组中
            if pixel>=0 and pixel<=255:
                result[i-1][j-1] = pixel
            
    return result

#读取图像

original = cv2.imread(r'D:\deng\smalljob\ImageSet\building.tif')
original_gray = cv2.cvtColor(original, cv2.COLOR_BGR2GRAY)   #将图像从RGB颜色空间转换到灰度颜色空间

img_y=sobel_x(original_gray)
img_x=sobel_y(original_gray)
img_xy=np.sqrt(img_x**2 + img_y**2)

#展示结果

pyplot.subplot(221),pyplot.imshow(original_gray,cmap='gray')
pyplot.title('original')
pyplot.axis('off')

pyplot.subplot(222),pyplot.imshow(img_x,cmap='gray')
pyplot.title('|G$_{x}$|')
pyplot.axis('off')

pyplot.subplot(223),pyplot.imshow(img_y,cmap='gray')
pyplot.title('|G$_{y}$|')
pyplot.axis('off')

pyplot.subplot(224),pyplot.imshow(img_xy,cmap='gray')
pyplot.title('|G$_{x}$|+|G$_{y}$|')
pyplot.axis('off')
pyplot.show()

运行结果:

以上是处理灰度图,以下是处理彩色图像

import cv2
import numpy as np
from matplotlib import pyplot


def sobel_x(img):
    # 定义Sobel算子
    sobel_x = [[-1, 0, 1], 
               [-2, 0, 2], 
               [-1, 0, 1]]
    # 获取图像尺寸
    height, width = img.shape
    # 初始化结果数组
    result = np.zeros((height - 2, width - 2))
    
    # 遍历图像像素
    for i in range(1, height - 1):
        for j in range(1, width - 1):
            # 计算Sobel算子卷积结果,为了更直观,用\连接
            pixel = (sobel_x[0][0] * img[i-1][j-1]) + (sobel_x[0][1] * img[i-1][j]) + \
                    (sobel_x[0][2] * img[i-1][j+1]) + (sobel_x[1][0] * img[i][j-1]) + \
                    (sobel_x[1][1] * img[i][j]) + (sobel_x[1][2] * img[i][j+1]) + \
                    (sobel_x[2][0] * img[i+1][j-1]) + (sobel_x[2][1] * img[i+1][j]) + \
                    (sobel_x[2][2] * img[i+1][j+1])
            # 将卷积结果存入结果数组中
            if pixel>=0 and pixel<=255:
                result[i-1][j-1] = pixel
            
    return result


def sobel_y(img):
    # 定义Sobel算子
    sobel_y = [[-1, -2, -1], 
               [0, 0, 0], 
               [1, 2, 1]]
    # 获取图像尺寸
    height, width = img.shape
    # 初始化结果数组
    result = np.zeros((height - 2, width - 2))
    
    # 遍历图像像素
    for i in range(1, height - 1):
        for j in range(1, width - 1):
            # 计算Sobel算子卷积结果,为了更直观,用\连接
            pixel = (sobel_y[0][0] * img[i-1][j-1]) + (sobel_y[0][1] * img[i-1][j]) + \
                    (sobel_y[0][2] * img[i-1][j+1]) + (sobel_y[1][0] * img[i][j-1]) + \
                    (sobel_y[1][1] * img[i][j]) + (sobel_y[1][2] * img[i][j+1]) + \
                    (sobel_y[2][0] * img[i+1][j-1]) + (sobel_y[2][1] * img[i+1][j]) + \
                    (sobel_y[2][2] * img[i+1][j+1])
            # 将卷积结果存入结果数组中
            if pixel>=0 and pixel<=255:
                result[i-1][j-1] = pixel
            
    return result


#读取图像

original = cv2.imread(r'D:\deng\smalljob\ImageSet\girl.jpg')
origin = cv2.cvtColor(original, cv2.COLOR_BGR2RGB) #将图像从BGR颜色空间转换到RGB颜色空间
b,g,r=cv2.split(origin)#分离颜色通道

img_b_y=sobel_x(b)
img_g_y=sobel_x(g)
img_r_y=sobel_x(r)

result_y=np.dstack((img_b_y,img_g_y,img_r_y))
result_y=np.abs(result_y).astype(np.float32)/255.0

img_b_x=sobel_y(b)
img_g_x=sobel_y(g)
img_r_x=sobel_y(r)

result_x=np.dstack((img_b_x,img_g_x,img_r_x))
result_x=np.abs(result_x).astype(np.float32)/255.0

result_xy=np.sqrt(result_x**2 + result_y**2)

#展示结果

pyplot.subplot(221),pyplot.imshow(origin,cmap='gray')
pyplot.title('original')
pyplot.axis('off')

pyplot.subplot(222),pyplot.imshow(result_x,cmap='gray')
pyplot.title('|G$_{x}$|')
pyplot.axis('off')

pyplot.subplot(223),pyplot.imshow(result_y,cmap='gray')
pyplot.title('|G$_{y}$|')
pyplot.axis('off')

pyplot.subplot(224),pyplot.imshow(result_xy,cmap='gray')
pyplot.title('|G$_{x}$|+|G$_{y}$|')
pyplot.axis('off')
pyplot.show()

运行结果:

 

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值