python—opencv图像膨胀|图像腐蚀|图像边缘检测sobel算子/拉普拉斯算子/canny算子

本文深入探讨了图像处理领域的核心算法,包括图像膨胀与腐蚀、轮廓检测、边缘检测等关键技术。通过Sobel算子、拉普拉斯算子及Canny算子实现边缘检测,展示了不同算子的效果对比。同时,介绍了图像的二值化处理、轮廓提取和边缘检测的具体实现过程。
摘要由CSDN通过智能技术生成

图像膨胀|图像腐蚀

import numpy as np
import matplotlib.pyplot as plt
import cv2

## a.图像的二值化 ,这里没有做阈值处理
src = cv2.imread('lina.jpg', 0)
ret2,th2 = cv2.threshold(src,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)
## b.设置卷积核5*5
kernel = np.ones((3, 3), np.uint8)
## c.图像的腐蚀,默认迭代次数
erosion = cv2.erode(th2, kernel)
## 图像膨胀
fatten = cv2.dilate(th2,kernel)
## 效果展示
imgs = [src,th2,erosion,fatten]
titles= ['original','binaryzation','after erosion','after fatten']
for i in range(4):
    plt.subplot(2,2,i+1)
    plt.imshow(imgs[i],cmap='gray');plt.title(titles[i])
plt.show()

在这里插入图片描述

图像轮廓

#图形的轮廓
import numpy as np
import matplotlib.pyplot as plt
import cv2
from skimage import measure,draw

src = cv2.imread('lina.jpg', 0)
ret2,img = cv2.threshold(src,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)
#检测所有图形的轮廓
contours = measure.find_contours(img, 0.5)

#绘制轮廓
fig, axes = plt.subplots(1,2,figsize=(8,8))
ax0, ax1= axes.ravel()
ax0.imshow(img,plt.cm.gray)
ax0.set_title('original image')

rows,cols=img.shape
ax1.axis([0,rows,cols,0])
for n, contour in enumerate(contours):
    ax1.plot(contour[:, 1], contour[:, 0], linewidth=2)
ax1.axis('image')
ax1.set_title('contours')
plt.show()

在这里插入图片描述

图像边缘检测

https://blog.csdn.net/qq_40962368/article/details/81416954

sobel算子

# Sobel边缘检测算子
import numpy as np
import matplotlib.pyplot as plt
import cv2

#解决中文显示问题
plt.rcParams['font.sans-serif']=['SimHei']
plt.rcParams['axes.unicode_minus'] = False

img = cv2.imread('lina.jpg', 0)
x = cv2.Sobel(img, cv2.CV_16S, 1, 0,ksize=3)
y = cv2.Sobel(img, cv2.CV_16S, 0, 1,ksize=3)
#cv2.CV_64F表示64位浮点数即64float。CV_16S是16位short型
#这里不使用numpy.float64,因为可能会发生溢出现象。用cv的数据则会自动
#第三和第四个参数分别是对X和Y方向的导数(即dx,dy),对于图像来说就是差分,这里1表示对X求偏导(差分),0表示不对Y求导(差分)。其中,X还可以求2次导。
#注意:对X求导就是检测X方向上是否有边缘。
XY = cv2.Sobel(img, cv2.CV_64F, 1, 1, ksize=3)
#这里对两个方向同时进行检测,则会过滤掉仅仅只是x或者y方向上的边缘
# cv2.convertScaleAbs(src[, dst[, alpha[, beta]]])
# 可选参数alpha是伸缩系数,beta是加到结果上的一个值,结果返回uint类型的图像
Scale_absX = cv2.convertScaleAbs(x)  # convert 转换  scale 缩放
Scale_absY = cv2.convertScaleAbs(y)
Scale_absXY = cv2.convertScaleAbs(XY)
result = cv2.addWeighted(Scale_absX, 0.5, Scale_absY, 0.5, 0)
# cv2.imshow('img', img)
# cv2.imshow('Scale_absX', Scale_absX)
# cv2.imshow('Scale_absY', Scale_absY)
# cv2.imshow('result', result)
# cv2.waitKey(0)
# cv2.destroyAllWindows()
imgs = [img,Scale_absX,Scale_absY,result]
titles = ['img','Scale_absX','Scale_absY','result']
for i in range(4):
    plt.subplot(2,2,i+1)
    plt.imshow(imgs[i],cmap='gray');plt.title(titles[i],fontsize=9)
    plt.axis('off')
plt.show()
plt.imshow(Scale_absXY,'gray');plt.axis('off');
plt.title('对两个方向同时进行检测,滤掉仅仅只是x或者y方向上的边缘')
plt.show()

Sobel函数求完导数后会有负值,还有会大于255的值。而原图像是uint8,即8位无符号数,所以Sobel建立的图像位数不够,会有截断。因此要使用16位有符号的数据类型,即cv2.CV_16S。处理完图像后,再使用cv2.convertScaleAbs()函数将其转回原来的uint8格式,否则图像无法显示。

在这里插入图片描述
在这里插入图片描述

拉普拉斯算子、canny算子

# 拉普拉斯算子
import numpy as np
import matplotlib.pyplot as plt
import cv2
img = cv2.imread('lina.jpg', 0)
laplacian = cv2.Laplacian(img, cv2.CV_16S, ksize=3)
dst = cv2.convertScaleAbs(laplacian)
plt.subplot(121);plt.imshow(dst,'gray');plt.title('laplacian')
#canny算子
blur = cv2.GaussianBlur(img, (3, 3), 0)  # 用高斯滤波处理原图像降噪
canny = cv2.Canny(blur, 50,150)  # 50是最小阈值,150是最大阈值
plt.subplot(122);plt.imshow(canny,'gray');plt.title('canny')
plt.show()

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值