欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

sobel计算以及代码

程序员文章站 2022-07-14 23:10:35
...

sobel 算子

索贝尔算子(Sobel operator)主要用作边缘检测,在技术上,它是以离散性差分算子,用来计算凸显两素函数的灰度之近似值。在图像的任何一点使用此算子,将会产生对应的灰度矢量或是法矢量。
Sobel 的卷积因子为:
sobel计算以及代码
该算子包含两组3 * 3 的矩阵,分别为横向和纵向,将之与图像做平面卷积,即可分别得出横向及纵向的亮度差
分近似值,若以A代表为原始图像,Gx及Gy分别代表经横向及纵向边缘检测的图像灰度值,其公式如下:
Gx=[10+120+210+1]×A and Gy=[+1+2+1000121]×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\

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

具体代码实现

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图
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方向
sobel计算以及代码