sobel计算以及代码

sobel 算子

索贝尔算子(Sobel operator)主要用作边缘检测,在技术上,它是以离散性差分算子,用来计算凸显两素函数的灰度之近似值。在图像的任何一点使用此算子,将会产生对应的灰度矢量或是法矢量。
Sobel 的卷积因子为:
在这里插入图片描述
该算子包含两组3 * 3 的矩阵,分别为横向和纵向,将之与图像做平面卷积,即可分别得出横向及纵向的亮度差
分近似值,若以A代表为原始图像,Gx及Gy分别代表经横向及纵向边缘检测的图像灰度值,其公式如下:
G x = [ − 1 0 + 1 − 2 0 + 2 − 1 0 + 1 ] × A   a n d   G y = [ + 1 + 2 + 1 0 0 0 − 1 − 2 − 1 ] × A   G_x=\left[ \begin{matrix} -1& 0& +1\\ -2& 0& +2\\ -1& 0& +1\\ \end{matrix} \right] \times A\ and\ G_y=\left[ \begin{matrix} +1& +2& +1\\ 0& 0& 0\\ -1& -2& -1\\ \end{matrix} \right] \times A\ Gx=121000+1+2+1×A and Gy=+101+202+101×A 

图像的每一像素的横向以及纵向灰度值通过以下公式结合,来计算该点灰度的大小:
G = G x 2 + G y 2   G=\sqrt{G_x^2+G_y^2}\ G=Gx2+Gy2  
通常,为了提高计算的效率,也使用以下公式计算:
∣ G ∣ = ∣ G x ∣ + ∣ G y ∣ \left| G \right|=\left| G_x \right|+\left| G_y \right| G=Gx+Gy

具体代码实现

import cv2 as cv
import math
import numpy as np


def rgb2gray(img):
    h=img.shape[0]
    w=img.shape[1]
    img1=np.zeros((h,w),np.uint8)
    for i in range(h):
        for j in range(w):
            img1[i, j] = np.max(img[i, j])
    return img1

def otsu(img):
    h=img.shape[0]
    w=img.shape[1]
    m=h*w
    otsuimg=np.zeros((h,w),np.uint8)
    threshold_max=threshold=0
    histogram=np.zeros(256,np.int32)
    probability=np.zeros(256,np.float32)
    for i in range (h):
        for j in range (w):
            s=img[i,j]
            histogram[s]+=1
    for k in range (256):
        probability[k]=histogram[k]/m
    for i in range (255):
        w0 = w1 = 0
        fgs = bgs = 0
        for j in range (256):
            if j<=i:
                w0+=probability[j]
                fgs+=j*probability[j]
            else:
                w1+=probability[j]
                bgs+=j*probability[j]
        u0=fgs/w0
        u1=bgs/w1
        g=w0*w1*(u0-u1)**2   # 类间方差
        if g>=threshold_max:
            threshold_max=g
            threshold=i
    print(threshold)
    for i in range (h):
        for j in range (w):
            if img[i,j]>threshold:
                otsuimg[i,j]=255
            else:
                otsuimg[i,j]=0
    return otsuimg

def sobel(img):
    h=img.shape[0]
    w=img.shape[1]
    sobelimg=np.zeros((h,w),np.uint8)
    sobelx = [[-1, 0, 1], [-2, 0, 2], [-1, 0, 1]]
    sobely = [[1, 2, 1], [0, 0, 0], [-1, -2, -1]]
    sobelx=np.array(sobelx)
    sobely=np.array(sobely)
    for i in range(1,h-1):
        for j in range(1,w-1):
            edgex=0
            edgey=0
            for k in range(-1,2):
                for l in range(-1,2):
                    edgex+=img[k+i,l+j]*sobelx[1+k,1+l]
                    edgey+=img[k+i,l+j]*sobely[1+k,1+l]
            gx=abs(edgex)
            gy=abs(edgey)
            gramag=gx+gy
            sobelimg[i,j]=gramag
    return sobelimg

image= cv.imread(r"pin1.jpg")
grayimage=rgb2gray(image)

otsuimage=otsu(grayimage)
cv.imshow("grayimage",otsuimage)
sobelimage=sobel(otsuimage)
cv.imshow("image",image)
cv.imshow("sobelimage",sobelimage)
cv.waitKey(0)
cv.destroyAllWindows()

结果

原图 && 二值化灰度图 && sobel图
在这里插入图片描述

opencv函数实现

import cv2
import numpy as np

img = cv2.imread(r"3.jpg")

x = cv2.Sobel(img, cv2.CV_16S, 1, 0)
y = cv2.Sobel(img, cv2.CV_16S, 0, 1)

absX = cv2.convertScaleAbs(x)  # 转回unit8
absY = cv2.convertScaleAbs(y)

dst = cv2.addWeighted(absX, 0.5, absY, 0.5, 0)

cv2.imshow("absX", absX)
cv2.imshow("absY", absY)

cv2.imshow("Result", dst)

cv2.waitKey(0)
cv2.destroyAllWindows()
结果

X 方向 && Y方向 && X+Y方向
在这里插入图片描述

  • 1
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值