sobel计算以及代码
程序员文章站
2022-07-14 23:10:35
...
sobel 算子
索贝尔算子(Sobel operator)主要用作边缘检测,在技术上,它是以离散性差分算子,用来计算凸显两素函数的灰度之近似值。在图像的任何一点使用此算子,将会产生对应的灰度矢量或是法矢量。
Sobel 的卷积因子为:
该算子包含两组3 * 3 的矩阵,分别为横向和纵向,将之与图像做平面卷积,即可分别得出横向及纵向的亮度差
分近似值,若以A代表为原始图像,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方向
上一篇: python日志模块logging
下一篇: Python循环判断基础学习