04 Sobel算子


前言

记录Sobel算子的学习过程。该算法相对其他的边界检测算法而言是比较的容易。但是对于噪声的鲁棒性要低于其他的边界检测技术。比如canny。

索伯算子是一种多用于边缘检测的离散性差分算子。索伯算子有两组不同的卷积因子,可以为一张图片做横向以及纵向的平面卷积。详细的讲就是,假设要对一张图中的(x,y)这个像素使用索伯算子。首先用两个卷积因子分别对该点做卷积,从而可得出该点在这两个方向上的亮度差分近似值。将xy两个方向的亮度近似值进行结合之后,即可得到该点亮度。 得到的是一个数,如果这个值大于了阈值,那么这个点就可以被考虑成边缘点。


一、算子

具体算子的模板如下图所示,
在这里插入图片描述

二、编程实现

1.卷积函数

代码如下(示例):


import numpy as np

def my_filter2D(img,kernel):
    """
       卷积函数
       :param image: 原图像,是灰度图
       :param kernel: 卷积核
       :return: 卷积后的图像
    """
    k_rows,k_cols = kernel.shape[:2]
    i_rows,i_cols = img.shape[:2]
    new_img = np.zeros((img.shape[0],img.shape[1]),dtype=np.float32)
    #进行遍历操作
    for row in range(i_rows-k_rows+1):
        for col in range(i_cols-k_cols+1):
            #创建一个视图window,大小与kernel一致
            windows=img[row:row+k_rows,col:col+k_cols]
            #完成卷积操作
            out=abs(np.sum(windows * np.flip(kernel), axis=(0, 1)))
            #赋值 3*3的kernel是row+1,但是2*2 此时的位置是左上,那就等于row,col,将下面修改一下。
           #new_img[row+1,col+1] = out
            new_img[row+k_rows//2,col+k_cols//2] = out
            new_img = np.clip(new_img, 0, 255).astype(np.uint8)
    return new_img

2.sobel算子函数

代码如下(示例):

import numpy as np
import img_filter2D #将前面的卷积函数写成一个模块并引入

def my_roberts(img):
    h,w = img.shape[:2]
    G = np.zeros((img.shape[0],img.shape[1]),dtype=np.float32)
    dx = np.array([[-1,0,1],[-2,0,2],[-1,0,1]])
    dy = np.array([[-1, -2, -1], [0, 0, 0], [1, 2, 1]])
    Gx = abs(img_filter2D.my_filter2D(img,dx))
    Gy = abs(img_filter2D.my_filter2D(img,dy))
    G = Gx+Gy
    new_img = np.clip(G, 0, 255).astype(np.uint8)
    Gx = np.clip(Gx, 0, 255).astype(np.uint8)
    Gy = np.clip(Gy, 0, 255).astype(np.uint8)
    return Gx,Gy,new_img

3进行测试

import cv2
import matplotlib.pyplot as plt
import Sobel

img = cv2.imread("lena.bmp",0)
i,j,k = Sobel.my_roberts(img)

figure_ = plt.figure()
ax1 = figure_.add_subplot(141)
ax1.set_title('original img')
plt.imshow(img,cmap='gray')#不要忘记这一步
ax2= figure_.add_subplot(142)
ax2.set_title('x_convolution')
plt.imshow(i,cmap='gray')
ax3 = figure_.add_subplot(143)
ax3.set_title('y_convolution')
plt.imshow(j,cmap='gray')

ax4 = figure_.add_subplot(144)
ax4.set_title('magnitude')
plt.imshow(k,cmap='gray')
plt.show()


结果如图所示:
在这里插入图片描述
Q:有没有发现第一张图是绿色的?
A:因为我一开始plt.imshow(img,cmap=‘gray’)代码里面忘记写cmap=‘gray’,他可能默认是彩色映射,改过来效果就应该没问题了。

猜你喜欢

转载自blog.csdn.net/CSDN_Yangk/article/details/129838349